(Added support for Has spawn chance, mainly for comparisons with poedb. Basically it is the specific modifiers spawn weight divided with the sum of all modifiers spawn weighting in that specific generation type.) |
(Module:Cargo contains the most up-to-date cargo functions. Also DRY principle...) |
||
(30 intermediate revisions by 2 users not shown) | |||
Line 3: | Line 3: | ||
-- |
-- |
||
− | local util = require('Module:Util') |
||
local getArgs = require('Module:Arguments').getArgs |
local getArgs = require('Module:Arguments').getArgs |
||
− | local |
+ | local m_util = require('Module:Util') |
− | local |
+ | local m_cargo = require('Module:Cargo') |
+ | local m_game = require('Module:Game') |
||
+ | local f_item_link = require('Module:Item link').item_link |
||
local p = {} |
local p = {} |
||
-- ---------------------------------------------------------------------------- |
-- ---------------------------------------------------------------------------- |
||
+ | -- Strings |
||
− | -- Utility / Helper functions |
||
-- ---------------------------------------------------------------------------- |
-- ---------------------------------------------------------------------------- |
||
+ | -- This section contains strings used by this module. |
||
+ | -- Add new strings here instead of in-code directly, this will help other |
||
+ | -- people to correct spelling mistakes easier and help with translation to |
||
+ | -- other PoE wikis. |
||
− | local |
+ | local i18n = { |
+ | categories = { |
||
− | |||
+ | mods = 'Mods', |
||
− | -- Validate single value properties and set them |
||
+ | }, |
||
− | |||
− | h.validate = {} |
||
− | |||
− | function h.validate.not_nil (args) |
||
− | return function (arg) |
||
− | if g_args[arg] == nil then |
||
− | error(string.format('%s must not be nil', arg)) |
||
− | end |
||
− | end |
||
− | end |
||
− | |||
− | function h.validate.number (args) |
||
− | return function (arg) |
||
− | g_args[arg] = util.cast.number(g_args[arg], args) |
||
− | return g_args[arg] |
||
− | end |
||
− | end |
||
− | |||
− | |||
− | function h.handle_mapped_property_args (map) |
||
− | local properties = {} |
||
+ | tooltips = { |
||
− | for _, data in ipairs(map) do |
||
− | + | -- intro texts |
|
+ | intro_named_id = "'''%s''' is the internal id of [[modifier]] '''%s'''.\n", |
||
− | data.func(data.name) |
||
+ | intro_unnamed_id = "'''%s''' is the internal id of an unnamed [[modifier]].\n", |
||
− | end |
||
− | + | -- core data |
|
+ | id = 'Mod Id', |
||
− | properties[data.property] = g_args[data.name] |
||
− | + | name = 'Name', |
|
+ | mod_group = 'Group', |
||
− | end |
||
+ | mod_type = 'Mod type', |
||
− | |||
+ | domain = 'Domain', |
||
− | g_frame:callParserFunction('#set:', properties) |
||
+ | domain_fmt = '%s (Id: %s)', |
||
− | end |
||
+ | generation_type = 'Generation type', |
||
− | |||
+ | generation_type_fmt = '%s (Id: %s)', |
||
− | function h.create_header(row) |
||
+ | required_level = 'Req. Level', |
||
− | local stat = mw.html.create('span') |
||
+ | stat_text = 'Effect', |
||
− | local text, nsub = mw.ustring.gsub(row['Has stat text'], '%d+', '?') |
||
+ | granted_buff_id = 'Granted Buff Id', |
||
− | stat |
||
+ | granted_buff_value = 'Granted Buff Value', |
||
− | :attr('class', 'mod-table-header-stat') |
||
+ | granted_skill = 'Granted Skill', |
||
− | :wikitext(text) |
||
− | + | tags = 'Tags', |
|
+ | tier_text = 'Tier Text', |
||
+ | -- shared |
||
− | local mgroup = mw.html.create('span') |
||
+ | ordinal = '#', |
||
− | mgroup |
||
+ | |||
− | :attr('class', 'mod-table-header-modgroup') |
||
− | + | -- stats |
|
− | + | stats = 'Stats', |
|
+ | stat_id = 'Stat Id', |
||
+ | min = 'Minimum', |
||
+ | max = 'Maximum', |
||
+ | -- weights |
||
− | local tbl = mw.html.create('table') |
||
+ | spawn_weights = 'Spawn weights', |
||
− | tbl |
||
+ | generation_weights = 'Generation weights', |
||
− | :attr('class', 'wikitable mw-collapsible mw-collapsed mod-table') |
||
− | + | tag = 'Tag', |
|
− | + | weight = 'Weight', |
|
+ | |||
− | :attr('class', 'mod-table-header') |
||
+ | -- sell price |
||
− | :attr('colspan', g_args.colspan) |
||
− | + | sell_price = 'Modifier sell price', |
|
+ | item = 'Item', |
||
− | :attr('class', 'mod-table-header-container') |
||
+ | }, |
||
− | :wikitext(tostring(stat) .. tostring(mgroup)) |
||
+ | |||
− | :done() |
||
− | + | errors = { |
|
− | + | -- |
|
+ | -- Mod template |
||
− | end |
||
+ | -- |
||
+ | sell_price_duplicate_name = 'Do not specify a sell price item name multiple times. Adjust the amount instead.', |
||
+ | sell_price_missing_argument = 'Both %s and %s must be specified', |
||
+ | }, |
||
+ | } |
||
− | function h.format_mod(tbl, row, tags) |
||
− | local tr = tbl:tag('tr') |
||
− | tr |
||
− | :tag('td') |
||
− | :wikitext(string.format('[[%s|%s]]', row[1], row['Has name'])) |
||
− | :attr('class', 'mod-table-cell-name') |
||
− | :done() |
||
− | :tag('td') |
||
− | :wikitext(row['Has level requirement']) |
||
− | :attr('class', 'mod-table-cell-level') |
||
− | :done() |
||
− | :tag('td') |
||
− | :wikitext(row['Has stat text']) |
||
− | :attr('class', 'mod-table-cell-stat') |
||
− | :done() |
||
− | :tag('td') |
||
− | :wikitext(table.concat(tags, ', ')) |
||
− | :attr('class', 'mod-table-cell-tags') |
||
− | :done() |
||
− | end |
||
+ | -- ---------------------------------------------------------------------------- |
||
+ | -- utility / Helper functions |
||
+ | -- ---------------------------------------------------------------------------- |
||
+ | |||
+ | local h = {} |
||
-- ---------------------------------------------------------------------------- |
-- ---------------------------------------------------------------------------- |
||
Line 110: | Line 89: | ||
-- Template: Mod |
-- Template: Mod |
||
-- |
-- |
||
+ | |||
+ | local mod_map = { |
||
+ | main = { |
||
+ | table = 'mods', |
||
+ | display_order = {'id', 'name', 'mod_group', 'mod_type', 'domain', 'generation_type', 'required_level', 'stat_text', 'granted_buff_id', 'granted_buff_value', 'granted_skill', 'tags', 'tier_text'}, |
||
+ | order = {'id', 'name', 'mod_group', '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.tooltips.id, |
||
+ | }, |
||
+ | name = { |
||
+ | name = 'name', |
||
+ | field = 'name', |
||
+ | type = 'String', |
||
+ | wikitext = i18n.tooltips.name, |
||
+ | }, |
||
+ | mod_group = { |
||
+ | name = 'mod_group', |
||
+ | field = 'mod_group', |
||
+ | type = 'String', |
||
+ | wikitext = i18n.tooltips.mod_group, |
||
+ | }, |
||
+ | mod_type = { |
||
+ | name = 'mod_type', |
||
+ | field = 'mod_type', |
||
+ | type = 'String', |
||
+ | wikitext = i18n.tooltips.mod_type, |
||
+ | }, |
||
+ | domain = { |
||
+ | name = 'domain', |
||
+ | field = 'domain', |
||
+ | type = 'Integer', |
||
+ | wikitext = 'Mod domain', |
||
+ | display = function (value) |
||
+ | return string.format(i18n.tooltips.domain_fmt, m_game.constants.mod.domains[value]['short_upper'], value) |
||
+ | end, |
||
+ | }, |
||
+ | generation_type = { |
||
+ | name = 'generation_type', |
||
+ | field = 'generation_type', |
||
+ | type = 'Integer', |
||
+ | wikitext = i18n.tooltips.generation_type, |
||
+ | display = function (value) |
||
+ | return string.format(i18n.tooltips.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.tooltips.required_level, |
||
+ | }, |
||
+ | stat_text = { |
||
+ | name = 'stat_text', |
||
+ | field = 'stat_text', |
||
+ | type = 'Text', |
||
+ | wikitext = i18n.tooltips.stat_text, |
||
+ | }, |
||
+ | stat_text_raw = { |
||
+ | name = nil, |
||
+ | field = 'stat_text_raw', |
||
+ | type = 'Text', |
||
+ | func = function(tpl_args, frame) |
||
+ | if tpl_args.stat_text then |
||
+ | tpl_args.stat_text_raw = string.gsub( |
||
+ | -- [[x]] -> x |
||
+ | string.gsub( |
||
+ | tpl_args.stat_text, '%[%[([^%]|]+)%]%]', '%1' |
||
+ | ), |
||
+ | -- [[x|y]] -> y |
||
+ | '%[%[[^|]+|([^%]|]+)%]%]', '%1' |
||
+ | ) |
||
+ | end |
||
+ | return tpl_args.stat_text_raw |
||
+ | end |
||
+ | }, |
||
+ | granted_buff_id = { |
||
+ | name = 'granted_buff_id', |
||
+ | field = 'granted_buff_id', |
||
+ | type = 'String', |
||
+ | wikitext = i18n.tooltips.granted_buff_id, |
||
+ | }, |
||
+ | granted_buff_value = { |
||
+ | name = 'granted_buff_value', |
||
+ | field = 'granted_buff_value', |
||
+ | type = 'Integer', |
||
+ | wikitext = i18n.tooltips.granted_buff_value, |
||
+ | }, |
||
+ | granted_skill = { |
||
+ | name = 'granted_skill', |
||
+ | field = 'granted_skill', |
||
+ | type = 'String', |
||
+ | wikitext = i18n.tooltips.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.tooltips.tier_text, |
||
+ | }, |
||
+ | }, |
||
+ | }, |
||
+ | 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, |
||
+ | }, |
||
+ | }, |
||
+ | }, |
||
+ | } |
||
+ | |||
+ | p.table_main = m_cargo.declare_factory{data=mod_map.main} |
||
+ | p.table_mod_sell_prices = m_cargo.declare_factory{data=mod_map.mod_sell_prices} |
||
+ | |||
+ | function p.table_mod_stats(frame) |
||
+ | m_cargo.declare(frame, { |
||
+ | _table = 'mod_stats', |
||
+ | id = 'String', |
||
+ | min = 'Integer', |
||
+ | max = 'Integer', |
||
+ | }) |
||
+ | end |
||
+ | |||
-- p.mod{id = "LocalIncreasedPhysicalDamagePercentUniqueOneHandSword2", name = "", mod_group = "LocalPhysicalDamagePercent", 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"} |
-- p.mod{id = "LocalIncreasedPhysicalDamagePercentUniqueOneHandSword2", name = "", mod_group = "LocalPhysicalDamagePercent", 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"} |
||
function p.mod(frame) |
function p.mod(frame) |
||
-- Get args |
-- Get args |
||
− | + | tpl_args = getArgs(frame, { |
|
parentFirst = true |
parentFirst = true |
||
}) |
}) |
||
− | + | frame = m_util.misc.get_frame(frame) |
|
-- |
-- |
||
Line 125: | Line 251: | ||
-- Validate single value properties and set them |
-- Validate single value properties and set them |
||
+ | m_util.args.from_cargo_map{ |
||
− | local map = { |
||
− | + | tpl_args=tpl_args, |
|
− | + | frame=frame, |
|
− | + | table_map=mod_map.main, |
|
− | wikitext = 'Mod Id', |
||
− | }, |
||
− | { |
||
− | name = 'name', |
||
− | property = 'Has name', |
||
− | wikitext = 'Name', |
||
− | }, |
||
− | { |
||
− | name = 'mod_group', |
||
− | property = 'Has mod group', |
||
− | wikitext = 'Group', |
||
− | }, |
||
− | { |
||
− | name = 'mod_type', |
||
− | property = 'Has mod type', |
||
− | wikitext = 'Mod type', |
||
− | }, |
||
− | { |
||
− | name = 'domain', |
||
− | property = 'Has mod domain', |
||
− | func = h.validate.number{min=1, max=13}, |
||
− | wikitext = 'Mod domain', |
||
− | display = function (value) |
||
− | return game.constants.mod.domains[value]['short_upper'] .. ' (Id: ' .. value .. ')' |
||
− | end, |
||
− | }, |
||
− | { |
||
− | name = 'generation_type', |
||
− | property = 'Has mod generation type', |
||
− | func = h.validate.number{min=1, max=12}, |
||
− | wikitext = 'Generation type', |
||
− | display = function (value) |
||
− | return game.constants.mod.generation_types[value]['short_upper'] .. ' (Id: ' .. value .. ')' |
||
− | end, |
||
− | }, |
||
− | { |
||
− | name = 'required_level', |
||
− | property = 'Has level requirement', |
||
− | func = h.validate.number{min=0, max=100}, |
||
− | wikitext = 'Req. level', |
||
− | }, |
||
− | { |
||
− | name = 'stat_text', |
||
− | property = 'Has stat text', |
||
− | wikitext = 'Effect', |
||
− | }, |
||
− | { |
||
− | name = 'granted_buff_id', |
||
− | property = 'Has granted buff id', |
||
− | wikitext = 'Granted Buff Id', |
||
− | }, |
||
− | { |
||
− | name = 'granted_buff_value', |
||
− | property = 'Has granted buff value', |
||
− | wikitext = 'Granted Buff Value', |
||
− | }, |
||
− | { |
||
− | name = 'granted_skill', |
||
− | property = 'Has granted skill id', |
||
− | wikitext = 'Granted Skill', |
||
− | }, |
||
} |
} |
||
+ | -- Validate % set the stat subobjects |
||
− | h.handle_mapped_property_args(map) |
||
+ | m_util.args.stats(tpl_args, {frame=frame}) |
||
− | |||
+ | for _, stat_data in pairs(tpl_args.stats) do |
||
− | -- Validate & set multi value property |
||
+ | m_cargo.store(frame, { |
||
− | |||
+ | _table = 'mod_stats', |
||
− | if g_args['tags'] == nil then |
||
− | + | id = stat_data.id, |
|
+ | min = stat_data.min, |
||
− | else |
||
− | + | max = stat_data.max, |
|
− | + | }) |
|
− | g_args['tags'] = tags |
||
− | |||
− | properties = {} |
||
− | properties['Has tag'] = table.concat(tags, ';') |
||
− | properties['+sep'] = ';' |
||
− | util.smw.set(g_frame, properties) |
||
end |
end |
||
− | |||
− | -- Validate % set the stat subobjects |
||
− | util.args.stats(g_args, {frame=g_frame}) |
||
-- Validate & set spawn weight subobjects |
-- Validate & set spawn weight subobjects |
||
+ | m_util.args.spawn_weight_list(tpl_args, { |
||
− | local i = 0 |
||
− | + | frame=frame, |
|
+ | }) |
||
− | local value = nil |
||
− | |||
− | repeat |
||
− | i = i + 1 |
||
− | id = { |
||
− | tag = string.format('spawn_weight%s_tag', i), |
||
− | value = string.format('spawn_weight%s_value', i), |
||
− | } |
||
− | |||
− | value = { |
||
− | tag = g_args[id.tag], |
||
− | value = g_args[id.value], |
||
− | } |
||
− | |||
− | if value.tag ~= nil and value.value ~= nil then |
||
− | properties = {} |
||
− | properties['Is tag number'] = i |
||
− | properties['Has tag'] = value.tag |
||
− | properties['Has spawn weight'] = h.validate.number({min=0})(id.value) |
||
− | |||
− | util.smw.subobject(g_frame, string.format('spawn weight %s', i), properties) |
||
− | |||
− | elseif not (value.tag == nil and value.value == nil) then |
||
− | error ('Both ' .. id.tag .. ' and ' .. id.value .. ' must be specified') |
||
− | end |
||
− | until value.tag == nil |
||
-- Validate & set generation weight subobjects |
-- Validate & set generation weight subobjects |
||
+ | m_util.args.generation_weight_list(tpl_args, { |
||
− | i = 0 |
||
− | + | frame=frame, |
|
− | + | }) |
|
− | |||
− | repeat |
||
− | i = i + 1 |
||
− | id = { |
||
− | tag = string.format('generation_weight%s_tag', i), |
||
− | value = string.format('generation_weight%s_value', i), |
||
− | } |
||
− | |||
− | value = { |
||
− | tag = g_args[id.tag], |
||
− | value = g_args[id.value], |
||
− | } |
||
− | |||
− | if value.tag ~= nil and value.value ~= nil then |
||
− | properties = {} |
||
− | properties['Is tag number'] = i |
||
− | properties['Has tag'] = value.tag |
||
− | properties['Has generation weight'] = h.validate.number({min=0})(id.value) |
||
− | |||
− | |||
− | util.smw.subobject(g_frame, string.format('generation weight %s', i), properties) |
||
− | |||
− | elseif not (value.tag == nil and value.value == nil) then |
||
− | error ('Both ' .. id.tag .. ' and ' .. id.value .. ' must be specified') |
||
− | end |
||
− | until value.tag == nil |
||
-- Validate & set mod sell values |
-- Validate & set mod sell values |
||
Line 279: | Line 284: | ||
repeat |
repeat |
||
i = i + 1 |
i = i + 1 |
||
− | + | ||
+ | local id = {} |
||
− | name = string.format('sell_price%s_name', i), |
||
+ | value = {} |
||
− | amount = string.format('sell_price%s_amount', i), |
||
+ | 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 = |
+ | value[key] = data.func(tpl_args[id[key]]) |
− | + | end |
|
− | amount = tonumber(g_args[id.amount]), |
||
− | } |
||
if value.name == nil and value.amount == nil then |
if value.name == nil and value.amount == nil then |
||
Line 293: | Line 296: | ||
elseif value.name ~= nil and value.amount ~= nil then |
elseif value.name ~= nil and value.amount ~= nil then |
||
if names[value.name] then |
if names[value.name] then |
||
− | error( |
+ | error(i18n.errors.sell_price_duplicate_name) |
else |
else |
||
names[value.name] = true |
names[value.name] = true |
||
end |
end |
||
+ | |||
− | |||
− | + | local cargo_data = { |
|
− | + | _table = mod_map.mod_sell_prices.table, |
|
+ | } |
||
− | properties['Has sell price amount'] = value.amount |
||
+ | for key, data in pairs(mod_map.mod_sell_prices.fields) do |
||
− | |||
− | + | cargo_data[data.field] = value[key] |
|
+ | end |
||
+ | m_cargo.store(frame, cargo_data) |
||
sell_prices[#sell_prices+1] = value |
sell_prices[#sell_prices+1] = value |
||
else |
else |
||
− | error ( |
+ | error (string.format(i18n.errors.sell_price_missing_arguments, id.name, id.amount)) |
end |
end |
||
Line 325: | Line 330: | ||
:attr('class', 'wikitable') |
:attr('class', 'wikitable') |
||
− | for _, |
+ | for _, key in ipairs(mod_map.main.display_order) do |
+ | local data = mod_map.main.fields[key] |
||
local text |
local text |
||
if data.display == nil then |
if data.display == nil then |
||
− | text = |
+ | text = tpl_args[key] |
else |
else |
||
− | text = data.display( |
+ | text = data.display(tpl_args[key]) |
end |
end |
||
Line 336: | Line 342: | ||
:tag('tr') |
:tag('tr') |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(data.wikitext) |
:done() |
:done() |
||
:tag('td') |
:tag('td') |
||
Line 344: | Line 350: | ||
:done() |
:done() |
||
end |
end |
||
− | |||
− | tbl |
||
− | :tag('tr') |
||
− | :tag('th') |
||
− | :wikitext('[[Property:Has tag|Tags]]') |
||
− | :done() |
||
− | :tag('td') |
||
− | :wikitext(table.concat(g_args['tags'], ', ')) |
||
− | :done() |
||
− | :done() |
||
− | :done() |
||
-- stat table |
-- stat table |
||
Line 364: | Line 359: | ||
:tag('th') |
:tag('th') |
||
:attr('colspan', 4) |
:attr('colspan', 4) |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.stats) |
:done() |
:done() |
||
:done() |
:done() |
||
:tag('tr') |
:tag('tr') |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.ordinal) |
:done() |
:done() |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.stat_id) |
:done() |
:done() |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.min) |
:done() |
:done() |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.max) |
:done() |
:done() |
||
:done() |
:done() |
||
:done() |
:done() |
||
− | for i=1, |
+ | for i=1, #tpl_args.stats do |
local value = { |
local value = { |
||
− | id = |
+ | id = tpl_args['stat' .. i .. '_id'], |
− | min = |
+ | min = tpl_args['stat' .. i .. '_min'], |
− | max = |
+ | max = tpl_args['stat' .. i .. '_max'], |
} |
} |
||
Line 418: | Line 413: | ||
:tag('th') |
:tag('th') |
||
:attr('colspan', 3) |
:attr('colspan', 3) |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.spawn_weights) |
:done() |
:done() |
||
:done() |
:done() |
||
:tag('tr') |
:tag('tr') |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.ordinal) |
:done() |
:done() |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.tag) |
:done() |
:done() |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.weight) |
:done() |
:done() |
||
:done() |
:done() |
||
Line 439: | Line 434: | ||
i = i + 1 |
i = i + 1 |
||
value = { |
value = { |
||
− | tag = |
+ | tag = tpl_args[string.format('spawn_weight%s_tag', i)], |
− | value = |
+ | value = tpl_args[string.format('spawn_weight%s_value', i)], |
} |
} |
||
Line 468: | Line 463: | ||
:tag('th') |
:tag('th') |
||
:attr('colspan', 3) |
:attr('colspan', 3) |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.generation_weights) |
:done() |
:done() |
||
:done() |
:done() |
||
:tag('tr') |
:tag('tr') |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.ordinal) |
:done() |
:done() |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.tag) |
:done() |
:done() |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.weight) |
:done() |
:done() |
||
:done() |
:done() |
||
Line 489: | Line 484: | ||
i = i + 1 |
i = i + 1 |
||
value = { |
value = { |
||
− | tag = |
+ | tag = tpl_args[string.format('generation_weight%s_tag', i)], |
− | value = |
+ | value = tpl_args[string.format('generation_weight%s_value', i)], |
} |
} |
||
Line 517: | Line 512: | ||
:tag('th') |
:tag('th') |
||
:attr('colspan', 2) |
:attr('colspan', 2) |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.sell_price) |
:done() |
:done() |
||
:done() |
:done() |
||
:tag('tr') |
:tag('tr') |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.ordinal) |
:done() |
:done() |
||
:tag('th') |
:tag('th') |
||
− | :wikitext( |
+ | :wikitext(i18n.tooltips.item) |
:done() |
:done() |
||
:done() |
:done() |
||
Line 537: | Line 532: | ||
:done() |
:done() |
||
:tag('td') |
:tag('td') |
||
− | :wikitext( |
+ | :wikitext(string.format('[[%s]]', value.name)) |
:done() |
:done() |
||
:done() |
:done() |
||
Line 546: | Line 541: | ||
out = {} |
out = {} |
||
− | if mw.ustring.find( |
+ | if mw.ustring.find(tpl_args['id'], '_') then |
− | out[#out+1] = |
+ | out[#out+1] = frame:expandTemplate{ title = 'Incorrect title', args = { title=tpl_args['id'] } } .. '\n\n\n' |
end |
end |
||
− | if |
+ | if tpl_args['name'] then |
+ | |||
− | out[#out+1] = string.format("'''%s''' is the internal id of modifier '''%s'''.\n", g_args['id'], g_args['name']) |
||
+ | out[#out+1] = string.format(i18n.tooltips.intro_named_id, tpl_args['id'], tpl_args['name']) |
||
else |
else |
||
− | out[#out+1] = string.format( |
+ | out[#out+1] = string.format(i18n.tooltips.intro_unnamed_id, tpl_args['id']) |
end |
end |
||
-- Categories |
-- Categories |
||
− | cats = { |
+ | cats = {i18n.categories.mods} |
-- Done -> output |
-- Done -> output |
||
− | return tostring(container) .. |
+ | return tostring(container) .. m_util.misc.add_category(cats) .. '\n' .. table.concat(out) |
− | end |
||
− | |||
− | -- |
||
− | -- Template: SMW query mods |
||
− | -- |
||
− | |||
− | function p.query_mods(frame) |
||
− | -- Args |
||
− | g_args = getArgs(frame, { |
||
− | parentFirst = true |
||
− | }) |
||
− | g_frame = util.misc.get_frame(frame) |
||
− | |||
− | g_args.colspan = 4 |
||
− | |||
− | local conditions = {} |
||
− | conditions[#conditions+1] = 'concept' |
||
− | if g_args.tag then |
||
− | conditions[#conditions+1] = string.format('[[Has subobject::<q>[[-Has subobject::+]] [[Has spawn weight::>>0]] [[Has tag::%s]]</q>]]', g_args.tag) |
||
− | end |
||
− | |||
− | g_args.header_level = g_args.header_level or 2 |
||
− | |||
− | -- Fields |
||
− | local fields = {} |
||
− | fields[#fields+1] = '?Is mod' |
||
− | fields[#fields+1] = '?Has name' |
||
− | fields[#fields+1] = '?Has level requirement' |
||
− | fields[#fields+1] = '?Has mod group' |
||
− | fields[#fields+1] = '?Has stat text' |
||
− | -- parameters |
||
− | local parameters = {} |
||
− | parameters.sort = 'Has mod group, ' |
||
− | parameters.limit = 1000 -- lets see |
||
− | |||
− | local data = {} |
||
− | data.header = { |
||
− | prefix = 'Prefix', |
||
− | suffix = 'Suffix', |
||
− | } |
||
− | |||
− | local out = {} |
||
− | for _, v in ipairs({'prefix', 'suffix'}) do |
||
− | out[#out+1] = string.format('<h%i>%s</h%i>', g_args.header_level, data.header[v], g_args.header_level) |
||
− | conditions[1] = string.format('[[Concept:Spawnable named %s item mods]]', v) |
||
− | |||
− | local query |
||
− | local results |
||
− | -- |
||
− | -- Query tags |
||
− | -- |
||
− | query = {} |
||
− | query[#query+1] = string.format('[[-Has subobject::<q>%s</q>]]', table.concat(conditions, ' ')) |
||
− | query[#query+1] = '[[Has tag::+]]' |
||
− | query[#query+1] = '[[Has spawn weight::+]]' |
||
− | --query[#query+1] = '[[Has spawn weight::>>0]]' |
||
− | query[#query+1] = '?Has tag' |
||
− | query[#query+1] = '?Has spawn weight#' -- need native number |
||
− | query.limit = 1000 |
||
− | query.offset = 0 |
||
− | -- Tag order is very important |
||
− | query.sort = ', Is tag number' |
||
− | |||
− | local tags = {} |
||
− | -- this works because lua only considers nil to be false >_> |
||
− | while query.offset do |
||
− | results = util.smw.query(query, g_frame) |
||
− | query.offset = query.offset + #results |
||
− | -- terminates the while if enough reuslts have been fetched |
||
− | if query.offset % 1000 ~= 0 then |
||
− | query.offset = nil |
||
− | end |
||
− | |||
− | for _, row in ipairs(results) do |
||
− | local page, _ = string.gsub(row[1], '#_[%x]+', '') |
||
− | if tags[page] == nil then |
||
− | tags[page] = {} |
||
− | end |
||
− | |||
− | local text |
||
− | if tonumber(row['Has spawn weight']) > 0 then |
||
− | text = '[[File:Yes.png|yes|link=]]' |
||
− | else |
||
− | text = '[[File:No.png|no|link=]]' |
||
− | end |
||
− | |||
− | tags[page][#tags[page]+1] = string.format('%s %s', row['Has tag'], text) |
||
− | end |
||
− | end |
||
− | |||
− | -- |
||
− | -- Query mods |
||
− | -- |
||
− | query = {} |
||
− | for _, v in ipairs(conditions) do |
||
− | query[#query+1] = v |
||
− | end |
||
− | for _, v in ipairs(fields) do |
||
− | query[#query+1] = v |
||
− | end |
||
− | for k, v in pairs(parameters) do |
||
− | query[k] = v |
||
− | end |
||
− | |||
− | results = util.smw.query(query, g_frame) |
||
− | |||
− | local last = '' |
||
− | local tbl = '' |
||
− | for _, row in ipairs(results) do |
||
− | local current = string.gsub(row['Is mod'], '%d+.*', '%%d.*') |
||
− | if string.match(last, current) then |
||
− | h.format_mod(tbl, row, tags[row[1]]) |
||
− | else |
||
− | out[#out+1] = tostring(tbl) |
||
− | tbl = h.create_header(row) |
||
− | h.format_mod(tbl, row, tags[row[1]]) |
||
− | end |
||
− | last = row['Is mod'] |
||
− | end |
||
− | |||
− | -- add the last table |
||
− | out[#out+1] = tostring(tbl) |
||
− | end |
||
− | |||
− | return table.concat(out, '') |
||
− | end |
||
− | |||
− | -- |
||
− | -- Template: SMW mod table |
||
− | -- |
||
− | |||
− | -- =p.mod_list{'Strength1', 'shitty name', 'test', 'test2', userparam='extra_rows=2, show_jewels=1'} |
||
− | -- =p.mod_list{'ColdCritMultiplier', 'shitty name', 'test', 'test2', userparam='extra_rows=2, show_jewels=1'} |
||
− | -- =p.mod_list{'MapMultipleExilesMap2Tier', 'asdasda', 'Area yields 15% more Items<br>8% increased Rarity of Items found in this Area<br>Area is inhabited by 2 additional Rogue Exiles<br>Extra monsters ignore rarity bias (Hidden)<br>+14% Monster pack size', userparam='extra_rows=1, type=map, effect_rowid=2'} |
||
− | |||
− | function p.mod_list(frame) |
||
− | local types = {'map', 'jewel'} |
||
− | |||
− | -- Args |
||
− | g_args = getArgs(frame, { |
||
− | parentFirst = true |
||
− | }) |
||
− | g_frame = util.misc.get_frame(frame) |
||
− | |||
− | -- |
||
− | local args = util.string.split_args(g_args.userparam, {sep=', '}) |
||
− | g_args.userparam = args |
||
− | |||
− | args.extra_rows = (tonumber(args.extra_rows) or 0) |
||
− | if args.show_tags == nil then |
||
− | args.show_tags = true |
||
− | else |
||
− | args.show_tags = util.cast.boolean(args.show_tags) |
||
− | end |
||
− | args.effect_rowid = (tonumber(args.effect_rowid) or 0) + 1 |
||
− | |||
− | tr = mw.html.create('tr') |
||
− | tr |
||
− | :tag('td') |
||
− | :attr('data-sort-value', g_args[2] or g_args[1]) |
||
− | :wikitext(string.format('[[%s|%s]]', g_args[1], g_args[2] or g_args[1])) |
||
− | :done() |
||
− | |||
− | local i = 2 |
||
− | local row_max = i + args.extra_rows |
||
− | local text |
||
− | while i < row_max do |
||
− | i = i + 1 |
||
− | text = g_args[i] or '' |
||
− | text = table.concat(mw.text.split(text, ';', true), '<br>') |
||
− | |||
− | if args.type == 'map' and i == args.effect_rowid then |
||
− | text = mw.text.split(text, '<br>', true) |
||
− | |||
− | local map = { |
||
− | '%d+%% increased Quantity of Items found in this Area', |
||
− | '%d+%% increased Rarity of Items found in this Area', |
||
− | '%+%d+%% Monster pack size', |
||
− | } |
||
− | out = {} |
||
− | |||
− | local valid |
||
− | for k, v in pairs(text) do |
||
− | valid = true |
||
− | for _, pattern in ipairs(map) do |
||
− | if mw.ustring.find(v, pattern) ~= nil then |
||
− | valid = false |
||
− | break |
||
− | end |
||
− | end |
||
− | |||
− | if valid then |
||
− | table.insert(out, v) |
||
− | end |
||
− | end |
||
− | |||
− | text = table.concat(out, '<br>') |
||
− | end |
||
− | |||
− | tr |
||
− | :tag('td') |
||
− | :wikitext(text) |
||
− | :done() |
||
− | end |
||
− | |||
− | |||
− | local query |
||
− | local result |
||
− | |||
− | if args.type == 'map' then |
||
− | query = { |
||
− | string.format('[[-Has subobject::%s]]', g_args[1]), |
||
− | '[[Has stat id::+]]', |
||
− | '?Has stat id', |
||
− | '?Has minimum stat value', |
||
− | '?Has maximum stat value', |
||
− | } |
||
− | |||
− | result = util.smw.query(query, g_frame) |
||
− | |||
− | local stat_map = { |
||
− | ['map_item_drop_quantity_+%'] = {disp=0, sort=0}, |
||
− | ['map_item_drop_rarity_+%'] = {disp=0, sort=0}, |
||
− | ['map_pack_size_+%'] = {disp=0, sort=0}, |
||
− | } |
||
− | |||
− | local stat |
||
− | for _, row in ipairs(result) do |
||
− | stat = stat_map[row['Has stat id']] |
||
− | if stat ~= nil then |
||
− | stat.sort = (row['Has minimum stat value'] + row['Has maximum stat value']) / 2 |
||
− | if row['Has minimum stat value'] ~= row['Has minimum stat value'] then |
||
− | stat.disp = string.format('(%s%-%s)', row['Has minimum stat value'], row['Has maximum stat value']) |
||
− | else |
||
− | stat.disp = row['Has minimum stat value'] |
||
− | end |
||
− | end |
||
− | end |
||
− | |||
− | for _, k in ipairs({'map_item_drop_quantity_+%', 'map_item_drop_rarity_+%', 'map_pack_size_+%'}) do |
||
− | stat = stat_map[k] |
||
− | tr |
||
− | :tag('td') |
||
− | :attr('data-sort-value', stat.sort) |
||
− | :wikitext(stat.disp) |
||
− | :done() |
||
− | :done() |
||
− | end |
||
− | end |
||
− | |||
− | local tags |
||
− | if args.show_tags or args.type == 'jewel' then |
||
− | query = { |
||
− | string.format('[[-Has subobject::%s]]', g_args[1]), |
||
− | '[[Has tag::+]]', |
||
− | '?Has tag', |
||
− | '?Has spawn weight', |
||
− | sort='Is tag number', |
||
− | } |
||
− | |||
− | tags = {} |
||
− | result = util.smw.query(query, g_frame) |
||
− | end |
||
− | |||
− | if args.type == 'jewel' then |
||
− | local jewels = { |
||
− | dex=0, |
||
− | str=0, |
||
− | int=0, |
||
− | pris=0, |
||
− | } |
||
− | |||
− | local cast_tbl = { |
||
− | not_dex={'str', 'int'}, |
||
− | not_int={'str', 'dex'}, |
||
− | not_str={'int', 'dex'}, |
||
− | default={'str','int','dex','pris'}, |
||
− | } |
||
− | |||
− | local i = #result |
||
− | local row |
||
− | local cast |
||
− | while i > 0 do |
||
− | row = result[i] |
||
− | cast = cast_tbl[row['Has tag']] |
||
− | if cast ~= nil then |
||
− | for _, k in ipairs(cast) do |
||
− | jewels[k] = row['Has spawn weight'] |
||
− | end |
||
− | end |
||
− | |||
− | i = i - 1 |
||
− | end |
||
− | |||
− | tr |
||
− | :tag('td') |
||
− | :attr('class', 'table-cell-dex') |
||
− | :wikitext(jewels.dex) |
||
− | :done() |
||
− | :tag('td') |
||
− | :attr('class', 'table-cell-int') |
||
− | :wikitext(jewels.int) |
||
− | :done() |
||
− | :tag('td') |
||
− | :attr('class', 'table-cell-str') |
||
− | :wikitext(jewels.str) |
||
− | :done() |
||
− | :tag('td') |
||
− | :attr('class', 'table-cell-prismatic') |
||
− | :wikitext(jewels.pris) |
||
− | :done() |
||
− | :done() |
||
− | end |
||
− | |||
− | if args.show_tags then |
||
− | for _, row in ipairs(result) do |
||
− | tags[#tags+1] = string.format('%s %s', row['Has tag'], row['Has spawn weight']) |
||
− | end |
||
− | |||
− | tr |
||
− | :tag('td') |
||
− | :wikitext(table.concat(tags, '<br>')) |
||
− | :done() |
||
− | :done() |
||
− | end |
||
− | |||
− | return tostring(tr) |
||
− | end |
||
− | |||
− | function p.item_sell_price(frame) |
||
− | -- Query and sum the vendor prices for an item. |
||
− | -- Unidentified items won't currently show the correct vendor price. Not sure how that is specified, nor is it used at all. |
||
− | -- Expanding {{il}} seems to give a nil /n the first time a new command is run. Doesn't always happen. |
||
− | |||
− | -- = p.item_sell_price{page="Voideye"} |
||
− | -- = p.item_sell_price{page="Pyre"} |
||
− | -- = p.item_sell_price{page="Vessel of Vinktar (Lightning Penetration)"} |
||
− | |||
− | -- Args |
||
− | local g_args = getArgs(frame, { |
||
− | parentFirst = true |
||
− | }) |
||
− | local g_frame = util.misc.get_frame(frame) |
||
− | |||
− | -- Only the explicit modifiers are counted when vendors calculates the price. |
||
− | local condition = string.format('[[%s]]', g_args['page']) |
||
− | local query_item_mods = { |
||
− | condition, |
||
− | '?Has explicit mod ids', |
||
− | '?Has rarity', |
||
− | } |
||
− | local results_query_item_mods = util.smw.query(query_item_mods, g_frame) |
||
− | local item_mods = util.string.split(results_query_item_mods[1]['Has explicit mod ids'], '<MANY>') |
||
− | |||
− | -- If the item has a Normal rarity then the sell price would be a fixed price. |
||
− | if results_query_item_mods[1]['Has rarity'] == 'Normal' then |
||
− | local amount_normal = 1 |
||
− | local currency_normal = 'Scroll Fragment' |
||
− | return string.format('%s %s', amount_normal, g_frame:expandTemplate{title = 'il', args = {currency_normal, currency_normal .. 's'}}) |
||
− | |||
− | -- return string.format('%s %s', amount_normal, currency_normal) |
||
− | end |
||
− | |||
− | local mods_sell_price = {} |
||
− | for _, modid in ipairs(item_mods) do |
||
− | local query_mod_page = { |
||
− | string.format('[[Is mod::%s]]', modid), |
||
− | } |
||
− | local mod_page = util.smw.query(query_mod_page, g_frame) |
||
− | |||
− | local query_mod_sell_price = { |
||
− | string.format('[[-Has subobject::%s]]', mod_page[1][1]), |
||
− | '?Has sell price amount#', |
||
− | '?Has sell price item name', |
||
− | } |
||
− | local results = util.smw.query(query_mod_sell_price, g_frame) |
||
− | |||
− | for _, k in ipairs(results) do |
||
− | if k['Has sell price amount'] ~= '' then |
||
− | if mods_sell_price[k['Has sell price item name']] == nil then |
||
− | mods_sell_price[k['Has sell price item name']] = k['Has sell price amount'] |
||
− | else |
||
− | mods_sell_price[k['Has sell price item name']] = k['Has sell price amount'] + mods_sell_price[k['Has sell price item name']] |
||
− | end |
||
− | end |
||
− | end |
||
− | end |
||
− | |||
− | local out = {} |
||
− | for currency, amount in pairs(mods_sell_price) do |
||
− | out[#out+1] = string.format('%s %s', amount, g_frame:expandTemplate{title = 'il', args = {currency, currency .. 's'}}) |
||
− | end |
||
− | |||
− | return table.concat(out, ', ') |
||
− | end |
||
− | |||
− | |||
− | function p.find_mod_domain(input) |
||
− | -- Find the mod domain based on the item class. |
||
− | local out = input |
||
− | local mod_domains = game.constants.mod.domains |
||
− | |||
− | for i,_ in ipairs(out) do |
||
− | out[i]['Has mod domain'] = 1 |
||
− | for j, row in pairs(mod_domains) do |
||
− | if out[i]['Has item class']:gsub('Map', 'Area'):match(mod_domains[j]['short_upper']) then -- This may need updating if an area item class doesn't have 'Map' in the string, or if the mod domain descriptions doesn't match the item class. |
||
− | out[i]['Has mod domain'] = j |
||
− | end |
||
− | end |
||
− | |||
− | out[i]['Has mod domain text'] = mod_domains[out[i]['Has mod domain']]['short_lower'] |
||
− | end |
||
− | |||
− | -- out[1]['Has mod domain'] = 1 |
||
− | -- out[1]['Has mod domain text'] = 'item' |
||
− | |||
− | return out |
||
− | end |
||
− | |||
− | function p.get_item_tags(frame) |
||
− | -- This function queries for the tags for a specific item. |
||
− | |||
− | -- Args |
||
− | local g_args = getArgs(frame, { |
||
− | parentFirst = true |
||
− | }) |
||
− | local g_frame = util.misc.get_frame(frame) |
||
− | |||
− | local item_name = g_args[1] |
||
− | |||
− | local query = { |
||
− | string.format('[[Has name::%s]]', item_name), |
||
− | '?Has tags', |
||
− | '?Has base strength requirement', |
||
− | '?Has base intelligence requirement', |
||
− | '?Has base dexterity requirement', |
||
− | '?Has item class' |
||
− | } |
||
− | local results = util.smw.query(query, g_frame) |
||
− | |||
− | for i,_ in ipairs(results) do |
||
− | results[i]['Has tags'] = results[i]['Has tags']:gsub('(<MANY>)', ', ') -- Remove unnecessary symbols. |
||
− | |||
− | function table.reverse(a) -- Reverse order. Item tags are often sorted from lowest to highest priority. Therefore reversing order should lead to finding a match faster most of the time. |
||
− | local res = {} |
||
− | for i = #a, 1, -1 do |
||
− | res[#res+1] = a[i] |
||
− | end |
||
− | return res |
||
− | end |
||
− | results[i]['Has tags'] = table.concat(table.reverse(util.string.split(results[i]['Has tags'], ', ')), ', ') |
||
− | end |
||
− | |||
− | results = p.find_mod_domain(results) |
||
− | |||
− | return results |
||
− | end |
||
− | |||
− | function p.header(str) |
||
− | -- Replace specific numbers with a generic #. |
||
− | local s = table.concat(util.string.split(str, '%(%d+%.*%d*%-%d+%.*%d*%)'), '#') |
||
− | s = table.concat(util.string.split(s, '%d+%.*%d*'), '#') |
||
− | s = table.concat(util.string.split(s, '<br>'), ', ') |
||
− | |||
− | return s |
||
− | end |
||
− | |||
− | function p.get_spawn_chance(frame) |
||
− | -- Calculates the spawn chance of a set of mods that all have a spawn weight. |
||
− | |||
− | -- Args |
||
− | local g_args = getArgs(frame, { |
||
− | parentFirst = true |
||
− | }) |
||
− | local g_frame = util.misc.get_frame(frame) |
||
− | |||
− | local tbl = g_args['tbl'] |
||
− | local chance_multiplier = tonumber(g_args['chance_multiplier']) or 1 -- Probabillities affecting the result besides the spawn weight. |
||
− | |||
− | local N = 0 |
||
− | for i,_ in ipairs(tbl) do |
||
− | N = N + tbl[i]['Has spawn weight'] -- Total number of outcomes. |
||
− | end |
||
− | |||
− | for i,_ in ipairs(tbl) do |
||
− | local n = tbl[i]['Has spawn weight'] -- Number of ways it can happen. |
||
− | |||
− | tbl[i]['Has spawn chance'] = string.format("%0.2f%%", n/N * chance_multiplier*100) -- Truncated value. |
||
− | end |
||
− | |||
− | return tbl |
||
− | end |
||
− | |||
− | function p.drop_down_table(frame) |
||
− | -- Misses forsaken masters currently. |
||
− | -- Add a proper expand/collapse toggle for the entire header row so it reacts together with mw-collapsible. |
||
− | -- Show Mod group in a better way perhaps: |
||
− | -- Mod group (expanded) |
||
− | -- # to Damage (Collapsed) |
||
− | -- 3 to Damage |
||
− | -- 5 to Damage |
||
− | -- Add a better solution for properties inside subobjects, for extra_properties. Note that properties already queried for should not be added with this solution. |
||
− | |||
− | -- Weapons |
||
− | -- p.drop_down_table{item = 'Rusted Hatchet', header = 'One Handed Axes'} |
||
− | -- p.drop_down_table{item = 'Stone Axe', header = 'Two Handed Axes'} |
||
− | |||
− | -- Accessories |
||
− | -- p.drop_down_table{item = 'Amber Amulet', header = 'Amulets'} |
||
− | |||
− | -- Jewels |
||
− | -- p.drop_down_table{item = 'Cobalt Jewel', header = 'Jewels'} |
||
− | |||
− | -- Armour |
||
− | -- p.drop_down_table{item = 'Plate Vest', header = 'Armour body armours'} |
||
− | -- p.drop_down_table{item = 'Iron Greaves', header = 'Armour boots'} |
||
− | -- p.drop_down_table{item = 'Iron Gauntlets', header = 'Armour gloves'} |
||
− | -- p.drop_down_table{item = 'Iron Hat', header = 'Armour helmets'} |
||
− | -- p.drop_down_table{item = 'Splintered Tower Shield', header = 'Armour shields'} |
||
− | |||
− | -- p.drop_down_table{item = 'Fishing Rod', header = 'FISH PLEASE', item_tags = 'fishing_rod', extra_properties = 'Has spawn weight, Has spawn chance'} |
||
− | |||
− | |||
− | -- Args |
||
− | local g_args = getArgs(frame, { |
||
− | parentFirst = true |
||
− | }) |
||
− | local g_frame = util.misc.get_frame(frame) |
||
− | |||
− | local get_item_tags = p.get_item_tags{g_args.item}[1] |
||
− | local item_tags = {} |
||
− | if g_args.item_tags ~= nil then |
||
− | item_tags = util.string.split(g_args.item_tags, ', ') |
||
− | else |
||
− | item_tags = util.string.split(get_item_tags['Has tags'], ', ') |
||
− | end |
||
− | |||
− | local header = g_args['header'] |
||
− | if header == nil then |
||
− | header = table.concat(item_tags, ', ') |
||
− | end |
||
− | |||
− | -- Conditions |
||
− | local conditions = {} |
||
− | conditions[1] = 'concept' -- Reserve for Concepts. |
||
− | conditions[#conditions+1] = string.format('[[Has subobject::<q> [[Has tag::%s]] </q>]]', table.concat(item_tags, ' || ')) |
||
− | |||
− | -- Fields |
||
− | local all_fields = { |
||
− | 1, |
||
− | 'Is mod', |
||
− | 'Has name', |
||
− | 'Has level requirement', |
||
− | 'Has mod group', |
||
− | 'Has mod type', |
||
− | 'Has stat text', |
||
− | } |
||
− | |||
− | local extra_properties = {} |
||
− | if g_args.extra_properties ~= nil then |
||
− | extra_properties = util.string.split(g_args.extra_properties, ', ') |
||
− | local a = #all_fields |
||
− | for _,v in ipairs(extra_properties) do |
||
− | table.insert(all_fields, a+1, v) |
||
− | end |
||
− | end |
||
− | |||
− | local fields = {} |
||
− | for _,v in ipairs(all_fields) do |
||
− | fields[#fields+1] = string.format('?%s', v) |
||
− | end |
||
− | |||
− | -- Parameters |
||
− | local parameters = { |
||
− | sort = 'Has mod group, Has mod type, Has level requirement', |
||
− | -- limit = 1000, -- lets see |
||
− | offset = 0, |
||
− | } |
||
− | |||
− | local data = {} |
||
− | data = { |
||
− | [1] = { |
||
− | header = 'Prefix', |
||
− | generation_type = 'prefix', |
||
− | condition = string.format('[[Concept:Spawnable named prefix %s mods]]', get_item_tags['Has mod domain text']), |
||
− | }, |
||
− | [2] = { |
||
− | header = 'Suffix', |
||
− | generation_type = 'suffix', |
||
− | condition = string.format('[[Concept:Spawnable named suffix %s mods]]', get_item_tags['Has mod domain text']), |
||
− | }, |
||
− | [3] = { |
||
− | header = 'Corrupted', |
||
− | generation_type = 'corrupted', |
||
− | condition = string.format('[[Concept:Spawnable corrupted %s mods]]', get_item_tags['Has mod domain text']), |
||
− | chance_multiplier = 1/4, -- See Vaal orb, for the 4 possible events. |
||
− | }, |
||
− | -- [4] = { |
||
− | -- header = 'Forsaken masters', |
||
− | -- generation_type = 'master', |
||
− | -- condition = '[[Concept:AAAAAAAAAAAAAAAAAAAA]]', |
||
− | -- }, |
||
− | } |
||
− | |||
− | -- Define the output. |
||
− | local out = {} |
||
− | out[#out+1] = string.format('==%s== \n', header) |
||
− | out[#out+1] = '<div style="float: right; text-align:center"><div class="mw-collapsible-collapse-all" style="cursor:pointer;">[Collapse All]</div><hr><div class="mw-collapsible-expand-all" style="cursor:pointer;">[Expand All]</div></div>' |
||
− | out[#out+1] = string.format('The table below displays the available [[modifiers]] for [[item]]s such as %s.<br><br><br>', m_item.item_link{get_item_tags[1]}) |
||
− | |||
− | local results = {} |
||
− | local item_mods = {} |
||
− | local tableIndex = -1 |
||
− | |||
− | for i_type,_ in ipairs(data) do |
||
− | local generation_type = data[i_type]['generation_type'] |
||
− | |||
− | local query = {} |
||
− | |||
− | conditions[1] = data[i_type]['condition'] |
||
− | query[#query+1] = table.concat(conditions, ' ') |
||
− | |||
− | for _, v in ipairs(fields) do |
||
− | query[#query+1] = v |
||
− | end |
||
− | for k, v in pairs(parameters) do |
||
− | query[k] = v |
||
− | end |
||
− | |||
− | if results[generation_type] == nil then |
||
− | results[generation_type] = {} |
||
− | end |
||
− | repeat |
||
− | local result = util.smw.query(query, g_frame) |
||
− | query.offset = query.offset + #result -- Possible error source if only one mod is missing. |
||
− | |||
− | for _,v in ipairs(result) do |
||
− | results[generation_type][#results[generation_type]+1] = v |
||
− | end |
||
− | until #result < 1000 |
||
− | |||
− | item_mods[generation_type] = {} |
||
− | |||
− | local container = mw.html.create('div') |
||
− | :attr('style', 'vertical-align:top; display:inline-block;') |
||
− | |||
− | if #results[generation_type] > 0 then |
||
− | query_mod_tags = { |
||
− | string.format('[[-Has subobject::<q>%s</q>]]', table.concat(conditions, ' ')), |
||
− | '?Has tag#', |
||
− | '?Has spawn weight#', |
||
− | '?Is tag number#', |
||
− | offset = 0, |
||
− | } |
||
− | |||
− | local results_mod_tags = {} |
||
− | local mod_data_subobject = {} |
||
− | repeat -- Query again and add the remaining results. |
||
− | results_mod_tags[#results_mod_tags+1] = util.smw.query(query_mod_tags, g_frame) |
||
− | query_mod_tags.offset = query_mod_tags.offset + #results_mod_tags[#results_mod_tags] |
||
− | |||
− | for _,v in ipairs(results_mod_tags[#results_mod_tags]) do |
||
− | local pagename = util.string.split(v[1], '#')[1] |
||
− | if mod_data_subobject[pagename] == nil then |
||
− | mod_data_subobject[pagename] = {} |
||
− | end |
||
− | |||
− | local subobjectname = v[1] |
||
− | mod_data_subobject[pagename][subobjectname] = v |
||
− | end |
||
− | until #results_mod_tags[#results_mod_tags] < 1000 |
||
− | |||
− | local last |
||
− | for i, v in ipairs(results[generation_type]) do -- Loop through all the results from the smw query. |
||
− | local pagename = results[generation_type][i][1] |
||
− | |||
− | local j = 0 |
||
− | local tag_match_stop |
||
− | repeat -- Loop through the mod tags until a match is found. |
||
− | j = j+1 |
||
− | local subobjectname = string.format('%s#%s_%s', pagename, 'spawn_weight', j) |
||
− | local mod_tag = mod_data_subobject[pagename][subobjectname]['Has tag'] |
||
− | local mod_tag_weight = tonumber(mod_data_subobject[pagename][subobjectname]['Has spawn weight']) |
||
− | |||
− | local y = 0 |
||
− | local tag_match_add |
||
− | repeat -- Loop through the item tags until it matches the mod tag and the mod tag has a value. |
||
− | y = y+1 |
||
− | tag_match_stop = ((mod_tag == item_tags[y]) and ((mod_tag_weight or -1) >= 0)) or (mod_data_subobject[pagename][subobjectname] == nil) |
||
− | tag_match_add = (mod_tag == item_tags[y]) and ((mod_tag_weight or -1) > 0) |
||
− | until tag_match_stop or y == #item_tags |
||
− | |||
− | if tag_match_add then |
||
− | local mod_scope = 'Global' |
||
− | for subobject, subobject_val in pairs(mod_data_subobject[pagename]) do |
||
− | if subobject:find('stat.*local') ~= nil then -- If at least one stat is local then change the scope of the mod to local. |
||
− | mod_scope = 'Local' |
||
− | end |
||
− | |||
− | if subobject == subobjectname then -- Complement with the properties the matching subobject has. |
||
− | for property,w in pairs(subobject_val) do |
||
− | if results[generation_type][i][property] == nil then |
||
− | results[generation_type][i][property] = {} |
||
− | end |
||
− | |||
− | results[generation_type][i][property] = w |
||
− | end |
||
− | end |
||
− | end |
||
− | |||
− | local a = #item_mods[generation_type] |
||
− | item_mods[generation_type][a+1] = {} |
||
− | for _,property in ipairs(all_fields) do -- Filtered item modifier table: |
||
− | item_mods[generation_type][a+1][property] = results[generation_type][i][property] |
||
− | end |
||
− | item_mods[generation_type][a+1]['Has mod scope'] = mod_scope |
||
− | end |
||
− | until tag_match_stop |
||
− | end |
||
− | |||
− | |||
− | |||
− | for _,v in ipairs(extra_properties) do |
||
− | if v == 'Has spawn chance' then |
||
− | item_mods[generation_type] = p.get_spawn_chance{tbl = item_mods[generation_type], chance_multiplier = data[i_type]['chance_multiplier']} |
||
− | break |
||
− | end |
||
− | end |
||
− | |||
− | |||
− | |||
− | local headers = container -- Display in <table>. |
||
− | headers |
||
− | :tag('h3') |
||
− | :wikitext(string.format('%s', data[i_type]['header'])) |
||
− | :done() |
||
− | :done() |
||
− | local tbl, last |
||
− | for _, mod_properties in ipairs(item_mods[generation_type]) do |
||
− | if mod_properties['Has mod group'] ~= last then |
||
− | |||
− | local count = {} |
||
− | for _,n in ipairs(item_mods[generation_type]) do -- Check if there are multiple mod types in the same mod group: |
||
− | if n['Has mod group'] == mod_properties['Has mod group'] then |
||
− | count[n['Has mod type']] = 1 |
||
− | end |
||
− | end |
||
− | |||
− | local number_of_mod_types = 0 |
||
− | for _ in pairs(count) do |
||
− | number_of_mod_types = number_of_mod_types + 1 |
||
− | end |
||
− | |||
− | if number_of_mod_types > 1 then |
||
− | tbl_caption = string.format('%s', util.html.poe_color('mod', 'Mod group: ' .. mod_properties['Has mod group'])) |
||
− | else |
||
− | tbl_caption = string.format('%s (%s)', util.html.poe_color('mod', p.header(mod_properties['Has stat text'])), mod_properties['Has mod scope']) |
||
− | end |
||
− | |||
− | tableIndex = tableIndex+1 |
||
− | tbl = container:tag('table') |
||
− | tbl |
||
− | :attr('class', 'mw-collapsible mw-collapsed') |
||
− | :attr('style', 'text-align:left; line-height:1.60em; width:810px;') |
||
− | :tag('th') |
||
− | :attr('class', string.format('mw-customtoggle-%s', tableIndex)) |
||
− | :attr('style', 'text-align:left; line-height:1.40em; border-bottom:1pt solid dimgrey;') |
||
− | :attr('colspan', '3' .. #extra_properties) |
||
− | :wikitext(tbl_caption) |
||
− | :done() |
||
− | :done() |
||
− | end |
||
− | |||
− | local mod_name = mod_properties['Has name'] |
||
− | if mod_name == '' then |
||
− | mod_name = mod_properties['Is mod'] |
||
− | end |
||
− | |||
− | local td = mw.html.create('td') |
||
− | if extra_properties ~= nil then |
||
− | for _, extra_property in ipairs(extra_properties) do |
||
− | td |
||
− | :attr('width', '*') |
||
− | :wikitext(string.format('%s: %s ', extra_property, mod_properties[extra_property])) |
||
− | :done() |
||
− | end |
||
− | end |
||
− | |||
− | tbl |
||
− | :tag('tr') |
||
− | :attr('class', 'mw-collapsible mw-collapsed') |
||
− | :attr('id', string.format('mw-customcollapsible-%s', tableIndex)) |
||
− | :tag('td') |
||
− | :attr('width', '160') |
||
− | :wikitext(string.format(' [[%s|%s]]', mod_properties[1], mod_name:gsub('%s', ' '))) |
||
− | :done() |
||
− | :tag('td') |
||
− | :attr('width', '1') |
||
− | :wikitext(string.format('%s %s',game.level_requirement['short_upper']:gsub('%s', ' '), mod_properties['Has level requirement'])) |
||
− | :done() |
||
− | :tag('td') |
||
− | :attr('width', '*') |
||
− | :wikitext(string.format('%s', util.html.poe_color('mod', mod_properties['Has stat text']:gsub('<br>', ', ')) )) |
||
− | :done() |
||
− | :node(td) |
||
− | :done() |
||
− | :done() |
||
− | |||
− | last = mod_properties['Has mod group'] |
||
− | end |
||
− | end |
||
− | |||
− | out[#out+1] = tostring(container) |
||
− | end |
||
− | |||
− | return table.concat(out,'') |
||
end |
end |
||
Latest revision as of 04:06, 2 May 2021
This Lua module is used on a very large number of pages. To avoid large-scale disruption and unnecessary server load, any changes to this module should first be tested in its /sandbox or /testcases subpages. The tested changes can then be added to this page in one single edit. Please consider discussing any changes on the talk page before implementing them. |
This module depends on the following other modules: |
Module for handling for Mods with Semantic MediaWiki support.
List of currently implemented templates
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 for mod related templates
--
local getArgs = require('Module:Arguments').getArgs
local m_util = require('Module:Util')
local m_cargo = require('Module:Cargo')
local m_game = require('Module:Game')
local f_item_link = require('Module:Item link').item_link
local p = {}
-- ----------------------------------------------------------------------------
-- Strings
-- ----------------------------------------------------------------------------
-- This section contains strings used by this module.
-- Add new strings here instead of in-code directly, this will help other
-- people to correct spelling mistakes easier and help with translation to
-- other PoE wikis.
local i18n = {
categories = {
mods = 'Mods',
},
tooltips = {
-- intro texts
intro_named_id = "'''%s''' is the internal id of [[modifier]] '''%s'''.\n",
intro_unnamed_id = "'''%s''' is the internal id of an unnamed [[modifier]].\n",
-- core data
id = 'Mod Id',
name = 'Name',
mod_group = 'Group',
mod_type = 'Mod type',
domain = 'Domain',
domain_fmt = '%s (Id: %s)',
generation_type = 'Generation type',
generation_type_fmt = '%s (Id: %s)',
required_level = 'Req. Level',
stat_text = 'Effect',
granted_buff_id = 'Granted Buff Id',
granted_buff_value = 'Granted Buff Value',
granted_skill = 'Granted Skill',
tags = 'Tags',
tier_text = 'Tier Text',
-- shared
ordinal = '#',
-- stats
stats = 'Stats',
stat_id = 'Stat Id',
min = 'Minimum',
max = 'Maximum',
-- weights
spawn_weights = 'Spawn weights',
generation_weights = 'Generation weights',
tag = 'Tag',
weight = 'Weight',
-- sell price
sell_price = 'Modifier sell price',
item = 'Item',
},
errors = {
--
-- Mod template
--
sell_price_duplicate_name = 'Do not specify a sell price item name multiple times. Adjust the amount instead.',
sell_price_missing_argument = 'Both %s and %s must be specified',
},
}
-- ----------------------------------------------------------------------------
-- utility / Helper functions
-- ----------------------------------------------------------------------------
local h = {}
-- ----------------------------------------------------------------------------
-- Templates
-- ----------------------------------------------------------------------------
--
-- Template: Mod
--
local mod_map = {
main = {
table = 'mods',
display_order = {'id', 'name', 'mod_group', 'mod_type', 'domain', 'generation_type', 'required_level', 'stat_text', 'granted_buff_id', 'granted_buff_value', 'granted_skill', 'tags', 'tier_text'},
order = {'id', 'name', 'mod_group', '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.tooltips.id,
},
name = {
name = 'name',
field = 'name',
type = 'String',
wikitext = i18n.tooltips.name,
},
mod_group = {
name = 'mod_group',
field = 'mod_group',
type = 'String',
wikitext = i18n.tooltips.mod_group,
},
mod_type = {
name = 'mod_type',
field = 'mod_type',
type = 'String',
wikitext = i18n.tooltips.mod_type,
},
domain = {
name = 'domain',
field = 'domain',
type = 'Integer',
wikitext = 'Mod domain',
display = function (value)
return string.format(i18n.tooltips.domain_fmt, m_game.constants.mod.domains[value]['short_upper'], value)
end,
},
generation_type = {
name = 'generation_type',
field = 'generation_type',
type = 'Integer',
wikitext = i18n.tooltips.generation_type,
display = function (value)
return string.format(i18n.tooltips.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.tooltips.required_level,
},
stat_text = {
name = 'stat_text',
field = 'stat_text',
type = 'Text',
wikitext = i18n.tooltips.stat_text,
},
stat_text_raw = {
name = nil,
field = 'stat_text_raw',
type = 'Text',
func = function(tpl_args, frame)
if tpl_args.stat_text then
tpl_args.stat_text_raw = string.gsub(
-- [[x]] -> x
string.gsub(
tpl_args.stat_text, '%[%[([^%]|]+)%]%]', '%1'
),
-- [[x|y]] -> y
'%[%[[^|]+|([^%]|]+)%]%]', '%1'
)
end
return tpl_args.stat_text_raw
end
},
granted_buff_id = {
name = 'granted_buff_id',
field = 'granted_buff_id',
type = 'String',
wikitext = i18n.tooltips.granted_buff_id,
},
granted_buff_value = {
name = 'granted_buff_value',
field = 'granted_buff_value',
type = 'Integer',
wikitext = i18n.tooltips.granted_buff_value,
},
granted_skill = {
name = 'granted_skill',
field = 'granted_skill',
type = 'String',
wikitext = i18n.tooltips.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.tooltips.tier_text,
},
},
},
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,
},
},
},
}
p.table_main = m_cargo.declare_factory{data=mod_map.main}
p.table_mod_sell_prices = m_cargo.declare_factory{data=mod_map.mod_sell_prices}
function p.table_mod_stats(frame)
m_cargo.declare(frame, {
_table = 'mod_stats',
id = 'String',
min = 'Integer',
max = 'Integer',
})
end
-- p.mod{id = "LocalIncreasedPhysicalDamagePercentUniqueOneHandSword2", name = "", mod_group = "LocalPhysicalDamagePercent", 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"}
function p.mod(frame)
-- Get args
tpl_args = getArgs(frame, {
parentFirst = true
})
frame = m_util.misc.get_frame(frame)
--
-- Validation & semantic properties
--
-- Validate single value properties and set them
m_util.args.from_cargo_map{
tpl_args=tpl_args,
frame=frame,
table_map=mod_map.main,
}
-- Validate % set the stat subobjects
m_util.args.stats(tpl_args, {frame=frame})
for _, stat_data in pairs(tpl_args.stats) do
m_cargo.store(frame, {
_table = 'mod_stats',
id = stat_data.id,
min = stat_data.min,
max = stat_data.max,
})
end
-- Validate & set spawn weight subobjects
m_util.args.spawn_weight_list(tpl_args, {
frame=frame,
})
-- Validate & set generation weight subobjects
m_util.args.generation_weight_list(tpl_args, {
frame=frame,
})
-- Validate & set mod sell values
i = 0
local names = {}
local sell_prices = {}
repeat
i = i + 1
local id = {}
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(frame, 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
--
-- Display
--
local container = mw.html.create('div')
container
:attr('class', 'modbox')
-- core stats
local tbl = container:tag('table')
tbl
:attr('class', 'wikitable')
for _, key in ipairs(mod_map.main.display_order) do
local data = mod_map.main.fields[key]
local text
if data.display == nil then
text = tpl_args[key]
else
text = data.display(tpl_args[key])
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
:attr('class', 'wikitable sortable')
:tag('tr')
:tag('th')
:attr('colspan', 4)
:wikitext(i18n.tooltips.stats)
:done()
:done()
:tag('tr')
:tag('th')
:wikitext(i18n.tooltips.ordinal)
:done()
:tag('th')
:wikitext(i18n.tooltips.stat_id)
:done()
:tag('th')
:wikitext(i18n.tooltips.min)
:done()
:tag('th')
:wikitext(i18n.tooltips.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
:attr('class', 'wikitable sortable')
:tag('tr')
:tag('th')
:attr('colspan', 3)
:wikitext(i18n.tooltips.spawn_weights)
:done()
:done()
:tag('tr')
:tag('th')
:wikitext(i18n.tooltips.ordinal)
:done()
:tag('th')
:wikitext(i18n.tooltips.tag)
:done()
:tag('th')
:wikitext(i18n.tooltips.weight)
:done()
:done()
:done()
i = 0
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
:attr('class', 'wikitable sortable')
:tag('tr')
:tag('th')
:attr('colspan', 3)
:wikitext(i18n.tooltips.generation_weights)
:done()
:done()
:tag('tr')
:tag('th')
:wikitext(i18n.tooltips.ordinal)
:done()
:tag('th')
:wikitext(i18n.tooltips.tag)
:done()
:tag('th')
:wikitext(i18n.tooltips.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
:attr('class', 'wikitable sortable')
:tag('tr')
:tag('th')
:attr('colspan', 2)
:wikitext(i18n.tooltips.sell_price)
:done()
:done()
:tag('tr')
:tag('th')
:wikitext(i18n.tooltips.ordinal)
:done()
:tag('th')
:wikitext(i18n.tooltips.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
out = {}
if mw.ustring.find(tpl_args['id'], '_') then
out[#out+1] = frame:expandTemplate{ title = 'Incorrect title', args = { title=tpl_args['id'] } } .. '\n\n\n'
end
if tpl_args['name'] then
out[#out+1] = string.format(i18n.tooltips.intro_named_id, tpl_args['id'], tpl_args['name'])
else
out[#out+1] = string.format(i18n.tooltips.intro_unnamed_id, tpl_args['id'])
end
-- Categories
cats = {i18n.categories.mods}
-- Done -> output
return tostring(container) .. m_util.misc.add_category(cats) .. '\n' .. table.concat(out)
end
return p