Module:Modifier compatibility: Difference between revisions
Jump to navigation
Jump to search
Neokowloon (talk | contribs) (the unveiled mod is in unveiled domain now. Crafted version does not have spawn weight and probably out of scope of to list those) |
No edit summary |
||
(6 intermediate revisions by the same user not shown) | |||
Line 8: | Line 8: | ||
require('Module:No globals') | require('Module:No globals') | ||
local m_util = require('Module:Util') | local m_util = require('Module:Util') | ||
local m_item_util = require('Module:Item util') | |||
local m_cargo = require('Module:Cargo') | local m_cargo = require('Module:Cargo') | ||
Line 14: | Line 15: | ||
local m_game = mw.loadData('Module:Game') | local m_game = mw.loadData('Module:Game') | ||
-- The cfg table contains all localisable strings and configuration, to make it | -- The cfg table contains all localisable strings and configuration, to make it | ||
Line 30: | Line 28: | ||
local h = {} | local h = {} | ||
function h.genericize_stat_text(str) | |||
function h. | |||
--[[ | --[[ | ||
This function replaces | This function replaces individual numbers and ranges of numbers with a number sign (#). | ||
]] | ]] | ||
str = string.gsub(str, '%(%d+%.?%d*%-%d+%.?%d*%)', '#') | |||
str = string.gsub(str, '%d+%.?%d*', '#') | |||
return str | |||
end | end | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
-- | -- Data and configuration for item mods | ||
-- ---------------------------------------------------------------------------- | -- ---------------------------------------------------------------------------- | ||
local | local item_mods = {} | ||
item_mods.sections = { | |||
{ | { | ||
heading = i18n.item_mods.standard_mods, | |||
where = function( | where = function (item_data) | ||
return | return [[ | ||
mods.id NOT LIKE "%%Royale%%" | |||
]] | |||
end, | end, | ||
}, | }, | ||
{ | { | ||
show = function (item_data) | |||
return item_data.can_have_influences | |||
return | |||
end, | end, | ||
tags = function (item_data) | |||
return {item_data.addon_tags.shaper} | |||
tags | |||
return | |||
end, | end, | ||
heading = i18n.item_mods.shaper_mods, | |||
}, | }, | ||
{ | { | ||
show = function (item_data) | |||
return item_data.can_have_influences | |||
return | |||
end, | end, | ||
tags = function (item_data) | |||
return {item_data.addon_tags.elder} | |||
tags | |||
return | |||
end, | end, | ||
heading = i18n.item_mods.elder_mods, | |||
}, | }, | ||
{ | { | ||
show = function (item_data) | |||
return item_data.can_have_influences | |||
return | |||
end, | end, | ||
tags = function (item_data) | |||
return {item_data.addon_tags.crusader} | |||
return | |||
end, | end, | ||
heading = i18n.item_mods.crusader_mods, | |||
}, | }, | ||
{ | { | ||
show = function (item_data) | |||
return item_data.can_have_influences | |||
return | |||
end, | end, | ||
tags = function (item_data) | |||
return {item_data.addon_tags.eyrie} | |||
tags | |||
return | |||
end, | end, | ||
heading = i18n.item_mods.redeemer_mods, | |||
}, | }, | ||
{ | { | ||
show = function (item_data) | |||
return item_data.can_have_influences | |||
return | |||
end, | end, | ||
tags = function (item_data) | |||
return {item_data.addon_tags.basilisk} | |||
tags | |||
return | |||
end, | end, | ||
heading = i18n.item_mods.hunter_mods, | |||
}, | }, | ||
{ | { | ||
show = function (item_data) | |||
return item_data.can_have_influences | |||
return | |||
end, | end, | ||
tags = function (item_data) | |||
return {item_data.addon_tags.adjudicator} | |||
tags | |||
return | |||
end, | end, | ||
heading = i18n.item_mods.warlord_mods, | |||
}, | }, | ||
{ | { | ||
show = function (item_data) | |||
return item_data.can_have_veiled_mods | |||
return | |||
end, | end, | ||
heading = i18n.item_mods.veiled_mods, | |||
domain = cfg.mod_domains.unveiled, | |||
}, | }, | ||
{ | { | ||
show = function (item_data) | |||
return item_data.can_be_corrupted | |||
return | |||
end, | end, | ||
heading = i18n.item_mods.corruption_implicit_mods, | |||
generation_types = { | |||
{ | |||
id = cfg.mod_generation_types.corrupted, | |||
}, | |||
}, | |||
}, | }, | ||
{ | { | ||
show = function (item_data) | |||
return cfg.eldritch_implicit_item_classes[item_data.class_id] or false | |||
return | |||
end, | end, | ||
heading = i18n.item_mods.eldritch_implicit_mods, | |||
generation_types = { | |||
{ | |||
id = cfg.mod_generation_types.searing_exarch, | |||
heading = i18n.item_mods.searing_exarch, | |||
}, | |||
{ | |||
id = cfg.mod_generation_types.eater_of_worlds, | |||
heading = i18n.item_mods.eater_of_worlds, | |||
}, | |||
}, | |||
}, | }, | ||
} | } | ||
Line 490: | Line 206: | ||
]] | ]] | ||
-- | -- Support legacy args | ||
tpl_args.item_name = tpl_args.item_name or tpl_args.item | |||
-- Query item | |||
local item_data = m_item_util.query_item(tpl_args, { | |||
}) | fields = { | ||
if | 'items.name=name', | ||
'items.tags=tags', | |||
'items.inventory_icon=inventory_icon', | |||
'items.html=html', | |||
} | |||
}) | |||
if item_data.error then | |||
if not m_util.cast.boolean(tpl_args.nocat) then | |||
return item_data.error:get_html() .. item_data.error:get_category() | |||
end | end | ||
return item_data.error:get_html() | |||
end | end | ||
-- Get the domain, if it's not defined in the table assume it's | -- Get the domain, if it's not defined in the table assume it's | ||
-- in the item domain. | -- in the item domain. | ||
item_data | item_data.domain = tonumber(tpl_args.domain) or cfg.mod_domains_by_item_class[item_data.class_id] or cfg.mod_domains.item | ||
-- Format item tags | |||
tpl_args.item_tags = m_util.cast.table(tpl_args.item_tags or item_data.tags) | |||
if tpl_args.extra_item_tags then | |||
-- Format item tags | local extra_tags = m_util.cast.table(tpl_args.extra_item_tags) | ||
tpl_args.item_tags = m_util. | for _, v in ipairs(extra_tags) do | ||
tpl_args.item_tags[#tpl_args.item_tags+1] = v | |||
end | |||
end | end | ||
-- | -- Determine whether the item can have influences | ||
item_data.can_have_influences = m_util.cast.boolean(m_game.constants.item.classes[item_data.class_id].can_have_influences) | |||
-- Determine whether the item can be corrupted | |||
item_data.can_be_corrupted = m_util.cast.boolean(m_game.constants.item.classes[item_data.class_id].can_be_corrupted) | |||
-- | -- Determine whether the item can have veiled mods | ||
item_data. | item_data.can_have_veiled_mods = m_util.cast.boolean(m_game.constants.item.classes[item_data.class_id].can_have_veiled_mods) | ||
-- | -- Get tags that are appended to influenced items | ||
item_data.addon_tags = m_game.constants.item.classes[item_data.class_id].tags or {} | |||
-- Populate mods data | |||
for _, section in ipairs(item_mods.sections) do | |||
-- Default generation types | |||
if type(section.generation_types) ~= 'table' then | |||
section.generation_types = { | |||
for _, | { | ||
id = cfg.mod_generation_types.prefix, | |||
heading = i18n.item_mods.prefixes, | |||
no_results = i18n.item_mods.prefixes_no_results | |||
}, | |||
{ | |||
id = cfg.mod_generation_types.suffix, | |||
heading = i18n.item_mods.suffixes, | |||
no_results = i18n.item_mods.suffixes_no_results | |||
} | |||
} | |||
end | |||
-- | -- Show the section? Default: Show | ||
local show = section.show ~= false | |||
if type(section.show) == 'function' then | |||
show = section.show(item_data) | |||
if | |||
end | end | ||
if show then | |||
if | -- Get item tags | ||
local section_tags = type(section.tags) == 'function' and section.tags(item_data) or section.tags or tpl_args.item_tags | |||
if type(section_tags) ~= 'table' or #section_tags == 0 then | |||
error('No tags.') | |||
end | end | ||
-- Build mods data for each generation type | |||
section.mods_data = {} | |||
for _, gen_type in ipairs(section.generation_types) do | |||
section.mods_data[gen_type.id] = {} | |||
-- Query mods | |||
local where = { | |||
string.format('mods.domain = %s', section.domain or item_data.domain), | |||
string.format('mods.generation_type = %s', gen_type.id), | |||
'mods.stat_text IS NOT NULL', | |||
string.format('mod_spawn_weights.tag IN ("%s")', table.concat(section_tags, '","')), | |||
} | |||
if section.where then | |||
where[#where+1] = section.where(item_data) | |||
end | end | ||
local results = m_cargo.query( | |||
{ | |||
'mods', | |||
'mod_stats', | |||
'mod_spawn_weights', | |||
}, | |||
{ | |||
'mods._pageID', | |||
'mods._pageName', | |||
'mods.name', | |||
'mods.id', | |||
'mods.required_level', | |||
'mods.generation_type', | |||
'mods.domain', | |||
'mods.mod_groups', | |||
'mods.mod_type', | |||
'mods.stat_text', | |||
'mods.stat_text_raw', | |||
'mods.tags', | |||
'mod_stats.id', | |||
'mod_spawn_weights.tag', | |||
'mod_spawn_weights.value', | |||
'mod_spawn_weights.ordinal', | |||
}, | |||
{ | { | ||
join = [[ | join = [[ | ||
Line 626: | Line 324: | ||
mods._pageID=mod_stats._pageID | mods._pageID=mod_stats._pageID | ||
]], | ]], | ||
where = | where = table.concat(where, ' AND '), | ||
groupBy = | groupBy = 'mods._pageID', | ||
having = 'mod_spawn_weights.value > 0', | |||
orderBy = [[ | orderBy = [[ | ||
mods. | mods.mod_groups ASC, | ||
mods.mod_type ASC, | |||
mods.mod_type, | mods.required_level ASC, | ||
mods.required_level | mod_spawn_weights.ordinal ASC | ||
mod_spawn_weights.ordinal | |||
]], | ]], | ||
} | } | ||
) | ) | ||
-- Group results | |||
if #results > 0 then | |||
for _, | for _, row in ipairs(results) do | ||
row['mods.mod_groups'] = m_util.cast.table(row['mods.mod_groups']) | |||
row['mods.tags'] = m_util.cast.table(row['mods.tags']) | |||
if #row['mods.mod_groups'] > 0 then | |||
for _, group in ipairs(row['mods.mod_groups']) do | |||
section.mods_data[gen_type.id][group] = section.mods_data[gen_type.id][group] or {} | |||
section.mods_data[gen_type.id][group][row['mods.mod_type']] = section.mods_data[gen_type.id][group][row['mods.mod_type']] or {} | |||
table.insert(section.mods_data[gen_type.id][group][row['mods.mod_type']], row) | |||
end | end | ||
end | end | ||
end | |||
end | end | ||
end | |||
if tpl_args.debug then | |||
mw.logObject(section.mods_data) | |||
end | end | ||
end | end | ||
end | end | ||
-- Build html output | |||
-- | local html = mw.html.create() | ||
for _, section in ipairs(item_mods.sections) do | |||
local section_wrapper | |||
local empty = true -- Section is empty | |||
if section.mods_data then | |||
section_wrapper = mw.html.create('div') | |||
:addClass('mod-compat__section') | |||
:tag('h3') | |||
:addClass('mod-compat__section-heading') | |||
:wikitext(section.heading) | |||
:done() | |||
for _, gen_type in ipairs(section.generation_types) do | |||
local gentype_wrapper = section_wrapper | |||
:tag('div') | |||
:addClass('mod-compat__gentype') | |||
local gentype_header = gentype_wrapper | |||
:tag('div') | |||
:addClass('mod-compat__gentype-header') | |||
:tag('span') | |||
:addClass('mod-compat__gentype-heading') | |||
:wikitext(gen_type.heading or i18n.item_mods.modifiers) | |||
:done() | |||
if type(section.mods_data[gen_type.id]) == 'table' and m_util.table.length(section.mods_data[gen_type.id]) > 0 then | |||
empty = false | |||
gentype_header | |||
:tag('span') | |||
:addClass('accordion__controls mw-editsection-like') | |||
for gkey, gval in pairs(section.mods_data[gen_type.id]) do | |||
local group_wrapper = gentype_wrapper | |||
:tag('div') | |||
:addClass('mod-compat__group') | |||
:tag('div') | |||
:addClass('mod-compat__group-label') | |||
:wikitext( string.format('%s %s', i18n.item_mods.group, gkey) ) | |||
:done() | |||
local mod_type_list = group_wrapper | |||
:tag('dl') | |||
:addClass('mod-compat__type-list accordion') | |||
for tkey, tval in pairs(gval) do | |||
local summary_text = tval[1]['mods.stat_text_raw'] | |||
if m_util.table.length(tval) > 1 then | |||
summary_text = h.genericize_stat_text(summary_text) | |||
end | |||
local mod_type_heading = mod_type_list | |||
:tag('dt') | |||
:addClass('mod-compat__type-summary accordion__toggle') | |||
:wikitext( m_util.html.poe_color('mod', summary_text) ) | |||
local mod_type_body = mod_type_list | |||
:tag('dd') | |||
:addClass('mod-compat__type-details accordion__panel') | |||
local mod_table = mod_type_body | |||
:tag('table') | |||
:addClass('wikitable modifier-table') | |||
:tag('tr') | |||
:tag('th') | |||
:wikitext(i18n.item_mods.modifier) | |||
:done() | |||
:tag('th') | |||
:wikitext(i18n.item_mods.required_level) | |||
:done() | |||
:tag('th') | |||
:wikitext(i18n.item_mods.stats) | |||
:done() | |||
:tag('th') | |||
:wikitext(i18n.item_mods.tags) | |||
:done() | |||
:done() | |||
for _, mod in ipairs(tval) do | |||
local name = mod['mods.name'] or mod['mods.mod_type'] or mod['mods.id'] | |||
local tag_list = mw.html.create('ul') | |||
:addClass('modifier-table__tag-list') | |||
for _, tag in ipairs(mod['mods.tags']) do | |||
tag_list | |||
:tag('li') | |||
:addClass('modifier-table__tag') | |||
:wikitext(tag) | |||
end | |||
mod_table | |||
:tag('tr') | |||
:tag('td') | |||
:wikitext( m_util.html.wikilink(mod['mods._pageName'], name) ) | |||
:done() | |||
:tag('td') | |||
:wikitext(mod['mods.required_level']) | |||
:done() | |||
:tag('td') | |||
:wikitext( m_util.html.poe_color('mod', mod['mods.stat_text_raw']) ) | |||
:done() | |||
:tag('td') | |||
:node(tag_list) | |||
:done() | |||
end | |||
end | |||
end | end | ||
else | else | ||
gentype_wrapper | |||
:wikitext(gen_type.no_results) | |||
end | end | ||
end | end | ||
end | end | ||
if not empty then | |||
html:node(section_wrapper) | |||
end | |||
end | end | ||
return tostring(html) | |||
return | |||
end | end | ||
Latest revision as of 19:01, 15 December 2022
The above documentation is transcluded from Module:Modifier compatibility/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:Modifier compatibility
--
-- This module implements Template:Item modifier compatibility
-------------------------------------------------------------------------------
require('Module:No globals')
local m_util = require('Module:Util')
local m_item_util = require('Module:Item util')
local m_cargo = require('Module:Cargo')
-- Should we use the sandbox version of our submodules?
local use_sandbox = m_util.misc.maybe_sandbox('Modifier compatibility')
local m_game = mw.loadData('Module:Game')
-- 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:Modifier compatibility/config/sandbox') or mw.loadData('Module:Modifier compatibility/config')
local i18n = cfg.i18n
-- ----------------------------------------------------------------------------
-- Helper functions
-- ----------------------------------------------------------------------------
local h = {}
function h.genericize_stat_text(str)
--[[
This function replaces individual numbers and ranges of numbers with a number sign (#).
]]
str = string.gsub(str, '%(%d+%.?%d*%-%d+%.?%d*%)', '#')
str = string.gsub(str, '%d+%.?%d*', '#')
return str
end
-- ----------------------------------------------------------------------------
-- Data and configuration for item mods
-- ----------------------------------------------------------------------------
local item_mods = {}
item_mods.sections = {
{
heading = i18n.item_mods.standard_mods,
where = function (item_data)
return [[
mods.id NOT LIKE "%%Royale%%"
]]
end,
},
{
show = function (item_data)
return item_data.can_have_influences
end,
tags = function (item_data)
return {item_data.addon_tags.shaper}
end,
heading = i18n.item_mods.shaper_mods,
},
{
show = function (item_data)
return item_data.can_have_influences
end,
tags = function (item_data)
return {item_data.addon_tags.elder}
end,
heading = i18n.item_mods.elder_mods,
},
{
show = function (item_data)
return item_data.can_have_influences
end,
tags = function (item_data)
return {item_data.addon_tags.crusader}
end,
heading = i18n.item_mods.crusader_mods,
},
{
show = function (item_data)
return item_data.can_have_influences
end,
tags = function (item_data)
return {item_data.addon_tags.eyrie}
end,
heading = i18n.item_mods.redeemer_mods,
},
{
show = function (item_data)
return item_data.can_have_influences
end,
tags = function (item_data)
return {item_data.addon_tags.basilisk}
end,
heading = i18n.item_mods.hunter_mods,
},
{
show = function (item_data)
return item_data.can_have_influences
end,
tags = function (item_data)
return {item_data.addon_tags.adjudicator}
end,
heading = i18n.item_mods.warlord_mods,
},
{
show = function (item_data)
return item_data.can_have_veiled_mods
end,
heading = i18n.item_mods.veiled_mods,
domain = cfg.mod_domains.unveiled,
},
{
show = function (item_data)
return item_data.can_be_corrupted
end,
heading = i18n.item_mods.corruption_implicit_mods,
generation_types = {
{
id = cfg.mod_generation_types.corrupted,
},
},
},
{
show = function (item_data)
return cfg.eldritch_implicit_item_classes[item_data.class_id] or false
end,
heading = i18n.item_mods.eldritch_implicit_mods,
generation_types = {
{
id = cfg.mod_generation_types.searing_exarch,
heading = i18n.item_mods.searing_exarch,
},
{
id = cfg.mod_generation_types.eater_of_worlds,
heading = i18n.item_mods.eater_of_worlds,
},
},
},
}
-- ----------------------------------------------------------------------------
-- Main functions
-- ----------------------------------------------------------------------------
local function _item_modifier_compatibility(tpl_args)
--[[
This function queries mods that can spawn on an item. It compares
the item tags and the spawn weight tags. If there's a match and
the spawn weight is larger than zero, then that mod is added to a
drop down list.
To Do:
* Add support to:
* Forsaken masters
* Bestiary
* 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 [Collapsible, default=Expanded]
# to Damage [Collapsible, default=Collapsed]
3 to Damage
5 to Damage
* Add a where condition that somehow filters out mods that obviously
wont match with the item. mod_spawn_weights.value>0 isn't enough due
to possible edge cases.
Examples:
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='Body armours'}
Boots
= p.drop_down_table{item='Iron Greaves', header='Boots'}
= p.drop_down_table{
item='Fishing Rod',
header='FISH PLEASE',
item_tags='fishing_rod',
extra_fields='mods.tags'
}
= p.drop_down_table{
item='Fishing Rod',
item_tags='axe, one_hand_weapon, onehand, weapon, default',
extra_item_tags='fishing_rod'
}
= p.drop_down_table{
item='Vaal Blade',
}
]]
-- Support legacy args
tpl_args.item_name = tpl_args.item_name or tpl_args.item
-- Query item
local item_data = m_item_util.query_item(tpl_args, {
fields = {
'items.name=name',
'items.tags=tags',
'items.inventory_icon=inventory_icon',
'items.html=html',
}
})
if item_data.error then
if not m_util.cast.boolean(tpl_args.nocat) then
return item_data.error:get_html() .. item_data.error:get_category()
end
return item_data.error:get_html()
end
-- Get the domain, if it's not defined in the table assume it's
-- in the item domain.
item_data.domain = tonumber(tpl_args.domain) or cfg.mod_domains_by_item_class[item_data.class_id] or cfg.mod_domains.item
-- Format item tags
tpl_args.item_tags = m_util.cast.table(tpl_args.item_tags or item_data.tags)
if tpl_args.extra_item_tags then
local extra_tags = m_util.cast.table(tpl_args.extra_item_tags)
for _, v in ipairs(extra_tags) do
tpl_args.item_tags[#tpl_args.item_tags+1] = v
end
end
-- Determine whether the item can have influences
item_data.can_have_influences = m_util.cast.boolean(m_game.constants.item.classes[item_data.class_id].can_have_influences)
-- Determine whether the item can be corrupted
item_data.can_be_corrupted = m_util.cast.boolean(m_game.constants.item.classes[item_data.class_id].can_be_corrupted)
-- Determine whether the item can have veiled mods
item_data.can_have_veiled_mods = m_util.cast.boolean(m_game.constants.item.classes[item_data.class_id].can_have_veiled_mods)
-- Get tags that are appended to influenced items
item_data.addon_tags = m_game.constants.item.classes[item_data.class_id].tags or {}
-- Populate mods data
for _, section in ipairs(item_mods.sections) do
-- Default generation types
if type(section.generation_types) ~= 'table' then
section.generation_types = {
{
id = cfg.mod_generation_types.prefix,
heading = i18n.item_mods.prefixes,
no_results = i18n.item_mods.prefixes_no_results
},
{
id = cfg.mod_generation_types.suffix,
heading = i18n.item_mods.suffixes,
no_results = i18n.item_mods.suffixes_no_results
}
}
end
-- Show the section? Default: Show
local show = section.show ~= false
if type(section.show) == 'function' then
show = section.show(item_data)
end
if show then
-- Get item tags
local section_tags = type(section.tags) == 'function' and section.tags(item_data) or section.tags or tpl_args.item_tags
if type(section_tags) ~= 'table' or #section_tags == 0 then
error('No tags.')
end
-- Build mods data for each generation type
section.mods_data = {}
for _, gen_type in ipairs(section.generation_types) do
section.mods_data[gen_type.id] = {}
-- Query mods
local where = {
string.format('mods.domain = %s', section.domain or item_data.domain),
string.format('mods.generation_type = %s', gen_type.id),
'mods.stat_text IS NOT NULL',
string.format('mod_spawn_weights.tag IN ("%s")', table.concat(section_tags, '","')),
}
if section.where then
where[#where+1] = section.where(item_data)
end
local results = m_cargo.query(
{
'mods',
'mod_stats',
'mod_spawn_weights',
},
{
'mods._pageID',
'mods._pageName',
'mods.name',
'mods.id',
'mods.required_level',
'mods.generation_type',
'mods.domain',
'mods.mod_groups',
'mods.mod_type',
'mods.stat_text',
'mods.stat_text_raw',
'mods.tags',
'mod_stats.id',
'mod_spawn_weights.tag',
'mod_spawn_weights.value',
'mod_spawn_weights.ordinal',
},
{
join = [[
mods._pageID=mod_spawn_weights._pageID,
mods._pageID=mod_stats._pageID
]],
where = table.concat(where, ' AND '),
groupBy = 'mods._pageID',
having = 'mod_spawn_weights.value > 0',
orderBy = [[
mods.mod_groups ASC,
mods.mod_type ASC,
mods.required_level ASC,
mod_spawn_weights.ordinal ASC
]],
}
)
-- Group results
if #results > 0 then
for _, row in ipairs(results) do
row['mods.mod_groups'] = m_util.cast.table(row['mods.mod_groups'])
row['mods.tags'] = m_util.cast.table(row['mods.tags'])
if #row['mods.mod_groups'] > 0 then
for _, group in ipairs(row['mods.mod_groups']) do
section.mods_data[gen_type.id][group] = section.mods_data[gen_type.id][group] or {}
section.mods_data[gen_type.id][group][row['mods.mod_type']] = section.mods_data[gen_type.id][group][row['mods.mod_type']] or {}
table.insert(section.mods_data[gen_type.id][group][row['mods.mod_type']], row)
end
end
end
end
end
if tpl_args.debug then
mw.logObject(section.mods_data)
end
end
end
-- Build html output
local html = mw.html.create()
for _, section in ipairs(item_mods.sections) do
local section_wrapper
local empty = true -- Section is empty
if section.mods_data then
section_wrapper = mw.html.create('div')
:addClass('mod-compat__section')
:tag('h3')
:addClass('mod-compat__section-heading')
:wikitext(section.heading)
:done()
for _, gen_type in ipairs(section.generation_types) do
local gentype_wrapper = section_wrapper
:tag('div')
:addClass('mod-compat__gentype')
local gentype_header = gentype_wrapper
:tag('div')
:addClass('mod-compat__gentype-header')
:tag('span')
:addClass('mod-compat__gentype-heading')
:wikitext(gen_type.heading or i18n.item_mods.modifiers)
:done()
if type(section.mods_data[gen_type.id]) == 'table' and m_util.table.length(section.mods_data[gen_type.id]) > 0 then
empty = false
gentype_header
:tag('span')
:addClass('accordion__controls mw-editsection-like')
for gkey, gval in pairs(section.mods_data[gen_type.id]) do
local group_wrapper = gentype_wrapper
:tag('div')
:addClass('mod-compat__group')
:tag('div')
:addClass('mod-compat__group-label')
:wikitext( string.format('%s %s', i18n.item_mods.group, gkey) )
:done()
local mod_type_list = group_wrapper
:tag('dl')
:addClass('mod-compat__type-list accordion')
for tkey, tval in pairs(gval) do
local summary_text = tval[1]['mods.stat_text_raw']
if m_util.table.length(tval) > 1 then
summary_text = h.genericize_stat_text(summary_text)
end
local mod_type_heading = mod_type_list
:tag('dt')
:addClass('mod-compat__type-summary accordion__toggle')
:wikitext( m_util.html.poe_color('mod', summary_text) )
local mod_type_body = mod_type_list
:tag('dd')
:addClass('mod-compat__type-details accordion__panel')
local mod_table = mod_type_body
:tag('table')
:addClass('wikitable modifier-table')
:tag('tr')
:tag('th')
:wikitext(i18n.item_mods.modifier)
:done()
:tag('th')
:wikitext(i18n.item_mods.required_level)
:done()
:tag('th')
:wikitext(i18n.item_mods.stats)
:done()
:tag('th')
:wikitext(i18n.item_mods.tags)
:done()
:done()
for _, mod in ipairs(tval) do
local name = mod['mods.name'] or mod['mods.mod_type'] or mod['mods.id']
local tag_list = mw.html.create('ul')
:addClass('modifier-table__tag-list')
for _, tag in ipairs(mod['mods.tags']) do
tag_list
:tag('li')
:addClass('modifier-table__tag')
:wikitext(tag)
end
mod_table
:tag('tr')
:tag('td')
:wikitext( m_util.html.wikilink(mod['mods._pageName'], name) )
:done()
:tag('td')
:wikitext(mod['mods.required_level'])
:done()
:tag('td')
:wikitext( m_util.html.poe_color('mod', mod['mods.stat_text_raw']) )
:done()
:tag('td')
:node(tag_list)
:done()
end
end
end
else
gentype_wrapper
:wikitext(gen_type.no_results)
end
end
end
if not empty then
html:node(section_wrapper)
end
end
return tostring(html)
end
-- ----------------------------------------------------------------------------
-- Exported functions
-- ----------------------------------------------------------------------------
local p = {}
--
-- Template:Item modifier compatibility
--
p.item_modifier_compatibility = m_util.misc.invoker_factory(_item_modifier_compatibility, {
wrappers = cfg.wrappers.item_mods,
})
return p