Module:AbilityTable: Difference between revisions

Jump to navigation Jump to search
Vergir (talk | contribs)
m add more missing moveslow entries
Vergir (talk | contribs)
Add heal stat; refactor pct_stat_cells to val_stat_cells with suffix param; move % suffix out of hardcode (with help from vergir-bot LLM)
Line 7: Line 7:
     ["wpndmg"]    = { "melee", "heavy_melee", "weapon_damage_increase" },
     ["wpndmg"]    = { "melee", "heavy_melee", "weapon_damage_increase" },
     ["healreduce"] = { "HealAmpReceivePenaltyPercent", "HealAmpRegenPenaltyPercent", "DisableHealing" },
     ["healreduce"] = { "HealAmpReceivePenaltyPercent", "HealAmpRegenPenaltyPercent", "DisableHealing" },
     ["debuffresist"]     = {
     ["debuffresist"] = {
         -- Do not insert: AbilityDuration, TickRate, SlowDuration
         -- Do not insert: AbilityDuration, TickRate, SlowDuration
         -- they do more harm than good and include a lot of excessive abilities to the list
         -- they do more harm than good and include a lot of excessive abilities to the list
Line 23: Line 23:
     "MovementSpeedSlow", "MovementSlowPct", "ClubSlowPercent", "MoveSpeedPenaltyPerStack", "MovementSlow" },
     "MovementSpeedSlow", "MovementSlowPct", "ClubSlowPercent", "MoveSpeedPenaltyPerStack", "MovementSlow" },
     ["dashslow"]  = { "GroundDashReductionPercent", "MaxGroundDashReductionPercent", "MoveSpeedAndDashSlowPct", "EnemyDashSlowPercent" },
     ["dashslow"]  = { "GroundDashReductionPercent", "MaxGroundDashReductionPercent", "MoveSpeedAndDashSlowPct", "EnemyDashSlowPercent" },
    ["heal"] = {
        "HealingPerSecond", "HealAmount", "HealFixedHealth", "FlatHealthHealing",
        "MaxHealthRegen", "ExternalBonusHealthRegen", "BonusHealthRegen",
        "MissingHealthPercentHeal", "MissingHealthBurstPct", "RakeHealPerKill",
        "TetherSharedHealPct", "AbilityLifestealPercentHero", "HealthStealPctHero",
        "DamageHealMult", "HealPctVsHeroes", "HeartHeal", "InfestHeal", "DeathTaxHeal",
        "HealOnKillPct", "HealMaxHealth", "HealMaxHealthPercent",
    },
}
}


Line 245: Line 253:
     local props = stat_to_props["healreduce"]
     local props = stat_to_props["healreduce"]


    -- Find the first heal reduction value, at base or in upgrades.
    -- DisableHealing is a flag (value=100%); all other props are negative percentages.
     local first_pct, first_tier, first_is_disable = nil, nil, false
     local first_pct, first_tier, first_is_disable = nil, nil, false


Line 288: Line 294:
     end
     end


    -- Upgrade notes: percent changes after the first value.
     local upgrades = ability["Upgrades"]
     local upgrades = ability["Upgrades"]
     if type(upgrades) == "table" then
     if type(upgrades) == "table" then
Line 322: Line 327:
end
end


-- Generic renderer for a single percentage stat (move slow, dash slow).
-- Generic renderer for a numeric stat column.
-- col_name: the column header string (e.g. "Move Slow")
-- col_name: the column header string
-- fields: ordered list of property names to check (first non-zero wins for display)
-- fields:   ordered list of property names (first non-zero wins)
-- Upgrade deltas are additive; notes track totals.
-- suffix:  string appended to values in cell and notes (e.g. "%" or "")
local function pct_stat_cells(ability, col_name, fields)
-- Upgrade deltas are additive; notes track running totals.
local function val_stat_cells(ability, col_name, fields, suffix)
    suffix = suffix or ""
     local cells = {}
     local cells = {}
     local notes = {}
     local notes = {}
Line 333: Line 340:
     if not first_field then return cells end
     if not first_field then return cells end


     local cell_str = tostring(first_val) .. "%"
     local cell_str = tostring(first_val) .. suffix
     if first_tier then cell_str = cell_str .. " (T" .. first_tier .. ")" end
     if first_tier then cell_str = cell_str .. " (T" .. first_tier .. ")" end
     cells[col_name] = cell_str
     cells[col_name] = cell_str
