Module:AbilityTable: Difference between revisions

Vergir (talk | contribs)
m add comment to reactivebarrier
Vergir (talk | contribs)
add dispelmagic stat, refactor filtering into filter_abilities with slot-4 exclusion for dispelmagic (with help from vergir-bot LLM)
Line 29: Line 29:
         -- engine-side CCs with no matching data prop
         -- engine-side CCs with no matching data prop
         "Itani Lo Sahn", "Dazzling Trick", "Ground Strike", "Hotel Guest",
         "Itani Lo Sahn", "Dazzling Trick", "Ground Strike", "Hotel Guest",
    },
    ["dispelmagic"] = {
        -- Excludes effects that prevent casting (StunDuration, SleepDuration, PetrifyDuration, HexDuration)
        -- since you cannot self-dispel while affected by those.
        -- Slot 4 (ultimate) abilities are excluded via filter_abilities.
        "SilenceDuration", "SilenceDebuff", "ImmobilizeDuration", "LiftDuration", "HoldInPlaceDuration",
        "RestrictionDuration",
        "SlowPercent", "EnemySlowPct", "MoveSlowPercent", "GroundDashReductionPercent", "SlowDuration",
        "DebuffDuration", "ExplodeDebuffDuration", "BulletDamageAmpDuration", "BulletResistReduction",
        "StealDuration", "EffectDuration", "DebuffAccuracy", "TimeSlowDuration",
        "BurnDuration", "BleedDuration", "VenomDuration",
        -- raw abilities
        "Life Drain", "Card Trick",
     },
     },
     ["heal"] = {
     ["heal"] = {
Line 121: Line 134:
local exclude_list = {
local exclude_list = {
     ["debuffresist"] = {
     ["debuffresist"] = {
         "Bookwyrm", -- has debuffduration for some reason
         "Bookwyrm", -- has DebuffDuration for some reason
         "Itani Lo Sahn", -- has debuffduration but does not get reduced
         "Itani Lo Sahn", -- has DebuffDuration but does not get reduced
         "Slam Fire", -- has debuffduration for some reason
         "Slam Fire", -- has DebuffDuration for some reason
         "Splatter", -- has SlowPercent but no duration to shave off.
         "Splatter", -- has SlowPercent but no duration to shave off.
     },
     },
Line 134: Line 147:
     },
     },
     ["heal"] = {
     ["heal"] = {
    "Riposte" -- has AbilityLifestealPercentHero, but doesn't deal damage to heal off of.
        "Riposte", -- has AbilityLifestealPercentHero, but doesn't deal damage to heal off of.
     }
     },
    ["dispelmagic"] = {
        "Bookwyrm", -- has DebuffDuration for some reason
        "Slam Fire", -- has DebuffDuration for some reason
    },
}
}


Line 190: Line 207:
     end
     end
     return nil, nil, nil
     return nil, nil, nil
end
-- ============================================================
-- Filtering
-- ============================================================
-- Filters a list of prop-matched abilities down to those that should appear
-- in the table for the given stat. Handles:
--  1. key_lookup membership (ability belongs to an active released hero)
--  2. exclude_list (manual false-positive suppressions)
--  3. stat-specific logic (e.g. dispelmagic strips slot-4 ultimates)
local function filter_abilities(stat, abilities, key_lookup)
    local excluded = {}
    if exclude_list[stat] then
        for _, name in ipairs(exclude_list[stat]) do
            excluded[name] = true
        end
    end
    local result = {}
    for _, ability in ipairs(abilities) do
        local key  = ability["Key"]
        local info = key and key_lookup[key]
        if info and not excluded[ability["Name"]] then
            local skip = false
            -- dispelmagic: skip ultimates (slot 4)
            if stat == "dispelmagic" and info.abilityNum == 4 then
                skip = true
            end
            if not skip then
                table.insert(result, ability)
            end
        end
    end
    return result
end
end


Line 592: Line 644:
     local get_cells  = spec and spec.get_cells or function() return {} end
     local get_cells  = spec and spec.get_cells or function() return {} end
     local stat_notes = human_notes[stat]
     local stat_notes = human_notes[stat]
    local excluded = {}
    if exclude_list[stat] then
        for _, name in ipairs(exclude_list[stat]) do
            excluded[name] = true
        end
    end


     local abilities = GameData.get_entities(GameData.Dataset.ABILITIES, internal_keys)
     local abilities = GameData.get_entities(GameData.Dataset.ABILITIES, internal_keys)
 
     local filtered = filter_abilities(stat, abilities, key_lookup)
     local filtered = {}
    for _, ability in ipairs(abilities) do
        local key = ability["Key"]
        if key and key_lookup[key] and not excluded[ability["Name"]] then
            table.insert(filtered, ability)
        end
    end


     if #filtered == 0 then
     if #filtered == 0 then