Module:Infobox item: Difference between revisions

Jump to navigation Jump to search
m Monster Domosed moved page Module:Infobox Item to Module:Infobox item: Misspelled title
Line 4: Line 4:
local data = mw.loadJsonData("Data:ItemCards.json")
local data = mw.loadJsonData("Data:ItemCards.json")
local stat_links = mw.loadJsonData("Data:StatLinks.json")
local stat_links = mw.loadJsonData("Data:StatLinks.json")
local ATTR_TYPE_ICON_MAP = require("Module:Icon/attr")


-- Local references for hot-path globals
-- Local references for hot-path globals
Line 18: Line 19:
local STATUS_FMT = "[[{{#invoke:Lang|get_string|Citadel_%s}}]]"
local STATUS_FMT = "[[{{#invoke:Lang|get_string|Citadel_%s}}]]"
     .. " [[{{#invoke:Lang|get_string|Citadel_StatusEffect}}]]"
     .. " [[{{#invoke:Lang|get_string|Citadel_StatusEffect}}]]"
-- Spirit damage constants
local SPIRIT_ICON = "[[File:Spirit_damage.png|12px]]"
local SPIRIT_COLOR = "#bc8ee8"
local SPIRIT_LINK = "Spirit Damage"


-- Label key remapping table (replaces if/elseif chain)
-- Label key remapping table (replaces if/elseif chain)
Line 182: Line 178:
end
end


local function append_label(val_str, prop_key, label, label_color, link_override)
local function append_label(val_str, prop_key, label, attr_link, link_override, is_main)
     if label == "" then return val_str end
     if label == "" then return val_str end
     local display_label
 
     local link_page = link_override or stat_links[prop_key]
     -- Resolve link priority: Override > Attribute Map Link > JSON Stat Link
     if link_page then
     local link_target = link_override
         if link_page == label then
    if not link_target or link_target == "" then
        link_target = attr_link
    end
    if not link_target or link_target == "" then
        link_target = stat_links[prop_key]
     end
 
    -- Construct label with link if valid
    local display_label = label
    if link_target and link_target ~= "" then
         if link_target == label then
             display_label = "[[" .. label .. "]]"
             display_label = "[[" .. label .. "]]"
         else
         else
             display_label = "[[" .. link_page .. "|" .. label .. "]]"
             display_label = "[[" .. link_target .. "|" .. label .. "]]"
         end
         end
    end
    -- Place label on a new line only for Main stats
    if is_main then
        return val_str .. "<br>" .. display_label
     else
     else
         display_label = label
         return val_str .. " " .. display_label
     end
     end
    if label_color then
        display_label = '<span style="color:' .. label_color .. '">'
            .. display_label .. '</span>'
    end
    return val_str .. " " .. display_label
end
end


Line 210: Line 216:
     if not conditional_label then
     if not conditional_label then
         conditional_label = format(
         conditional_label = format(
             ' <span style="color:#C0C0C0">(%s)</span>',
             '<span style="color:#C0C0C0">(%s)</span>',
             lang.get_string("Citadel_Shop_ConditionalAttribute")
             lang.get_string("Citadel_Shop_ConditionalAttribute")
         )
         )
     end
     end
     return val_str .. conditional_label
    -- Place conditional text on a new line
     return val_str .. "<br>" .. conditional_label
end
end


Line 224: Line 231:


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Spirit damage detection helper
-- Attribute Icon/Style detection helper
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------


local function is_spirit_damage(prop_key, css_type)
local function resolve_attr_style(css_type)
     return prop_key == "Damage" and css_type == "tech_damage"
     if not css_type then return nil end
    local attr = ATTR_TYPE_ICON_MAP[css_type]
    if not attr then return nil end
 
    local color = attr.color or "Grey" -- Fallback color
    local img = attr.img or "GenericProperty.png"
    local link = attr.link
    local size = attr.size -- Optional
 
    -- Construct icon using the defined color template: {{Icon/Color|img|size|link=link}}
    local icon_str
    if size and size ~= "" then
        icon_str = format("{{Icon/%s|[[File:%s|%spx]]|link=%s}}", color, img, size, link or "")
    else
        icon_str = format("{{Icon/%s|[[File:%s|%spx]]|link=%s}}", color, img, 20, link or "")
    end
 
    return {
        icon = icon_str,
        link = link
    }