Line 355: Line 362:
                         local total = running + delta
                         local total = running + delta
                         table.insert(notes, "T" .. i .. " upgrade increases "
                         table.insert(notes, "T" .. i .. " upgrade increases "
                             .. col_name:lower() .. " by " .. delta
                             .. col_name:lower() .. " by " .. delta .. suffix
                             .. "% (total " .. total .. "%).")
                             .. " (total " .. total .. suffix .. ").")
                         running = total
                         running = total
                     end
                     end
Line 369: Line 376:


local function moveslow_cells(ability)
local function moveslow_cells(ability)
     local cells = pct_stat_cells(ability, "Move Slow", stat_to_props["moveslow"])
     local cells = val_stat_cells(ability, "Move Slow", stat_to_props["moveslow"], "%")


    -- If the ability slows the caster during channel, note it.
     local channel_slow = num_val(ability["ChannelSlowPercent"])
     local channel_slow = num_val(ability["ChannelSlowPercent"])
     if channel_slow and channel_slow ~= 0 then
     if channel_slow and channel_slow ~= 0 then
Line 384: Line 390:
     local props = stat_to_props["dashslow"]
     local props = stat_to_props["dashslow"]


    -- If GroundDashReductionPercent is set at base AND any other dashslow prop
    -- exists anywhere (base or upgrades), the base value is a caster self-slow
    -- rather than an enemy debuff. Exclude it from the main value and note it instead.
     local caster_dash_slow = nil
     local caster_dash_slow = nil
     local base_ground = num_val(ability["GroundDashReductionPercent"])
     local base_ground = num_val(ability["GroundDashReductionPercent"])
Line 425: Line 428:
     end
     end


     local cells = pct_stat_cells(ability, "Dash Slow", props)
     local cells = val_stat_cells(ability, "Dash Slow", props, "%")


     if caster_dash_slow then
     if caster_dash_slow then
Line 433: Line 436:


     return cells
     return cells
end
local function heal_cells(ability)
    return val_stat_cells(ability, "Heal Amount", stat_to_props["heal"], "")
end
end


Line 455: Line 462:
         headers  = { "Dash Slow", "Notes" },
         headers  = { "Dash Slow", "Notes" },
         get_cells = dashslow_cells,
         get_cells = dashslow_cells,
    },
    ["heal"] = {
        headers  = { "Heal Amount", "Notes" },
        get_cells = heal_cells,
     },
     },
}
}
Line 535: Line 546:
     local stat_notes = human_notes[stat]
     local stat_notes = human_notes[stat]


    -- Build excluded-name set for this stat
     local excluded = {}
     local excluded = {}
     if exclude_list[stat] then
     if exclude_list[stat] then
Line 545: Line 555:
     local abilities = GameData.get_entities(GameData.Dataset.ABILITIES, internal_keys)
     local abilities = GameData.get_entities(GameData.Dataset.ABILITIES, internal_keys)


    -- Keep only abilities belonging to active, released heroes and not excluded
     local filtered = {}
     local filtered = {}
     for _, ability in ipairs(abilities) do
     for _, ability in ipairs(abilities) do
Line 558: Line 567:
     end
     end


    -- Sort by hero name, then ability slot number.
     table.sort(filtered, function(a, b)
     table.sort(filtered, function(a, b)
         local ia = key_lookup[a["Key"]]
         local ia = key_lookup[a["Key"]]
Line 569: Line 577:
     end)
     end)


    -- Disclaimer
     local edit_url = mw.uri.fullUrl("Module:AbilityTable", { action = "edit" })
     local edit_url = mw.uri.fullUrl("Module:AbilityTable", { action = "edit" })
     local disclaimer = frame:preprocess(
     local disclaimer = frame:preprocess(
Line 580: Line 587:


     if compact then
     if compact then
        -- Compact mode: <ul> with one <li> per hero.
        -- Each item: "{HeroIcon}: {AbilityIcon} (note), {AbilityIcon}, ..."
         local hero_order    = {}
         local hero_order    = {}
         local hero_abilities = {}
         local hero_abilities = {}
Line 613: Line 618:
     end
     end


    -- Normal mode: wikitable with one row per ability and stat-specific columns.
     local has_notes_header = false
     local has_notes_header = false
     local final_headers = {}
     local final_headers = {}