Module:Infobox item: Difference between revisionsGive feedback
Gammaton32 (talk | contribs) removed enhanced tabber as a temporary fix for broken formatting |
append_label: prefer per-stat StatLinks target over generic attribute-type link (fixes e.g. Debuff Resist → Ability Duration) (with help from vergir-bot LLM) |
||
| (7 intermediate revisions by 4 users not shown) | |||
| Line 15: | Line 15: | ||
local tostring = tostring | local tostring = tostring | ||
local type = type | local type = type | ||
-- Status Effect Icon Map | |||
local STATUS_EFFECT_ICON_MAP = { | |||
StatusEffectDisarmed = {img='Status_Disarm.png', link='Disarm', color='Red'}, | |||
StatusEffectEMP = {img='Status_Silence.png', link='Silence', color='Purple'}, | |||
StatusEffectInvisible= {img='Invisible.png', link='Invisible',color='Green'}, | |||
StatusEffectStun = {img='Status_Stun.png', link='Stun', color='NoColor'}, | |||
StatusEffectSlow = {img='Status_Movement_Slow.png', link='Slow', color='Purple'}, | |||
} | |||
-- Pre-computed constants | -- Pre-computed constants | ||
| Line 28: | Line 37: | ||
local LABEL_KEY_REMAP = { | local LABEL_KEY_REMAP = { | ||
DotDuration = "DOTDuration", | DotDuration = "DOTDuration", | ||
} | |||
-- Item name override mapping (old name -> new name) | |||
local ITEM_NAME_OVERRIDES = { | |||
["debuff remover"] = "Dispel Magic", | |||
["backstabber"] = "Stalker", | |||
} | } | ||
| Line 54: | Line 69: | ||
local conditional_label -- lazily initialised | local conditional_label -- lazily initialised | ||
-------------------------------------------------------------------------------- | |||
-- Item name resolution | |||
-------------------------------------------------------------------------------- | |||
local function resolve_item_name(name) | |||
-- Check if there's an override for this name (case-insensitive) | |||
local lowercase_name = name:lower() | |||
local override = ITEM_NAME_OVERRIDES[lowercase_name] | |||
if override then | |||
return override | |||
end | |||
-- If no override, try to find the item in data and return its proper Name | |||
-- First try direct key lookup | |||
if data[name] and not data[name].IsDisabled then | |||
return data[name].Name or name | |||
end | |||
-- Then try case-insensitive search by Name field | |||
local lowercase_search = name:lower() | |||
for _, v in pairs(data) do | |||
if v.Name and v.Name:lower() == lowercase_search and not v.IsDisabled then | |||
return v.Name | |||
end | |||
end | |||
-- Fallback to original name | |||
return name | |||
end | |||
-------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ||
| Line 72: | Line 117: | ||
local function get_json_item(name) | local function get_json_item(name) | ||
local direct = data[ | -- Apply name override before lookup | ||
local resolved_name = resolve_item_name(name) | |||
local direct = data[resolved_name] | |||
if direct and not direct.IsDisabled then return direct end | if direct and not direct.IsDisabled then return direct end | ||
local fallback | local fallback | ||
for _, v in pairs(data) do | for _, v in pairs(data) do | ||
if v.Name == | if v.Name == resolved_name then | ||
if not v.IsDisabled then return v end | if not v.IsDisabled then return v end | ||
fallback = fallback or v | fallback = fallback or v | ||
| Line 129: | Line 177: | ||
local function get_component_of_sorted(item_input) | local function get_component_of_sorted(item_input) | ||
-- Apply name override before processing | |||
local resolved_input = resolve_item_name(item_input) | |||
local target_key | local target_key | ||
if data[ | if data[resolved_input] then | ||
target_key = | target_key = resolved_input | ||
else | else | ||
for k, v in pairs(data) do | for k, v in pairs(data) do | ||
if v.Name == | if v.Name == resolved_input and not v.IsDisabled then | ||
target_key = k | target_key = k | ||
break | break | ||
| Line 185: | Line 236: | ||
if label == "" then return val_str end | if label == "" then return val_str end | ||
-- Resolve link priority: Override > Attribute Map | -- Resolve link priority: Override > JSON Stat Link > Attribute Map Link | ||
local link_target = link_override | local link_target = link_override | ||
if not link_target or link_target == "" then | if not link_target or link_target == "" then | ||
link_target = | link_target = stat_links[prop_key] | ||
end | end | ||
if not link_target or link_target == "" then | if not link_target or link_target == "" then | ||
link_target = | link_target = attr_link | ||
end | end | ||
| Line 255: | Line 306: | ||
icon_str = format("{{Icon/%s|[[File:%s|%spx|link=%s]]}}", color, img, 18, link or "") | icon_str = format("{{Icon/%s|[[File:%s|%spx|link=%s]]}}", color, img, 18, link or "") | ||
end | end | ||
return { | |||
icon = icon_str, | |||
link = link | |||
} | |||
end | |||
-------------------------------------------------------------------------------- | |||
-- Status Effect Icon helper | |||
-------------------------------------------------------------------------------- | |||
local function resolve_status_effect_icon(prop_key) | |||
local effect_config = STATUS_EFFECT_ICON_MAP[prop_key] | |||
if not effect_config then return nil end | |||
local color = effect_config.color or "NoColor" | |||
local img = effect_config.img or "GenericProperty.png" | |||
local link = effect_config.link | |||
-- Construct icon using the defined color template | |||
local icon_str = format( | |||
"{{Icon/%s|[[File:%s|18px|link=%s]]}}", | |||
color, img, link or "" | |||
) | |||
return { | return { | ||
| Line 380: | Line 455: | ||
return append_conditional(val_str, allow_conditional, usage_flags) | return append_conditional(val_str, allow_conditional, usage_flags) | ||
end | |||
-------------------------------------------------------------------------------- | |||
-- Status Effect formatting helper | |||
-------------------------------------------------------------------------------- | |||
local function format_status_effect(prop_key) | |||
local lang_str = format("[[{{#invoke:Lang|get_string|Citadel_%s}}]]", prop_key) | |||
.. " [[{{#invoke:Lang|get_string|Citadel_StatusEffect}}]]" | |||
-- Get icon for this status effect | |||
local icon_style = resolve_status_effect_icon(prop_key) | |||
if icon_style and icon_style.icon then | |||
return icon_style.icon .. " " .. lang_str | |||
end | |||
return lang_str | |||
end | end | ||
| Line 428: | Line 520: | ||
local item_name = frame.args[1] | local item_name = frame.args[1] | ||
if not item_name then return "Item name missing" end | if not item_name then return "Item name missing" end | ||
-- Resolve the item name (apply override if exists) | |||
local resolved_name = resolve_item_name(item_name) | |||
local item = get_json_item(item_name) | local item = get_json_item(item_name) | ||
| Line 438: | Line 533: | ||
insert(lines, "| enhanced = true") | insert(lines, "| enhanced = true") | ||
end | end | ||
insert(lines, "| item_name = " .. | -- Use resolved name for item_name parameter | ||
insert(lines, "| item_name = " .. resolved_name) | |||
if item.StreetBrawl == true then | if item.StreetBrawl == true then | ||
insert(lines, "| street_brawl = true") | insert(lines, "| street_brawl = true") | ||
end | |||
-- Pass through nocat arg to the Infobox item template if provided | |||
local nocat = frame.args.nocat | |||
if nocat and nocat ~= "" then | |||
insert(lines, "| nocat = " .. nocat) | |||
end | end | ||
| Line 457: | Line 559: | ||
if enhanced then | if enhanced then | ||
val = format_value_enhanced( | val = format_value_enhanced( | ||
resolved_name, obj.Key, obj.Value, obj.Type, | |||
obj.LocTokenOverride, nil, false, obj.UsageFlags, | obj.LocTokenOverride, nil, false, obj.UsageFlags, | ||
true -- disable_attr | true -- disable_attr | ||
| Line 479: | Line 581: | ||
if enhanced then | if enhanced then | ||
val = format_value_enhanced( | val = format_value_enhanced( | ||
resolved_name, obj.Key, obj.Value, obj.Type, | |||
obj.LocTokenOverride, nil, false, obj.UsageFlags, | obj.LocTokenOverride, nil, false, obj.UsageFlags, | ||
true -- disable_attr | true -- disable_attr | ||
| Line 500: | Line 602: | ||
------------------------------------------------------------------ | ------------------------------------------------------------------ | ||
-- Build formatters once (closures capture | -- Build formatters once (closures capture resolved_name) | ||
------------------------------------------------------------------ | ------------------------------------------------------------------ | ||
local main_formatter, alt_formatter | local main_formatter, alt_formatter | ||
| Line 507: | Line 609: | ||
main_formatter = function(obj) | main_formatter = function(obj) | ||
if obj.Key:match("^StatusEffect") then | if obj.Key:match("^StatusEffect") then | ||
return | return format_status_effect(obj.Key) | ||
end | end | ||
return format_value_enhanced( | return format_value_enhanced( | ||
resolved_name, obj.Key, obj.Value, obj.Type, | |||
obj.LocTokenOverride, false, true, obj.UsageFlags, nil, true | obj.LocTokenOverride, false, true, obj.UsageFlags, nil, true | ||
) | ) | ||
end | end | ||
alt_formatter = function(obj) | alt_formatter = function(obj) | ||
if obj.Key:match("^StatusEffect") then | |||
return format_status_effect(obj.Key) | |||
end | |||
return format_value_enhanced( | return format_value_enhanced( | ||
resolved_name, obj.Key, obj.Value, obj.Type, | |||
obj.LocTokenOverride, nil, false, obj.UsageFlags, | obj.LocTokenOverride, nil, false, obj.UsageFlags, | ||
true -- disable_attr | true -- disable_attr | ||
| Line 524: | Line 629: | ||
main_formatter = function(obj) | main_formatter = function(obj) | ||
if obj.Key:match("^StatusEffect") then | if obj.Key:match("^StatusEffect") then | ||
return | return format_status_effect(obj.Key) | ||
end | end | ||
return format_value( | return format_value( | ||
| Line 532: | Line 637: | ||
end | end | ||
alt_formatter = function(obj) | alt_formatter = function(obj) | ||
if obj.Key:match("^StatusEffect") then | |||
return format_status_effect(obj.Key) | |||
end | |||
return format_value( | return format_value( | ||
obj.Key, obj.Value, obj.Type, obj.LocTokenOverride, | obj.Key, obj.Value, obj.Type, obj.LocTokenOverride, | ||
| Line 559: | Line 667: | ||
insert(lines, format( | insert(lines, format( | ||
"| %s%d_description = {{#invoke:Lang|get_string|%s|item_name=%s}}", | "| %s%d_description = {{#invoke:Lang|get_string|%s|item_name=%s}}", | ||
prefix, counter, loc, | prefix, counter, loc, resolved_name | ||
)) | )) | ||
end | end | ||
| Line 604: | Line 712: | ||
-- Cooldown / ChargeUp | -- Cooldown / ChargeUp | ||
local cd = format_section_cooldown(section, | local cd = format_section_cooldown(section, resolved_name, enhanced) | ||
if cd.cooldown then | if cd.cooldown then | ||
insert(lines, format("| %s%d_cooldown = %s", prefix, counter, cd.cooldown)) | insert(lines, format("| %s%d_cooldown = %s", prefix, counter, cd.cooldown)) | ||
| Line 624: | Line 732: | ||
------------------------------------------------------------------ | ------------------------------------------------------------------ | ||
for i = 1, 2 do | for i = 1, 2 do | ||
local comp = ItemData.get_component_name { args = { | local comp = ItemData.get_component_name { args = { resolved_name, i } } | ||
if comp and comp ~= "" then | if comp and comp ~= "" then | ||
insert(lines, format("| component%d_name = %s", i, comp)) | insert(lines, format("| component%d_name = %s", i, comp)) | ||
| Line 676: | Line 784: | ||
function p.render(frame) | function p.render(frame) | ||
local output = concat({ | local output = concat({ | ||
"<tabber>", | |||
lang.get_string("citadel_settings_camera_preset_default") .. "=", | |||
build_tooltip_impl(frame, false), | build_tooltip_impl(frame, false), | ||
"|-|", | |||
lang.get_string("Citadel_ItemDraft_Enhanced") .. "=", | |||
build_tooltip_impl(frame, true), | |||
"</tabber>" | |||
}, "\n") | }, "\n") | ||
return mw.getCurrentFrame():preprocess(output) | return mw.getCurrentFrame():preprocess(output) | ||