end
end


Line 236: Line 263:


local function format_value(prop_key, value, css_type, loc_override,
local function format_value(prop_key, value, css_type, loc_override,
                             skip_label, allow_conditional, usage_flags, scale_info)
                             skip_label, allow_conditional, usage_flags, scale_info,
                            disable_attr, is_main)
     local numeric_val = extract_numeric(value)
     local numeric_val = extract_numeric(value)
     if not numeric_val then return nil end
     if not numeric_val then return nil end
Line 267: Line 295:
     end
     end


     -- Spirit damage: prepend icon before the value
     -- Attribute styling (Icon via template) based on css_type
     local spirit = is_spirit_damage(prop_key, css_type)
     local attr_style
     if spirit then
    if not disable_attr then
         val_str = SPIRIT_ICON .. " " .. val_str
        attr_style = resolve_attr_style(css_type)
    end
   
     if attr_style and attr_style.icon then
         val_str = attr_style.icon .. " " .. val_str
     end
     end


     val_str = append_label(val_str, label_key, label,
     val_str = append_label(val_str, label_key, label,
         spirit and SPIRIT_COLOR or nil,
         attr_style and attr_style.link or nil,
         spirit and SPIRIT_LINK or nil)
         nil, is_main) -- link_override not used here in base calls
 
     return append_conditional(val_str, allow_conditional, usage_flags)
     return append_conditional(val_str, allow_conditional, usage_flags)
end
end
Line 285: Line 318:
local function format_value_enhanced(item_name, prop_key, value, css_type,
local function format_value_enhanced(item_name, prop_key, value, css_type,
                                     loc_override, skip_label,
                                     loc_override, skip_label,
                                     allow_conditional, usage_flags)
                                     allow_conditional, usage_flags,
                                    disable_attr, is_main)
     local numeric_val = extract_numeric(value)
     local numeric_val = extract_numeric(value)
     if not numeric_val then return nil end
     if not numeric_val then return nil end
Line 327: Line 361:
     end
     end


     -- Spirit damage: prepend icon before the value
     -- Attribute styling (Icon via template) based on css_type
     local spirit = is_spirit_damage(prop_key, css_type)
     local attr_style
     if spirit then
    if not disable_attr then
         val_str = SPIRIT_ICON .. " " .. val_str
        attr_style = resolve_attr_style(css_type)
    end
 
     if attr_style and attr_style.icon then
         val_str = attr_style.icon .. " " .. val_str
     end
     end


     val_str = append_label(val_str, label_key, label,
     val_str = append_label(val_str, label_key, label,
         spirit and SPIRIT_COLOR or nil,
         attr_style and attr_style.link or nil,
         spirit and SPIRIT_LINK or nil)
         nil, is_main)
 
     return append_conditional(val_str, allow_conditional, usage_flags)
     return append_conditional(val_str, allow_conditional, usage_flags)
end
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Tooltip builder helpers
-- Tooltip builder helpers
Line 358: Line 398:
end
end


local function process_stats(lines, fmt, counter, start_index, prop_list,
local function process_stat_list(lines, param_fmt, counter, start_index,
                            item_name, seen, formatter)
                                prop_list, seen, formatter)
     local stat_index = start_index
     local stat_index = start_index
     for _, prop_obj in ipairs(prop_list or {}) do
     for _, prop_obj in ipairs(prop_list or {}) do
Line 369: Line 409:
             local val = formatter(prop_obj)
             local val = formatter(prop_obj)
             if val then
             if val then
                 insert(lines, format(fmt, counter, stat_index, val))
                 insert(lines, format(param_fmt, counter, stat_index, val))
                 stat_index = stat_index + 1
                 stat_index = stat_index + 1
                 seen[key] = true
                 seen[key] = true
