Module:AbilityTable: Difference between revisions

Jump to navigation Jump to search
Vergir (talk | contribs)
collect_effects falls back to prop name for unmapped props instead of skipping (with help from vergir-bot LLM)
Vergir (talk | contribs)
Drop Duration column from debuff table (with help from vergir-bot LLM)
Line 29: Line 29:
-- The hero is resolved automatically from AbilityCards.json via the ability name.
-- The hero is resolved automatically from AbilityCards.json via the ability name.
-- Each entry requires:
-- Each entry requires:
--  effects = { "EffectName", ... }  (supports "Effect (TN)" for upgrade-only)
--  effects = { "EffectName", ... }  (supports "Effect (TN)" for upgrade-only)
--  duration = <number or nil>        (nil renders as "—")
local manual_entries = {
local manual_entries = {
     ["debuff"] = {
     ["debuff"] = {
         ["Combo"] = {
         ["Combo"] = {
             effects = { "Stun" },
             effects = { "Stun" },
            duration = 2.4,
         },
         },
         ["Sand Blast"] = {
         ["Sand Blast"] = {
             effects = { "Disarm" },
             effects = { "Disarm" },
            duration = 2.5,
         },
         },
         ["Spirit Lasso"] = {
         ["Spirit Lasso"] = {
             effects = { "Stun" },
             effects = { "Stun" },
            duration = 2.25,
         },
         },
     },
     },
Line 308: Line 304:
         if manual.effects and #manual.effects > 0 then
         if manual.effects and #manual.effects > 0 then
             cells["Effects"] = table.concat(manual.effects, ", ")
             cells["Effects"] = table.concat(manual.effects, ", ")
        end
        if manual.duration then
            cells["Duration"] = tostring(manual.duration)
         end
         end
         return cells
         return cells
Line 318: Line 311:
     local effects_set  = {}  -- effect name -> true, for dedup
     local effects_set  = {}  -- effect name -> true, for dedup


     -- Iterate stat_to_props["debuff"], skipping DebuffDuration (handled separately).
     -- Iterate stat_to_props["debuff"], skipping DebuffDuration (it has no named effect).
     -- Use debuff_prop_to_effect for the display name; fall back to the prop name itself.
     -- Use debuff_prop_to_effect for the display name; fall back to the prop name itself.
     local function collect_effects(obj, tier)
     local function collect_effects(obj, tier)
Line 339: Line 332:
     if type(upgrades) == "table" then
     if type(upgrades) == "table" then
         for i, tier in ipairs(upgrades) do
         for i, tier in ipairs(upgrades) do
             if type(tier) == "table" then
             if type(tier) == "table" then collect_effects(tier, i) end
                collect_effects(tier, i)
            end
         end
         end
     end
     end


    -- DebuffDuration: present anywhere → Duration shows "(See notes)"
    local has_debuff_dur = (ability["DebuffDuration"] and ability["DebuffDuration"] ~= 0)
    if not has_debuff_dur and type(upgrades) == "table" then
        for _, tier in ipairs(upgrades) do
            if type(tier) == "table" and tier["DebuffDuration"] and tier["DebuffDuration"] ~= 0 then
                has_debuff_dur = true
                break
            end
        end
    end
    -- Effects cell
     local effect_parts = {}
     local effect_parts = {}
     for _, e in ipairs(effects_seen) do
     for _, e in ipairs(effects_seen) do
Line 363: Line 342:
     if #effect_parts > 0 then
     if #effect_parts > 0 then
         cells["Effects"] = table.concat(effect_parts, ", ")
         cells["Effects"] = table.concat(effect_parts, ", ")
    end
    -- Duration cell: collect distinct non-DebuffDuration duration fields (base or upgrade).
    -- If exactly one found → use its value. If multiple, or DebuffDuration present → "(See notes)".
    local DUR_FIELDS = {
        "StunDuration", "SleepDuration", "SilenceDuration", "PetrifyDuration",
        "HexDuration", "ImmobilizeDuration", "LiftDuration", "SlowDuration",
        "HoldInPlaceDuration", "AbilityDuration", "TimeSlowDuration", "LateCheckoutStun",
    }
    local dur_found = {}
    local function collect_durations(obj)
        for _, f in ipairs(DUR_FIELDS) do
            if not dur_found[f] then
                local val = num_val(obj[f])
                if val and val > 0 then dur_found[f] = val end
            end
        end
    end
    collect_durations(ability)
    if type(upgrades) == "table" then
        for _, tier in ipairs(upgrades) do
            if type(tier) == "table" then collect_durations(tier) end
        end
    end
    local count, sole_val = 0, nil
    for _, val in pairs(dur_found) do count = count + 1; sole_val = val end
    if count == 1 then
        cells["Duration"] = tostring(sole_val)
    elseif count > 1 or has_debuff_dur then
        cells["Duration"] = "(See notes)"
     end
     end


Line 415: Line 361:
     },
     },
     ["debuff"] = {
     ["debuff"] = {
         headers  = { "Effects", "Duration" },
         headers  = { "Effects" },
         get_cells = debuff_cells,
         get_cells = debuff_cells,
     },
     },