Module:Mod: Difference between revisions
Jump to navigation
Jump to search
>OmegaK2 m (Fix) |
m (88 revisions imported) |
||
(34 intermediate revisions by 7 users not shown) | |||
Line 1: | Line 1: | ||
-- | ------------------------------------------------------------------------------- | ||
-- Module | -- | ||
-- | -- Module:Mod | ||
-- | |||
-- This module implements Template:Mod | |||
------------------------------------------------------------------------------- | |||
require('Module:No globals') | |||
local m_util = require('Module:Util') | local m_util = require('Module:Util') | ||
local | local m_cargo = require('Module:Cargo') | ||
local | -- Should we use the sandbox version of our submodules? | ||
local use_sandbox = m_util.misc.maybe_sandbox('Mod') | |||
local | local m_game = use_sandbox and mw.loadData('Module:Game/sandbox') or mw.loadData('Module:Game') | ||
-- Lazy loading | |||
local f_item_table -- require('Module:Item table').item_table | |||
-- | -- The cfg table contains all localisable strings and configuration, to make it | ||
-- easier to port this module to another wiki. | |||
local cfg = use_sandbox and mw.loadData('Module:Mod/config/sandbox') or mw.loadData('Module:Mod/config') | |||
-- | |||
local i18n = | local i18n = cfg.i18n | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
-- | -- Helper functions | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
local h = {} | local h = {} | ||
-- | -- Lazy loading for Module:Item table | ||
function h.item_table(args) | |||
if not f_item_table then | |||
f_item_table = require('Module:Item table').item_table | |||
end | |||
return f_item_table(args) | |||
end | |||
h. | function h.set_weights(tpl_args, args) | ||
-- Parses a weighted pair of lists and sets properties | |||
-- | |||
-- tpl_args: argument table to work with | |||
-- args: | |||
-- prefix - input prefix for parsing the arguments from tpl_args | |||
-- table_map - cargo table map | |||
args = args or {} | |||
for i=1, math.huge do -- repeat until no more weights are found | |||
local prefix = args.prefix .. i | |||
local params = { | |||
tag = string.format('%s_tag', prefix), | |||
value = string.format('%s_value', prefix), | |||
} | |||
local tag = tpl_args[params.tag] | |||
local value = tpl_args[params.value] | |||
if tag == nil and value == nil then | |||
break | |||
end | end | ||
if tag == nil or value == nil then | |||
error(string.format(i18n.errors.invalid_weight, params.tag, params.value)) | |||
end | |||
value = m_util.cast.number(value, {min = 0}) | |||
-- Store to cargo table unless tag = default and value = 0 | |||
if tag ~= 'default' or value ~= 0 then | |||
m_cargo.store({ | |||
_table = args.table_map.table, | |||
[args.table_map.fields.ordinal.field] = i, | |||
[args.table_map.fields.tag.field] = tag, | |||
[args.table_map.fields.value.field] = value, | |||
}) | |||
end | |||
end | end | ||
end | end | ||
Line 140: | Line 86: | ||
main = { | main = { | ||
table = 'mods', | table = 'mods', | ||
display_order = {'id', 'name', 'mod_groups', 'mod_type', 'domain', 'generation_type', 'required_level', 'stat_text', 'granted_buff_id', 'granted_buff_value', 'granted_skill', 'tags', 'tier_text'}, | |||
order = {'id', 'name', 'mod_groups', 'mod_type', 'domain', 'generation_type', 'required_level', 'stat_text', 'stat_text_raw', 'granted_buff_id', 'granted_buff_value', 'granted_skill', 'tags', 'tier_text'}, | |||
fields = { | fields = { | ||
id = { | id = { | ||
name = | name = 'id', | ||
field = | field = 'id', | ||
type = 'String', | type = 'String', | ||
wikitext = ' | wikitext = i18n.data_sheet.id, | ||
func = function (tpl_args, value) | |||
-- Validate that the id is unique | |||
local results = m_cargo.query( | |||
{'mods'}, | |||
{'mods._pageName'}, | |||
{ | |||
where = string.format( | |||
'mods.id = "%s" AND mods._pageName != "%s"', | |||
value, | |||
m_cargo.addslashes(mw.title.getCurrentTitle().prefixedText) | |||
) | |||
} | |||
) | |||
if #results > 0 then | |||
error(string.format(i18n.errors.duplicate_mod_id, results[1]['mods._pageName'])) | |||
end | |||
return value | |||
end | |||
}, | }, | ||
name = { | name = { | ||
name = | name = 'name', | ||
field = | field = 'name', | ||
type = 'String', | type = 'String', | ||
wikitext = | wikitext = i18n.data_sheet.name, | ||
}, | }, | ||
mod_groups = { | |||
name = | name = 'mod_groups', | ||
field = | field = 'mod_groups', | ||
type = 'String', | type = 'List (,) of String', | ||
wikitext = ' | wikitext = i18n.data_sheet.mod_groups, | ||
display = function (value) | |||
return table.concat(value, ', ') | |||
end, | |||
default = {}, | |||
}, | }, | ||
mod_type = { | mod_type = { | ||
name = | name = 'mod_type', | ||
field = | field = 'mod_type', | ||
type = 'String', | type = 'String', | ||
wikitext = | wikitext = i18n.data_sheet.mod_type, | ||
}, | }, | ||
domain = { | domain = { | ||
name = | name = 'domain', | ||
field = | field = 'domain', | ||
type = 'Integer', | type = 'Integer', | ||
wikitext = 'Mod domain', | wikitext = 'Mod domain', | ||
display = function (value) | display = function (value) | ||
return | return string.format(i18n.data_sheet.domain_fmt, m_game.constants.mod.domains[value]['short_upper'], value) | ||
end, | end, | ||
}, | }, | ||
generation_type = { | generation_type = { | ||
name = | name = 'generation_type', | ||
field = | field = 'generation_type', | ||
type = 'Integer', | type = 'Integer', | ||
wikitext = i18n.data_sheet.generation_type, | |||
display = function (value) | display = function (value) | ||
return | return string.format(i18n.data_sheet.generation_type_fmt, m_game.constants.mod.generation_types[value]['short_upper'], value) | ||
end, | end, | ||
}, | }, | ||
required_level = { | required_level = { | ||
name = | name = 'required_level', | ||
field = | field = 'required_level', | ||
type = 'Integer', | type = 'Integer', | ||
wikitext = i18n.data_sheet.required_level, | |||
}, | }, | ||
stat_text = { | stat_text = { | ||
name = | name = 'stat_text', | ||
field = | field = 'stat_text', | ||
type = 'Text', | type = 'Text', | ||
wikitext = | wikitext = i18n.data_sheet.stat_text, | ||
}, | }, | ||
stat_text_raw = { | stat_text_raw = { | ||
Line 204: | Line 169: | ||
field = 'stat_text_raw', | field = 'stat_text_raw', | ||
type = 'Text', | type = 'Text', | ||
func = function(tpl_args, | func = function (tpl_args, value) | ||
tpl_args. | if tpl_args.stat_text then | ||
-- | -- Strip wikilinks and html, but keep any line break tags | ||
string. | value = m_util.string.strip_wikilinks(tpl_args.stat_text) | ||
value = mw.ustring.gsub(value, '<br */?>', '�') | |||
) | value = m_util.string.strip_html(value) | ||
value = mw.ustring.gsub(value, '�', '<br>') | |||
' | end | ||
return value | |||
return | |||
end | end | ||
}, | }, | ||
granted_buff_id = { | granted_buff_id = { | ||
name = | name = 'granted_buff_id', | ||
field = | field = 'granted_buff_id', | ||
type = 'String', | type = 'String', | ||
wikitext = | wikitext = i18n.data_sheet.granted_buff_id, | ||
}, | }, | ||
granted_buff_value = { | granted_buff_value = { | ||
name = | name = 'granted_buff_value', | ||
field = | field = 'granted_buff_value', | ||
type = 'Integer', | type = 'Integer', | ||
wikitext = | wikitext = i18n.data_sheet.granted_buff_value, | ||
}, | }, | ||
granted_skill = { | granted_skill = { | ||
name = | name = 'granted_skill', | ||
field = | field = 'granted_skill', | ||
type = 'String', | type = 'String', | ||
wikitext = | wikitext = i18n.data_sheet.granted_skill, | ||
}, | }, | ||
tags = { | tags = { | ||
name = | name = 'tags', | ||
field = | field = 'tags', | ||
type = 'List (,) of String', | type = 'List (,) of String', | ||
wikitext = 'Tags', | wikitext = 'Tags', | ||
display = function (value) | |||
return table.concat(value, ', ') | |||
end, | end, | ||
default = {}, | |||
}, | |||
tier_text = { | |||
name = 'tier_text', | |||
field = 'tier_text', | |||
type = 'Text', | |||
wikitext = i18n.data_sheet.tier_text, | |||
}, | |||
}, | |||
}, | |||
mod_stats = { | |||
table = 'mod_stats', | |||
fields = { | |||
id = { | |||
field = 'id', | |||
type = 'String', | |||
}, | |||
min = { | |||
field = 'min', | |||
type = 'Integer', | |||
}, | |||
max = { | |||
field = 'max', | |||
type = 'Integer', | |||
}, | |||
}, | |||
}, | |||
mod_spawn_weights = { | |||
table = 'mod_spawn_weights', | |||
fields = { | |||
ordinal = { | |||
field = 'ordinal', | |||
type = 'Integer', | |||
}, | |||
tag = { | |||
field = 'tag', | |||
type = 'String', | |||
}, | |||
value = { | |||
field = 'value', | |||
type = 'Integer', | |||
}, | |||
}, | |||
}, | |||
mod_generation_weights = { | |||
table = 'mod_generation_weights', | |||
fields = { | |||
ordinal = { | |||
field = 'ordinal', | |||
type = 'Integer', | |||
}, | |||
tag = { | |||
field = 'tag', | |||
type = 'String', | |||
}, | |||
value = { | |||
field = 'value', | |||
type = 'Integer', | |||
}, | }, | ||
}, | }, | ||
Line 263: | Line 272: | ||
fields = { | fields = { | ||
name = { | name = { | ||
name = | name = 'name', | ||
field = | field = 'name', | ||
type = 'String', | type = 'String', | ||
func = function (value) return value end, | func = function (value) return value end, | ||
}, | }, | ||
amount = { | amount = { | ||
name = | name = 'amount', | ||
field = | field = 'amount', | ||
type = 'Integer', | type = 'Integer', | ||
func = tonumber, | func = tonumber, | ||
Line 278: | Line 287: | ||
} | } | ||
-- ---------------------------------------------------------------------------- | |||
-- Main functions | |||
-- ---------------------------------------------------------------------------- | |||
-- p.mod{id = "LocalIncreasedPhysicalDamagePercentUniqueOneHandSword2", name = "", | local function _mod(tpl_args) | ||
-- p.mod{id = "LocalIncreasedPhysicalDamagePercentUniqueOneHandSword2", name = "", mod_groups = "LocalPhysicalDamagePercent, Dexterity", domain = "1", generation_type = "3", required_level = "1", mod_type = "LocalPhysicalDamagePercent", stat_text = "150% increased Physical Damage", stat1_id = "local_physical_damage_+%", stat1_min = "150", stat1_max = "150"} | |||
-- | -- | ||
-- | -- Validate and store | ||
-- | -- | ||
-- Validate single value properties and set them | -- Validate single value properties and set them | ||
m_cargo.store_mapped_args{ | |||
tpl_args = tpl_args, | |||
table_map = mod_map.main, | |||
} | } | ||
-- Validate and store stats | |||
m_util.args.stats(tpl_args) | |||
-- Validate | |||
m_util.args.stats(tpl_args | |||
for _, stat_data in pairs(tpl_args.stats) do | for _, stat_data in pairs(tpl_args.stats) do | ||
m_cargo.store({ | |||
_table = 'mod_stats', | _table = 'mod_stats', | ||
id = stat_data.id, | id = stat_data.id, | ||
Line 346: | Line 315: | ||
end | end | ||
-- Validate | -- Validate and store spawn weights | ||
h.set_weights(tpl_args, { | |||
prefix = 'spawn_weight', | |||
table_map = mod_map.mod_spawn_weights | |||
}) | }) | ||
-- Validate | -- Validate and store generation weights | ||
h.set_weights(tpl_args, { | |||
prefix = 'generation_weight', | |||
table_map = mod_map.mod_generation_weights | |||
}) | }) | ||
-- Validate | -- Validate and store mod sell values | ||
i = 0 | local i = 0 | ||
local names = {} | local names = {} | ||
local sell_prices = {} | local sell_prices = {} | ||
Line 364: | Line 335: | ||
local id = {} | local id = {} | ||
value = {} | local value = {} | ||
for key, data in pairs(mod_map.mod_sell_prices.fields) do | for key, data in pairs(mod_map.mod_sell_prices.fields) do | ||
id[key] = string.format('%s%s_%s', | id[key] = string.format('%s%s_%s', 'sell_price', i, data.name) | ||
value[key] = data.func(tpl_args[id[key]]) | value[key] = data.func(tpl_args[id[key]]) | ||
end | end | ||
Line 385: | Line 356: | ||
cargo_data[data.field] = value[key] | cargo_data[data.field] = value[key] | ||
end | end | ||
m_cargo.store(cargo_data) | |||
sell_prices[#sell_prices+1] = value | sell_prices[#sell_prices+1] = value | ||
Line 393: | Line 364: | ||
until value == nil | until value == nil | ||
-- Attach to tables | |||
mw.getCurrentFrame():expandTemplate{title = 'Template:Mod/cargo/mods/attach'} | |||
mw.getCurrentFrame():expandTemplate{title = 'Template:Mod/cargo/mod stats/attach'} | |||
mw.getCurrentFrame():expandTemplate{title = 'Template:Mod/cargo/mod spawn weights/attach'} | |||
mw.getCurrentFrame():expandTemplate{title = 'Template:Mod/cargo/mod generation weights/attach'} | |||
mw.getCurrentFrame():expandTemplate{title = 'Template:Mod/cargo/mod sell prices/attach'} | |||
-- | -- | ||
Line 399: | Line 377: | ||
local container = mw.html.create('div') | local container = mw.html.create('div') | ||
:addClass('modbox') | |||
: | |||
-- core stats | -- core stats | ||
local tbl = container:tag('table') | local tbl = container:tag('table') | ||
:addClass('wikitable') | |||
: | |||
for _, key in ipairs(mod_map.main. | for _, key in ipairs(mod_map.main.display_order) do | ||
local data = mod_map.main.fields[key] | local data = mod_map.main.fields[key] | ||
local text | local text = tpl_args[key] | ||
if data.display == | if type(data.display) == 'function' then | ||
text = data.display(text) | |||
text = data.display( | |||
end | end | ||
tbl | tbl | ||
:tag('tr') | :tag('tr') | ||
Line 428: | Line 401: | ||
:done() | :done() | ||
end | end | ||
-- stat table | -- stat table | ||
Line 444: | Line 406: | ||
tbl = container:tag('table') | tbl = container:tag('table') | ||
tbl | tbl | ||
: | :addClass('wikitable sortable') | ||
:tag('tr') | :tag('tr') | ||
:tag('th') | :tag('th') | ||
:attr('colspan', 4) | :attr('colspan', 4) | ||
:wikitext( | :wikitext(i18n.data_sheet.stats) | ||
:done() | :done() | ||
:done() | :done() | ||
:tag('tr') | :tag('tr') | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.ordinal) | ||
:done() | :done() | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.stat_id) | ||
:done() | :done() | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.min) | ||
:done() | :done() | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.max) | ||
:done() | :done() | ||
:done() | :done() | ||
Line 498: | Line 460: | ||
tbl = container:tag('table') | tbl = container:tag('table') | ||
tbl | tbl | ||
: | :addClass('wikitable sortable') | ||
:tag('tr') | :tag('tr') | ||
:tag('th') | :tag('th') | ||
:attr('colspan', 3) | :attr('colspan', 3) | ||
:wikitext( | :wikitext(i18n.data_sheet.spawn_weights) | ||
:done() | :done() | ||
:done() | :done() | ||
:tag('tr') | :tag('tr') | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.ordinal) | ||
:done() | :done() | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.tag) | ||
:done() | :done() | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.weight) | ||
:done() | :done() | ||
:done() | :done() | ||
Line 519: | Line 481: | ||
i = 0 | i = 0 | ||
value = nil | local value = nil | ||
repeat | repeat | ||
i = i + 1 | i = i + 1 | ||
Line 548: | Line 510: | ||
tbl = container:tag('table') | tbl = container:tag('table') | ||
tbl | tbl | ||
: | :addClass('wikitable sortable') | ||
:tag('tr') | :tag('tr') | ||
:tag('th') | :tag('th') | ||
:attr('colspan', 3) | :attr('colspan', 3) | ||
:wikitext( | :wikitext(i18n.data_sheet.generation_weights) | ||
:done() | :done() | ||
:done() | :done() | ||
:tag('tr') | :tag('tr') | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.ordinal) | ||
:done() | :done() | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.tag) | ||
:done() | :done() | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.weight) | ||
:done() | :done() | ||
:done() | :done() | ||
Line 597: | Line 559: | ||
tbl = container:tag('table') | tbl = container:tag('table') | ||
tbl | tbl | ||
: | :addClass('wikitable sortable') | ||
:tag('tr') | :tag('tr') | ||
:tag('th') | :tag('th') | ||
:attr('colspan', 2) | :attr('colspan', 2) | ||
:wikitext( | :wikitext(i18n.data_sheet.sell_price) | ||
:done() | :done() | ||
:done() | :done() | ||
:tag('tr') | :tag('tr') | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.ordinal) | ||
:done() | :done() | ||
:tag('th') | :tag('th') | ||
:wikitext( | :wikitext(i18n.data_sheet.item) | ||
:done() | :done() | ||
:done() | :done() | ||
Line 621: | Line 583: | ||
:done() | :done() | ||
:tag('td') | :tag('td') | ||
:wikitext( | :wikitext(string.format('[[%s]]', value.name)) | ||
:done() | :done() | ||
:done() | :done() | ||
Line 628: | Line 590: | ||
-- Generic messages on the page | -- Generic messages on the page | ||
out = {} | local out = {} | ||
if mw.ustring.find(tpl_args['id'], '_') then | if mw.ustring.find(tpl_args['id'], '_') then | ||
out[#out+1] = | out[#out+1] = mw.getCurrentFrame():expandTemplate{ title = 'Incorrect title', args = { title=tpl_args['id'] } } .. '\n\n\n' | ||
end | end | ||
if tpl_args['name'] then | if tpl_args['name'] then | ||
out[#out+1] = string.format( | out[#out+1] = string.format(i18n.sections.intro_named_id, tpl_args['id'], tpl_args['name']) | ||
else | else | ||
out[#out+1] = string.format( | out[#out+1] = string.format(i18n.sections.intro_unnamed_id, tpl_args['id']) | ||
end | end | ||
-- Item usage | |||
local items = m_cargo.query( | |||
{'item_mods'}, | |||
{'item_mods._pageName=page'}, | |||
{ | |||
-- | where = string.format( | ||
'item_mods.id = "%s"', | |||
tpl_args['id'] | |||
) | |||
local | |||
} | } | ||
) | |||
if #items > 0 then | |||
local html = mw.html.create() | |||
:tag('h2') | |||
:wikitext(i18n.sections.items) | |||
:tag(' | |||
:wikitext( | |||
:done() | :done() | ||
:tag(' | :tag('p') | ||
:wikitext(i18n.sections.used_by_items) | |||
:wikitext( | |||
:done() | :done() | ||
out[#out+1] = tostring(html) | |||
out[#out+1] = h.item_table{ | |||
q_tables = 'items', | |||
q_where = string.format( | |||
'items._pageName IN ("%s")', | |||
table.concat(m_util.table.column(items, 'page'), '","') | |||
), | |||
q_orderBy = 'items.name ASC', | |||
} | } | ||
end | end | ||
-- Categories | |||
local cats = {i18n.categories.mods} | |||
-- Done -> output | |||
-- | |||
return tostring(container) .. m_util.misc.add_category(cats) .. '\n' .. table.concat(out) | |||
end | end | ||
-- ---------------------------------------------------------------------------- | |||
-- Exported functions | |||
-- ---------------------------------------------------------------------------- | |||
local p = {} | |||
p.table_main = m_cargo.declare_factory{data=mod_map.main} | |||
p.table_mod_stats = m_cargo.declare_factory{data=mod_map.mod_stats} | |||
p.table_mod_spawn_weights = m_cargo.declare_factory{data=mod_map.mod_spawn_weights} | |||
p.table_mod_generation_weights = m_cargo.declare_factory{data=mod_map.mod_generation_weights} | |||
p.table_mod_sell_prices = m_cargo.declare_factory{data=mod_map.mod_sell_prices} | |||
-- | |||
-- Template:Mod | |||
-- | |||
p.mod = m_util.misc.invoker_factory(_mod, { | |||
wrappers = 'Template:Mod', | |||
}) | |||
return p | return p |
Latest revision as of 20:25, 25 September 2024
The above documentation is transcluded from Module:Mod/doc.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
Editors can experiment in this module's sandbox and testcases pages.
Subpages of this module.
-------------------------------------------------------------------------------
--
-- Module:Mod
--
-- This module implements Template:Mod
-------------------------------------------------------------------------------
require('Module:No globals')
local m_util = require('Module:Util')
local m_cargo = require('Module:Cargo')
-- Should we use the sandbox version of our submodules?
local use_sandbox = m_util.misc.maybe_sandbox('Mod')
local m_game = use_sandbox and mw.loadData('Module:Game/sandbox') or mw.loadData('Module:Game')
-- Lazy loading
local f_item_table -- require('Module:Item table').item_table
-- The cfg table contains all localisable strings and configuration, to make it
-- easier to port this module to another wiki.
local cfg = use_sandbox and mw.loadData('Module:Mod/config/sandbox') or mw.loadData('Module:Mod/config')
local i18n = cfg.i18n
-- ----------------------------------------------------------------------------
-- Helper functions
-- ----------------------------------------------------------------------------
local h = {}
-- Lazy loading for Module:Item table
function h.item_table(args)
if not f_item_table then
f_item_table = require('Module:Item table').item_table
end
return f_item_table(args)
end
function h.set_weights(tpl_args, args)
-- Parses a weighted pair of lists and sets properties
--
-- tpl_args: argument table to work with
-- args:
-- prefix - input prefix for parsing the arguments from tpl_args
-- table_map - cargo table map
args = args or {}
for i=1, math.huge do -- repeat until no more weights are found
local prefix = args.prefix .. i
local params = {
tag = string.format('%s_tag', prefix),
value = string.format('%s_value', prefix),
}
local tag = tpl_args[params.tag]
local value = tpl_args[params.value]
if tag == nil and value == nil then
break
end
if tag == nil or value == nil then
error(string.format(i18n.errors.invalid_weight, params.tag, params.value))
end
value = m_util.cast.number(value, {min = 0})
-- Store to cargo table unless tag = default and value = 0
if tag ~= 'default' or value ~= 0 then
m_cargo.store({
_table = args.table_map.table,
[args.table_map.fields.ordinal.field] = i,
[args.table_map.fields.tag.field] = tag,
[args.table_map.fields.value.field] = value,
})
end
end
end
-- ----------------------------------------------------------------------------
-- Templates
-- ----------------------------------------------------------------------------
--
-- Template: Mod
--
local mod_map = {
main = {
table = 'mods',
display_order = {'id', 'name', 'mod_groups', 'mod_type', 'domain', 'generation_type', 'required_level', 'stat_text', 'granted_buff_id', 'granted_buff_value', 'granted_skill', 'tags', 'tier_text'},
order = {'id', 'name', 'mod_groups', 'mod_type', 'domain', 'generation_type', 'required_level', 'stat_text', 'stat_text_raw', 'granted_buff_id', 'granted_buff_value', 'granted_skill', 'tags', 'tier_text'},
fields = {
id = {
name = 'id',
field = 'id',
type = 'String',
wikitext = i18n.data_sheet.id,
func = function (tpl_args, value)
-- Validate that the id is unique
local results = m_cargo.query(
{'mods'},
{'mods._pageName'},
{
where = string.format(
'mods.id = "%s" AND mods._pageName != "%s"',
value,
m_cargo.addslashes(mw.title.getCurrentTitle().prefixedText)
)
}
)
if #results > 0 then
error(string.format(i18n.errors.duplicate_mod_id, results[1]['mods._pageName']))
end
return value
end
},
name = {
name = 'name',
field = 'name',
type = 'String',
wikitext = i18n.data_sheet.name,
},
mod_groups = {
name = 'mod_groups',
field = 'mod_groups',
type = 'List (,) of String',
wikitext = i18n.data_sheet.mod_groups,
display = function (value)
return table.concat(value, ', ')
end,
default = {},
},
mod_type = {
name = 'mod_type',
field = 'mod_type',
type = 'String',
wikitext = i18n.data_sheet.mod_type,
},
domain = {
name = 'domain',
field = 'domain',
type = 'Integer',
wikitext = 'Mod domain',
display = function (value)
return string.format(i18n.data_sheet.domain_fmt, m_game.constants.mod.domains[value]['short_upper'], value)
end,
},
generation_type = {
name = 'generation_type',
field = 'generation_type',
type = 'Integer',
wikitext = i18n.data_sheet.generation_type,
display = function (value)
return string.format(i18n.data_sheet.generation_type_fmt, m_game.constants.mod.generation_types[value]['short_upper'], value)
end,
},
required_level = {
name = 'required_level',
field = 'required_level',
type = 'Integer',
wikitext = i18n.data_sheet.required_level,
},
stat_text = {
name = 'stat_text',
field = 'stat_text',
type = 'Text',
wikitext = i18n.data_sheet.stat_text,
},
stat_text_raw = {
name = nil,
field = 'stat_text_raw',
type = 'Text',
func = function (tpl_args, value)
if tpl_args.stat_text then
-- Strip wikilinks and html, but keep any line break tags
value = m_util.string.strip_wikilinks(tpl_args.stat_text)
value = mw.ustring.gsub(value, '<br */?>', '�')
value = m_util.string.strip_html(value)
value = mw.ustring.gsub(value, '�', '<br>')
end
return value
end
},
granted_buff_id = {
name = 'granted_buff_id',
field = 'granted_buff_id',
type = 'String',
wikitext = i18n.data_sheet.granted_buff_id,
},
granted_buff_value = {
name = 'granted_buff_value',
field = 'granted_buff_value',
type = 'Integer',
wikitext = i18n.data_sheet.granted_buff_value,
},
granted_skill = {
name = 'granted_skill',
field = 'granted_skill',
type = 'String',
wikitext = i18n.data_sheet.granted_skill,
},
tags = {
name = 'tags',
field = 'tags',
type = 'List (,) of String',
wikitext = 'Tags',
display = function (value)
return table.concat(value, ', ')
end,
default = {},
},
tier_text = {
name = 'tier_text',
field = 'tier_text',
type = 'Text',
wikitext = i18n.data_sheet.tier_text,
},
},
},
mod_stats = {
table = 'mod_stats',
fields = {
id = {
field = 'id',
type = 'String',
},
min = {
field = 'min',
type = 'Integer',
},
max = {
field = 'max',
type = 'Integer',
},
},
},
mod_spawn_weights = {
table = 'mod_spawn_weights',
fields = {
ordinal = {
field = 'ordinal',
type = 'Integer',
},
tag = {
field = 'tag',
type = 'String',
},
value = {
field = 'value',
type = 'Integer',
},
},
},
mod_generation_weights = {
table = 'mod_generation_weights',
fields = {
ordinal = {
field = 'ordinal',
type = 'Integer',
},
tag = {
field = 'tag',
type = 'String',
},
value = {
field = 'value',
type = 'Integer',
},
},
},
mod_sell_prices = {
table = 'mod_sell_prices',
order = {'name', 'amount'},
fields = {
name = {
name = 'name',
field = 'name',
type = 'String',
func = function (value) return value end,
},
amount = {
name = 'amount',
field = 'amount',
type = 'Integer',
func = tonumber,
},
},
},
}
-- ----------------------------------------------------------------------------
-- Main functions
-- ----------------------------------------------------------------------------
local function _mod(tpl_args)
-- p.mod{id = "LocalIncreasedPhysicalDamagePercentUniqueOneHandSword2", name = "", mod_groups = "LocalPhysicalDamagePercent, Dexterity", domain = "1", generation_type = "3", required_level = "1", mod_type = "LocalPhysicalDamagePercent", stat_text = "150% increased Physical Damage", stat1_id = "local_physical_damage_+%", stat1_min = "150", stat1_max = "150"}
--
-- Validate and store
--
-- Validate single value properties and set them
m_cargo.store_mapped_args{
tpl_args = tpl_args,
table_map = mod_map.main,
}
-- Validate and store stats
m_util.args.stats(tpl_args)
for _, stat_data in pairs(tpl_args.stats) do
m_cargo.store({
_table = 'mod_stats',
id = stat_data.id,
min = stat_data.min,
max = stat_data.max,
})
end
-- Validate and store spawn weights
h.set_weights(tpl_args, {
prefix = 'spawn_weight',
table_map = mod_map.mod_spawn_weights
})
-- Validate and store generation weights
h.set_weights(tpl_args, {
prefix = 'generation_weight',
table_map = mod_map.mod_generation_weights
})
-- Validate and store mod sell values
local i = 0
local names = {}
local sell_prices = {}
repeat
i = i + 1
local id = {}
local value = {}
for key, data in pairs(mod_map.mod_sell_prices.fields) do
id[key] = string.format('%s%s_%s', 'sell_price', i, data.name)
value[key] = data.func(tpl_args[id[key]])
end
if value.name == nil and value.amount == nil then
value = nil
elseif value.name ~= nil and value.amount ~= nil then
if names[value.name] then
error(i18n.errors.sell_price_duplicate_name)
else
names[value.name] = true
end
local cargo_data = {
_table = mod_map.mod_sell_prices.table,
}
for key, data in pairs(mod_map.mod_sell_prices.fields) do
cargo_data[data.field] = value[key]
end
m_cargo.store(cargo_data)
sell_prices[#sell_prices+1] = value
else
error (string.format(i18n.errors.sell_price_missing_arguments, id.name, id.amount))
end
until value == nil
-- Attach to tables
mw.getCurrentFrame():expandTemplate{title = 'Template:Mod/cargo/mods/attach'}
mw.getCurrentFrame():expandTemplate{title = 'Template:Mod/cargo/mod stats/attach'}
mw.getCurrentFrame():expandTemplate{title = 'Template:Mod/cargo/mod spawn weights/attach'}
mw.getCurrentFrame():expandTemplate{title = 'Template:Mod/cargo/mod generation weights/attach'}
mw.getCurrentFrame():expandTemplate{title = 'Template:Mod/cargo/mod sell prices/attach'}
--
-- Display
--
local container = mw.html.create('div')
:addClass('modbox')
-- core stats
local tbl = container:tag('table')
:addClass('wikitable')
for _, key in ipairs(mod_map.main.display_order) do
local data = mod_map.main.fields[key]
local text = tpl_args[key]
if type(data.display) == 'function' then
text = data.display(text)
end
tbl
:tag('tr')
:tag('th')
:wikitext(data.wikitext)
:done()
:tag('td')
:wikitext(text)
:done()
:done()
:done()
end
-- stat table
tbl = container:tag('table')
tbl
:addClass('wikitable sortable')
:tag('tr')
:tag('th')
:attr('colspan', 4)
:wikitext(i18n.data_sheet.stats)
:done()
:done()
:tag('tr')
:tag('th')
:wikitext(i18n.data_sheet.ordinal)
:done()
:tag('th')
:wikitext(i18n.data_sheet.stat_id)
:done()
:tag('th')
:wikitext(i18n.data_sheet.min)
:done()
:tag('th')
:wikitext(i18n.data_sheet.max)
:done()
:done()
:done()
for i=1, #tpl_args.stats do
local value = {
id = tpl_args['stat' .. i .. '_id'],
min = tpl_args['stat' .. i .. '_min'],
max = tpl_args['stat' .. i .. '_max'],
}
if value.id then
tbl
:tag('tr')
:tag('td')
:wikitext(i)
:done()
:tag('td')
:wikitext(value.id)
:done()
:tag('td')
:wikitext(value.min)
:done()
:tag('td')
:wikitext(value.max)
:done()
:done()
:done()
end
end
-- spawn weight table
tbl = container:tag('table')
tbl
:addClass('wikitable sortable')
:tag('tr')
:tag('th')
:attr('colspan', 3)
:wikitext(i18n.data_sheet.spawn_weights)
:done()
:done()
:tag('tr')
:tag('th')
:wikitext(i18n.data_sheet.ordinal)
:done()
:tag('th')
:wikitext(i18n.data_sheet.tag)
:done()
:tag('th')
:wikitext(i18n.data_sheet.weight)
:done()
:done()
:done()
i = 0
local value = nil
repeat
i = i + 1
value = {
tag = tpl_args[string.format('spawn_weight%s_tag', i)],
value = tpl_args[string.format('spawn_weight%s_value', i)],
}
if value.tag then
tbl
:tag('tr')
:tag('td')
:wikitext(i)
:done()
:tag('td')
:wikitext(value.tag)
:done()
:tag('td')
:wikitext(value.value)
:done()
:done()
:done()
end
until value.tag == nil
-- generation weight table
tbl = container:tag('table')
tbl
:addClass('wikitable sortable')
:tag('tr')
:tag('th')
:attr('colspan', 3)
:wikitext(i18n.data_sheet.generation_weights)
:done()
:done()
:tag('tr')
:tag('th')
:wikitext(i18n.data_sheet.ordinal)
:done()
:tag('th')
:wikitext(i18n.data_sheet.tag)
:done()
:tag('th')
:wikitext(i18n.data_sheet.weight)
:done()
:done()
:done()
i = 0
value = nil
repeat
i = i + 1
value = {
tag = tpl_args[string.format('generation_weight%s_tag', i)],
value = tpl_args[string.format('generation_weight%s_value', i)],
}
if value.tag then
tbl
:tag('tr')
:tag('td')
:wikitext(i)
:done()
:tag('td')
:wikitext(value.tag)
:done()
:tag('td')
:wikitext(value.value)
:done()
:done()
:done()
end
until value.tag == nil
-- Sell prices
tbl = container:tag('table')
tbl
:addClass('wikitable sortable')
:tag('tr')
:tag('th')
:attr('colspan', 2)
:wikitext(i18n.data_sheet.sell_price)
:done()
:done()
:tag('tr')
:tag('th')
:wikitext(i18n.data_sheet.ordinal)
:done()
:tag('th')
:wikitext(i18n.data_sheet.item)
:done()
:done()
:done()
for i, value in ipairs(sell_prices) do
tbl
:tag('tr')
:tag('td')
:wikitext(value.amount)
:done()
:tag('td')
:wikitext(string.format('[[%s]]', value.name))
:done()
:done()
end
-- Generic messages on the page
local out = {}
if mw.ustring.find(tpl_args['id'], '_') then
out[#out+1] = mw.getCurrentFrame():expandTemplate{ title = 'Incorrect title', args = { title=tpl_args['id'] } } .. '\n\n\n'
end
if tpl_args['name'] then
out[#out+1] = string.format(i18n.sections.intro_named_id, tpl_args['id'], tpl_args['name'])
else
out[#out+1] = string.format(i18n.sections.intro_unnamed_id, tpl_args['id'])
end
-- Item usage
local items = m_cargo.query(
{'item_mods'},
{'item_mods._pageName=page'},
{
where = string.format(
'item_mods.id = "%s"',
tpl_args['id']
)
}
)
if #items > 0 then
local html = mw.html.create()
:tag('h2')
:wikitext(i18n.sections.items)
:done()
:tag('p')
:wikitext(i18n.sections.used_by_items)
:done()
out[#out+1] = tostring(html)
out[#out+1] = h.item_table{
q_tables = 'items',
q_where = string.format(
'items._pageName IN ("%s")',
table.concat(m_util.table.column(items, 'page'), '","')
),
q_orderBy = 'items.name ASC',
}
end
-- Categories
local cats = {i18n.categories.mods}
-- Done -> output
return tostring(container) .. m_util.misc.add_category(cats) .. '\n' .. table.concat(out)
end
-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------
local p = {}
p.table_main = m_cargo.declare_factory{data=mod_map.main}
p.table_mod_stats = m_cargo.declare_factory{data=mod_map.mod_stats}
p.table_mod_spawn_weights = m_cargo.declare_factory{data=mod_map.mod_spawn_weights}
p.table_mod_generation_weights = m_cargo.declare_factory{data=mod_map.mod_generation_weights}
p.table_mod_sell_prices = m_cargo.declare_factory{data=mod_map.mod_sell_prices}
--
-- Template:Mod
--
p.mod = m_util.misc.invoker_factory(_mod, {
wrappers = 'Template:Mod',
})
return p