Module:Sandbox/LVL: Difference between revisions

LVL (talk | contribs)
No edit summary
LVL (talk | contribs)
No edit summary
Line 4: Line 4:
local data = mw.loadJsonData("Data:Monster_Domosed/ItemData.json")
local data = mw.loadJsonData("Data:Monster_Domosed/ItemData.json")


-- Helper function: get first non-nil string from variants (moved to module level)
local function first_non_nil(...)
    for i = 1, select("#", ...) do
        local v = select(i, ...)
        if v and v ~= "" then return v end
    end
    return ""
end
-- Helper: get lang string with case fallback (from Domo's version)
local function get_lang_with_fallback(base_key, suffix1, suffix2)
    return first_non_nil(
        lang.get_string(base_key .. suffix1),
        lang.get_string(base_key .. suffix2)
    )
end
-- Get component-of items sorted by tier (your fix, kept here until ready to move to Module:ItemData)
local function get_component_of_sorted(item_input)
local function get_component_of_sorted(item_input)
    -- Find the item's key
     local target_key = nil
     local target_key = nil
     if data[item_input] then
     if data[item_input] then
Line 18: Line 35:
     if not target_key then return {} end
     if not target_key then return {} end


    -- Find all items that have this item as a component
     local parents = {}
     local parents = {}
     for key, item in pairs(data) do
     for key, item in pairs(data) do
Line 31: Line 47:
     end
     end


     -- Sort by Tier instead of alphabetically
     -- Sort by Tier instead of alphabetically (your fix)
     table.sort(parents, function(a, b)
     table.sort(parents, function(a, b)
         local tier_a = tonumber(data[a] and data[a]["Tier"]) or 0
         local tier_a = tonumber(data[a] and data[a]["Tier"]) or 0
Line 60: Line 76:
end
end


-- Check if property exists in language data
-- Check if property exists in language data (refactored to loop, from Domo's version)
local function is_property_in_lang_data(prop)
local function is_property_in_lang_data(prop)
     local keys = {
     local suffixes = {"_label", "_Label", "_prefix", "_Prefix", "_postfix", "_Postfix", "_postvalue_label", "_Postvalue_Label"}
        prop .. "_label",
     for _, suffix in ipairs(suffixes) do
        prop .. "_Label",
         if lang.get_string(prop .. suffix) then
        prop .. "_prefix",
        prop .. "_Prefix",
        prop .. "_postfix",
        prop .. "_Postfix",
        prop .. "_postvalue_label",
        prop .. "_Postvalue_Label"
    }
 
     for _, key in ipairs(keys) do
         if lang.get_string(key) then
             return true
             return true
         end
         end
     end
     end
     return false
     return false
end
end
Line 105: Line 110:
     local value, css, loc_key = get_raw_value(item_name, prop)
     local value, css, loc_key = get_raw_value(item_name, prop)
     if value == nil or value == 0 or value == "" then
     if value == nil or value == 0 or value == "" then
    return nil
        return nil
     end
     end


Line 116: Line 121:
     -- Skip if property has no lang data
     -- Skip if property has no lang data
     local label_key = loc_key:gsub("^#", "")
     local label_key = loc_key:gsub("^#", "")
if not (
    if not (
    lang.get_string(label_key.."_label") or
        lang.get_string(label_key.."_label") or
    lang.get_string(label_key.."_Label") or
        lang.get_string(label_key.."_Label") or
    lang.get_string(label_key.."_prefix") or
        lang.get_string(label_key.."_prefix") or
    lang.get_string(label_key.."_Prefix") or
        lang.get_string(label_key.."_Prefix") or
    lang.get_string(label_key.."_postfix") or
        lang.get_string(label_key.."_postfix") or
    lang.get_string(label_key.."_Postfix") or
        lang.get_string(label_key.."_Postfix") or
    lang.get_string(label_key.."_postvalue_label") or
        lang.get_string(label_key.."_postvalue_label") or
    lang.get_string(label_key.."_Postvalue_Label")
        lang.get_string(label_key.."_Postvalue_Label")
) then
    ) then
    return nil
        return nil
end
    end
 
if debug == 2 then
    if debug == 2 then
    local label_val, prefix_val, postfix_val
        local label_val = lang.get_string(label_key.."_label") and label_key.."_label"
                      or lang.get_string(label_key.."_Label") and label_key.."_Label"
    -- determine which label key worked
                      or "(none)"
    if lang.get_string(label_key.."_label") then
        local prefix_val = lang.get_string(label_key.."_prefix") and label_key.."_prefix"
        label_val = label_key.."_label"
                        or lang.get_string(label_key.."_Prefix") and label_key.."_Prefix"
    elseif lang.get_string(label_key.."_Label") then
                        or "(none)"
        label_val = label_key.."_Label"
        local postfix_val = lang.get_string(label_key.."_postfix") and label_key.."_postfix"
    else
                        or lang.get_string(label_key.."_Postfix") and label_key.."_Postfix"
        label_val = "(none)"
                        or "(none)"
    end
        return string.format(
            "raw invoke key: %s | raw value: %s | label key used: %s | prefix key used: %s | postfix key used: %s",
    -- determine which prefix key worked
            loc_key, tostring(value), label_val, prefix_val, postfix_val
    if lang.get_string(label_key.."_prefix") then
        )
        prefix_val = label_key.."_prefix"
    end
    elseif lang.get_string(label_key.."_Prefix") then
        prefix_val = label_key.."_Prefix"
    else
        prefix_val = "(none)"
    end
    -- determine which postfix key worked
    if lang.get_string(label_key.."_postfix") then
        postfix_val = label_key.."_postfix"
    elseif lang.get_string(label_key.."_Postfix") then
        postfix_val = label_key.."_Postfix"
    else
        postfix_val = "(none)"
    end
    return string.format(
        "raw invoke key: %s | raw value: %s | label key used: %s | prefix key used: %s | postfix key used: %s",
        loc_key,
        tostring(value),
        label_val,
        prefix_val,
        postfix_val
    )
end


     if prop == "BuildUpPerShot" then label_key = "BuildupPerShot"
     if prop == "BuildUpPerShot" then label_key = "BuildupPerShot"
Line 173: Line 154:
     end
     end


-- Helper function: get first non-nil string from variants
    -- Get actual label, prefix, postfix with fallbacks (using helper from Domo's version)
local function first_non_nil(...)
    local label = skip_label and "" or get_lang_with_fallback(label_key, "_label", "_Label")
     for i = 1, select("#", ...) do
     local prefix = get_lang_with_fallback(label_key, "_prefix", "_Prefix")
        local v = select(i, ...)
    local postfix = get_lang_with_fallback(label_key, "_postfix", "_Postfix")
        if v and v ~= "" then return v end
    end
    return ""
end


-- Get actual label, prefix, postfix with fallbacks
local label = skip_label and "" or first_non_nil(
    lang.get_string(label_key.."_label"),
    lang.get_string(label_key.."_Label")
)
local prefix = first_non_nil(
    lang.get_string(label_key.."_prefix"),
    lang.get_string(label_key.."_Prefix")
)
local postfix = first_non_nil(
    lang.get_string(label_key.."_postfix"),
    lang.get_string(label_key.."_Postfix")
)
   
     if prefix == "" and postfix == "" and label == "" then
     if prefix == "" and postfix == "" and label == "" then
    return nil
        return nil
end
    end


     local val_str = tostring(value)
     local val_str = tostring(value)
Line 217: Line 178:
         end
         end
     end
     end
   
 
     ------------------------------------------------------------------
     ------------------------------------------------------------------
     -- CSS-specific formatting
     -- CSS-specific formatting (after prefix to avoid double +)
     ------------------------------------------------------------------
     ------------------------------------------------------------------
     if css == "move_speed" or css == "sprint_speed" then
     if css == "move_speed" or css == "sprint_speed" then
Line 234: Line 195:
     -- Append postfix
     -- Append postfix
     ------------------------------------------------------------------
     ------------------------------------------------------------------
-- Append postfix
    if prop ~= "BuildUpPerShot" and postfix ~= "" and not val_str:find(postfix, 1, true) then
if prop ~= "BuildUpPerShot" and postfix ~= "" and not val_str:find(postfix, 1, true) then
        if postfix == "HP/s" then
    if postfix == "HP/s" then
            val_str = val_str .. " " .. postfix
        val_str = val_str .. " " .. postfix
        else
    else
            val_str = val_str .. postfix
        val_str = val_str .. postfix
        end
    end
    end
end


     ------------------------------------------------------------------
     ------------------------------------------------------------------
Line 262: Line 222:


     ------------------------------------------------------------------
     ------------------------------------------------------------------
     -- Append (Conditional) ONLY if allowed
     -- Append (Conditional) ONLY if allowed (your fix: only for ImportantProperties)
     ------------------------------------------------------------------
     ------------------------------------------------------------------
if allow_conditional
    if allow_conditional
    and type(raw_prop) == "table"
        and type(raw_prop) == "table"
    and (raw_prop.UsageFlags == "ConditionallyApplied" or raw_prop.UsageFlags == "ConditionallyEnemyApplied")
        and (raw_prop.UsageFlags == "ConditionallyApplied" or raw_prop.UsageFlags == "ConditionallyEnemyApplied")
then
    then
    local conditional_text = lang.get_string("Citadel_Shop_ConditionalAttribute")
        local conditional_text = lang.get_string("Citadel_Shop_ConditionalAttribute")
    val_str = val_str .. string.format(' <span style="color:#C0C0C0">(%s)</span>', conditional_text)
        val_str = val_str .. string.format(' <span style="color:#C0C0C0">(%s)</span>', conditional_text)
end
    end


     return val_str
     return val_str
Line 283: Line 243:
         )
         )
     else
     else
        -- allow_conditional = true: ImportantProperties can show Conditional (your fix)
         return format_stat(item_name, prop, skip_label, debug, true)
         return format_stat(item_name, prop, skip_label, debug, true)
     end
     end
Line 328: Line 289:
                 for _, prop in ipairs(entry.Properties or {}) do
                 for _, prop in ipairs(entry.Properties or {}) do
                     if prop ~= "AbilityCooldown" and prop ~= "AbilityChargeUpTime" then
                     if prop ~= "AbilityCooldown" and prop ~= "AbilityChargeUpTime" then
                        -- allow_conditional = false for innate stats (your fix)
                         local val = format_stat(item_name, prop, false, debug, false)
                         local val = format_stat(item_name, prop, false, debug, false)
                         if val then
                         if val then
Line 348: Line 310:
                 local loc = entry.LocString and entry.LocString:gsub("#","") or nil
                 local loc = entry.LocString and entry.LocString:gsub("#","") or nil
                 if loc then
                 if loc then
                     table.insert(
                     table.insert(lines, string.format(
                        lines,
                        "| passive%d_description = {{#invoke:Lang|get_string|%s|item_name=%s}}",
                        string.format(
                        passive_counter, loc, item_name
                            "| passive%d_description = {{#invoke:Lang|get_string|%s|item_name=%s}}",
                    ))
                            passive_counter, loc, item_name
                        )
                    )
                 end
                 end


Line 360: Line 319:
                 local seen_props = {}
                 local seen_props = {}


                 -- ImportantProperties
                 -- ImportantProperties: allow_conditional = true (via format_property_for_infobox)
                 for _, prop in ipairs(entry.ImportantProperties or {}) do
                 for _, prop in ipairs(entry.ImportantProperties or {}) do
                     if prop ~= "AbilityCooldown" and prop ~= "AbilityChargeUpTime" and is_property_in_lang_data(prop) and not seen_props[prop] then
                     if prop ~= "AbilityCooldown" and prop ~= "AbilityChargeUpTime"
                      and is_property_in_lang_data(prop) and not seen_props[prop] then
                         local val = format_property_for_infobox(item_name, prop, false, debug)
                         local val = format_property_for_infobox(item_name, prop, false, debug)
                         if val then
                         if val then
Line 372: Line 332:
                 end
                 end


                 -- Properties
                 -- Properties: allow_conditional = false (your fix)
                 for _, prop in ipairs(entry.Properties or {}) do
                 for _, prop in ipairs(entry.Properties or {}) do
                     if prop ~= "AbilityCooldown" and prop ~= "AbilityChargeUpTime" and is_property_in_lang_data(prop) and not seen_props[prop] then
                     if prop ~= "AbilityCooldown" and prop ~= "AbilityChargeUpTime"
                      and is_property_in_lang_data(prop) and not seen_props[prop] then
                         local val = format_stat(item_name, prop, false, debug, false)
                         local val = format_stat(item_name, prop, false, debug, false)
                         if val then
                         if val then
Line 385: Line 346:


                 -- AbilityCooldown
                 -- AbilityCooldown
                 for _, prop in ipairs(entry.Properties or {}) do
                 for _, prop_list in ipairs({entry.Properties or {}, entry.ImportantProperties or {}}) do
                    if prop == "AbilityCooldown" then
                     for _, prop in ipairs(prop_list) do
                        local cd = format_stat(item_name, prop, true, debug)
                        if prop == "AbilityCooldown" then
                        if cd then
                            local cd = format_stat(item_name, prop, true, debug)
                            table.insert(lines, string.format("| passive%d_cooldown = %s", passive_counter, cd))
                            if cd then
                        end
                                table.insert(lines, string.format("| passive%d_cooldown = %s", passive_counter, cd))
                     end
                            end
                end
                for _, prop in ipairs(entry.ImportantProperties or {}) do
                    if prop == "AbilityCooldown" then
                        local cd = format_stat(item_name, prop, true, debug)
                        if cd then
                            table.insert(lines, string.format("| passive%d_cooldown = %s", passive_counter, cd))
                         end
                         end
                     end
                     end
Line 403: Line 358:


                 -- AbilityChargeUpTime
                 -- AbilityChargeUpTime
                 for _, prop in ipairs(entry.Properties or {}) do
                 for _, prop_list in ipairs({entry.Properties or {}, entry.ImportantProperties or {}}) do
                    if prop == "AbilityChargeUpTime" then
                     for _, prop in ipairs(prop_list) do
                        local cu = format_stat(item_name, prop, true, debug)
                        if prop == "AbilityChargeUpTime" then
                        if cu then
                            local cu = format_stat(item_name, prop, true, debug)
                            table.insert(lines, string.format("| passive%d_chargeup = %s", passive_counter, cu))
                            if cu then
                        end
                                table.insert(lines, string.format("| passive%d_chargeup = %s", passive_counter, cu))
                     end
                            end
                end
                for _, prop in ipairs(entry.ImportantProperties or {}) do
                    if prop == "AbilityChargeUpTime" then
                        local cu = format_stat(item_name, prop, true, debug)
                        if cu then
                            table.insert(lines, string.format("| passive%d_chargeup = %s", passive_counter, cu))
                         end
                         end
                     end
                     end
Line 433: Line 382:
             for _, entry in ipairs(section.Entries or {}) do
             for _, entry in ipairs(section.Entries or {}) do
                 if entry.LocString then
                 if entry.LocString then
                     table.insert(
                     table.insert(lines, string.format(
                        lines,
                        "| active%d_description = {{#invoke:Lang|get_string|%s|item_name=%s}}",
                        string.format(
                        active_index, entry.LocString:gsub("#",""), item_name
                            "| active%d_description = {{#invoke:Lang|get_string|%s|item_name=%s}}",
                    ))
                            active_index,
                            entry.LocString:gsub("#",""),
                            item_name
                        )
                    )
                 end
                 end


Line 447: Line 391:
                 local seen_props = {}
                 local seen_props = {}


                 -- ImportantProperties
                 -- ImportantProperties: allow_conditional = true (via format_property_for_infobox)
                 for _, prop in ipairs(entry.ImportantProperties or {}) do
                 for _, prop in ipairs(entry.ImportantProperties or {}) do
                     if prop ~= "AbilityCooldown" and prop ~= "AbilityChargeUpTime" and is_property_in_lang_data(prop) and not seen_props[prop] then
                     if prop ~= "AbilityCooldown" and prop ~= "AbilityChargeUpTime"
                      and is_property_in_lang_data(prop) and not seen_props[prop] then
                         local val = format_property_for_infobox(item_name, prop, false, debug)
                         local val = format_property_for_infobox(item_name, prop, false, debug)
                         if val then
                         if val then
Line 459: Line 404:
                 end
                 end


                 -- Properties
                 -- Properties: allow_conditional = false (your fix)
                 for _, prop in ipairs(entry.Properties or {}) do
                 for _, prop in ipairs(entry.Properties or {}) do
                     if prop ~= "AbilityCooldown" and prop ~= "AbilityChargeUpTime" and is_property_in_lang_data(prop) and not seen_props[prop] then
                     if prop ~= "AbilityCooldown" and prop ~= "AbilityChargeUpTime"
                      and is_property_in_lang_data(prop) and not seen_props[prop] then
                         local val = format_stat(item_name, prop, false, debug, false)
                         local val = format_stat(item_name, prop, false, debug, false)
                         if val then
                         if val then
Line 472: Line 418:


                 -- AbilityCooldown
                 -- AbilityCooldown
                 for _, prop in ipairs(entry.Properties or {}) do
                 for _, prop_list in ipairs({entry.Properties or {}, entry.ImportantProperties or {}}) do
                    if prop == "AbilityCooldown" then
                     for _, prop in ipairs(prop_list) do
                        local cd = format_stat(item_name, prop, true, debug)
                        if prop == "AbilityCooldown" then
                        if cd then
                            local cd = format_stat(item_name, prop, true, debug)
                            table.insert(lines, string.format("| active%d_cooldown = %s", active_index, cd))
                            if cd then
                        end
                                table.insert(lines, string.format("| active%d_cooldown = %s", active_index, cd))
                     end
                            end
                end
                for _, prop in ipairs(entry.ImportantProperties or {}) do
                    if prop == "AbilityCooldown" then
                        local cd = format_stat(item_name, prop, true, debug)
                        if cd then
                            table.insert(lines, string.format("| active%d_cooldown = %s", active_index, cd))
                         end
                         end
                     end
                     end
Line 490: Line 430:


                 -- AbilityChargeUpTime
                 -- AbilityChargeUpTime
                 for _, prop in ipairs(entry.Properties or {}) do
                 for _, prop_list in ipairs({entry.Properties or {}, entry.ImportantProperties or {}}) do
                    if prop == "AbilityChargeUpTime" then
                     for _, prop in ipairs(prop_list) do
                        local cu = format_stat(item_name, prop, true, debug)
                        if prop == "AbilityChargeUpTime" then
                        if cu then
                            local cu = format_stat(item_name, prop, true, debug)
                            table.insert(lines, string.format("| active%d_chargeup = %s", active_index, cu))
                            if cu then
                        end
                                table.insert(lines, string.format("| active%d_chargeup = %s", active_index, cu))
                     end
                            end
                end
                for _, prop in ipairs(entry.ImportantProperties or {}) do
                    if prop == "AbilityChargeUpTime" then
                        local cu = format_stat(item_name, prop, true, debug)
                        if cu then
                            table.insert(lines, string.format("| active%d_chargeup = %s", active_index, cu))
                         end
                         end
                     end
                     end
Line 513: Line 447:


     ----------------------------------------------------------------------
     ----------------------------------------------------------------------
     -- Global fallback for AbilityCooldown and AbilityChargeUpTime
     -- Global fallback for AbilityCooldown (your fix: attaches to active section)
     ----------------------------------------------------------------------
     ----------------------------------------------------------------------
     if not cooldown_found_in_sections and item.AbilityCooldown then
     if not cooldown_found_in_sections and item.AbilityCooldown then
    local cd = format_stat(item_name, "AbilityCooldown", true, debug)
        local cd = format_stat(item_name, "AbilityCooldown", true, debug)
    if cd then
        if cd then
        local has_active = false
            local has_active = false
        for _, section in ipairs(item.TooltipSections or {}) do
            for _, section in ipairs(item.TooltipSections or {}) do
            if section.Type == "EArea_Active" then has_active = true; break end
                if section.Type == "EArea_Active" then has_active = true; break end
        end
            end
        if has_active then
            if has_active then
            table.insert(lines, "| active1_cooldown = " .. cd)
                table.insert(lines, "| active1_cooldown = " .. cd)
        else
            else
            table.insert(lines, "| item_stat_cooldown = " .. cd)
                table.insert(lines, "| item_stat_cooldown = " .. cd)
        end
            end
    end
        end
end
    end


     if not chargeup_found_in_sections and item.AbilityChargeUpTime then
     if not chargeup_found_in_sections and item.AbilityChargeUpTime then
Line 550: Line 484:


     ----------------------------------------------------------------------
     ----------------------------------------------------------------------
     -- Is Component Of
     -- Is Component Of (your tier-sorted fix)
     ----------------------------------------------------------------------
     ----------------------------------------------------------------------
     local parents = get_component_of_sorted(item_name)
     local parents = get_component_of_sorted(item_name)
Line 561: Line 495:


     ----------------------------------------------------------------------
     ----------------------------------------------------------------------
     -- Sounds (sound1, sound2, sound3, ...)
     -- Sounds (always manual, passed as sound1= sound2= etc.)
     ----------------------------------------------------------------------
     ----------------------------------------------------------------------
     for key, value in pairs(frame.args) do
     for key, value in pairs(frame.args) do