Line 377: Line 417:
     return stat_index
     return stat_index
end
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Unified tooltip builder (handles both default and enhanced modes)
-- Unified tooltip builder (handles both default and enhanced modes)
Line 388: Line 429:


     local ItemData = require("Module:ItemData")
     local ItemData = require("Module:ItemData")
     local lines = { "{{Infobox item" }
     local lines = { "{{Monster_Domosed/Infobox item" }


     if enhanced then
     if enhanced then
Line 402: Line 443:


     ------------------------------------------------------------------
     ------------------------------------------------------------------
     -- Innate stats
     -- Innate stats (Main and Alt merged into item_stat sequentially)
     ------------------------------------------------------------------
     ------------------------------------------------------------------
     local innate_index = 1
     local innate_index = 1
Line 408: Line 449:
         if section.Type == "Innate" then
         if section.Type == "Innate" then
             for _, obj in ipairs(section.Main or {}) do
             for _, obj in ipairs(section.Main or {}) do
                 if is_property_in_lang_data(obj.Key, obj.LocTokenOverride) then
                 if is_property_in_lang_data(obj.Key, obj.LocTokenOverride) then
                     local val
                     local val
                     if enhanced then
                     if enhanced then
                         val = format_value_enhanced(item_name, obj.Key, obj.Value, obj.Type, obj.LocTokenOverride, nil, false, obj.UsageFlags)
                         val = format_value_enhanced(
                            item_name, obj.Key, obj.Value, obj.Type,  
                            obj.LocTokenOverride, nil, false, obj.UsageFlags,
                            true -- disable_attr
                        )
                     else
                     else
                         val = format_value(obj.Key, obj.Value, obj.Type, obj.LocTokenOverride, false, false, obj.UsageFlags, obj.Scale)
                         val = format_value(
                            obj.Key, obj.Value, obj.Type, obj.LocTokenOverride,  
                            false, false, obj.UsageFlags, obj.Scale,
                            true -- disable_attr
                        )
                     end
                     end
                     if val then
                     if val then
Line 423: Line 471:
             end
             end
             for _, obj in ipairs(section.Alt or {}) do
             for _, obj in ipairs(section.Alt or {}) do
                 if is_property_in_lang_data(obj.Key, obj.LocTokenOverride) then
                 if is_property_in_lang_data(obj.Key, obj.LocTokenOverride) then
                     local val
                     local val
Line 429: Line 476:
                         val = format_value_enhanced(
                         val = format_value_enhanced(
                             item_name, obj.Key, obj.Value, obj.Type,
                             item_name, obj.Key, obj.Value, obj.Type,
                             obj.LocTokenOverride, nil, false, obj.UsageFlags
                             obj.LocTokenOverride, nil, false, obj.UsageFlags,
                            true -- disable_attr
                         )
                         )
                     else
                     else
                         val = format_value(
                         val = format_value(
                             obj.Key, obj.Value, obj.Type, obj.LocTokenOverride,
                             obj.Key, obj.Value, obj.Type, obj.LocTokenOverride,
                             false, false, obj.UsageFlags, obj.Scale
                             false, false, obj.UsageFlags, obj.Scale,
                            true -- disable_attr
                         )
                         )
                     end
                     end
Line 456: Line 505:
                 return format(STATUS_FMT, obj.Key)
                 return format(STATUS_FMT, obj.Key)
             end
             end
             return format_value_enhanced(
             return format_value_enhanced(
                 item_name, obj.Key, obj.Value, obj.Type,
                 item_name, obj.Key, obj.Value, obj.Type,
                 obj.LocTokenOverride, false, true, obj.UsageFlags
                 obj.LocTokenOverride, false, true, obj.UsageFlags, nil, true
             )
             )
         end
         end
         alt_formatter = function(obj)
         alt_formatter = function(obj)
             return format_value_enhanced(
             return format_value_enhanced(
                 item_name, obj.Key, obj.Value, obj.Type,
                 item_name, obj.Key, obj.Value, obj.Type,
                 obj.LocTokenOverride, nil, false, obj.UsageFlags
                 obj.LocTokenOverride, nil, false, obj.UsageFlags,
                true -- disable_attr
             )
             )
         end
         end
     else
     else
main_formatter = function(obj)
        main_formatter = function(obj)
    if obj.Key:match("^StatusEffect") then
            if obj.Key:match("^StatusEffect") then
        return format(STATUS_FMT, obj.Key)
                return format(STATUS_FMT, obj.Key)
    end
            end
 
            return format_value(
    return format_value(
                obj.Key, obj.Value, obj.Type, obj.LocTokenOverride,
        obj.Key, obj.Value, obj.Type, obj.LocTokenOverride,
                false, true, obj.UsageFlags, obj.Scale, nil, true
        false, true, obj.UsageFlags, obj.Scale
            )
    )
        end
end
         alt_formatter = function(obj)
         alt_formatter = function(obj)
             return format_value(
             return format_value(
                 obj.Key, obj.Value, obj.Type, obj.LocTokenOverride,
                 obj.Key, obj.Value, obj.Type, obj.LocTokenOverride,
                 false, false, obj.UsageFlags, obj.Scale
                 false, false, obj.UsageFlags, obj.Scale,
                true -- disable_attr
             )
             )
         end
         end
Line 490: Line 537:


     ------------------------------------------------------------------
     ------------------------------------------------------------------
     -- Passive & Active stats (unified loop)
     -- Passive & Active sections — Main and Alt output separately
     ------------------------------------------------------------------
     ------------------------------------------------------------------
     local passive_counter, active_counter = 1, 1
     local passive_counter, active_counter = 1, 1
Line 500: Line 547:
             local prefix = is_active and "active" or "passive"
             local prefix = is_active and "active" or "passive"
             local counter = is_active and active_counter or passive_counter
             local counter = is_active and active_counter or passive_counter
            local stat_fmt = "| " .. prefix .. "%d_stat%d = %s"


             -- Description
             -- Description
Line 514: Line 560:
             end
             end


             -- Stats
             -- Main stats → prefix{N}_main{M}
             local seen = {}
             local main_fmt = "| " .. prefix .. "%d_main%d = %s"
             local stat_index = process_stats(
            local main_seen = {}
                 lines, stat_fmt, counter, 1,
             local main_index = 1
                 section.Main, item_name, seen, main_formatter
            for _, prop_obj in ipairs(section.Main or {}) do
            )
                local key = prop_obj.Key
            process_stats(
                 if not main_seen[key] and (
                lines, stat_fmt, counter, stat_index,
                    key:match("^StatusEffect")
                 section.Alt, item_name, seen, alt_formatter
                    or is_property_in_lang_data(key, prop_obj.LocTokenOverride)
             )
                ) then
                    local val = main_formatter(prop_obj)
                    if val then
                        insert(lines, format(main_fmt, counter, main_index, val))
                        main_index = main_index + 1
                        main_seen[key] = true
                    end
                end
            end
 
            -- Alt stats → prefix{N}_alt{M}
            local alt_fmt = "| " .. prefix .. "%d_alt%d = %s"
            local alt_seen = {}
            local alt_index = 1
            for _, prop_obj in ipairs(section.Alt or {}) do
                 local key = prop_obj.Key
                -- Skip keys already emitted as main stats
                if not main_seen[key] and not alt_seen[key] and (
                    key:match("^StatusEffect")
                    or is_property_in_lang_data(key, prop_obj.LocTokenOverride)
                ) then
                    local val = alt_formatter(prop_obj)
                    if val then
                        insert(lines, format(alt_fmt, counter, alt_index, val))
                        alt_index = alt_index + 1
                        alt_seen[key] = true
                    end
                 end
             end


             -- Cooldown / ChargeUp
             -- Cooldown / ChargeUp
Line 577: Line 651:
     return concat(lines, "\n")
     return concat(lines, "\n")
end
end
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Public interface
-- Public interface