Module:AbilityTable: Difference between revisions

Vergir (talk | contribs)
m more debuffresist/dispelmagic fixes in preparation of auto-notes
add debuff_cells renderer shared by debuffresist and dispelmagic, outputs upgrade-only debuff notes (with help from vergir-bot LLM)
Line 247: Line 247:
-- Human notes are appended by the framework, not here.
-- Human notes are appended by the framework, not here.
-- ============================================================
-- ============================================================
-- Short display names for debuff properties.
local debuff_short_name = {
    ["StunDuration"]              = "stun",
    ["SleepDuration"]              = "sleep",
    ["SilenceDuration"]            = "silence",
    ["SilenceDebuff"]              = "silence",
    ["PetrifyDuration"]            = "petrify",
    ["HexDuration"]                = "hex",
    ["ImmobilizeDuration"]        = "immobilize",
    ["LiftDuration"]              = "lift",
    ["HoldInPlaceDuration"]        = "immobilize",
    ["RestrictionDuration"]        = "immobilize",
    ["DebuffDuration"]            = "debuff",
    ["ExplodeDebuffDuration"]      = "debuff",
    ["SlowPercent"]                = "slow",
    ["EnemySlowPct"]              = "slow",
    ["MoveSlowPercent"]            = "slow",
    ["GroundDashReductionPercent"] = "dash slow",
    ["SlowDuration"]              = "slow",
    ["MaxSlowDuration"]            = "slow",
    ["BulletDamageAmpDuration"]    = "bullet amp",
    ["BulletResistReduction"]      = "bullet resist reduction",
    ["StealDuration"]              = "debuff",
    ["EffectDuration"]            = "debuff",
    ["DebuffAccuracy"]            = "debuff",
    ["TimeSlowDuration"]          = "time slow",
    ["LateCheckoutStun"]          = "stun",
    ["BurnDuration"]              = "burn",
    ["BleedDuration"]              = "bleed",
    ["VenomDuration"]              = "venom",
    ["TossDuration"]              = "Knockback",
}
-- Returns true if prop is found with a non-zero value anywhere in record,
-- excluding the Upgrades key. Mirrors GameData.record_matches_prop logic.
local function prop_in_base(record, prop)
    for k, v in pairs(record) do
        if k == "Upgrades" then
            -- skip
        elseif k == prop then
            if type(v) == "table" then v = v["Value"] end
            if v ~= nil and v ~= 0 and v ~= "" and v ~= "0" and v ~= "0m" then
                return true
            end
        elseif type(v) == "table" then
            if prop_in_base(v, prop) then return true end
        elseif type(v) == "string" then
            if v == prop then return true end
        end
    end
    return false
end
-- Renderer shared by debuffresist and dispelmagic.
-- Outputs a Notes cell describing which debuffs are added only by upgrades.
-- If any prop from the stat's list is found in the base ability, outputs nothing.
-- Otherwise lists per-tier debuff names: "T2 slow", "T1 disarm, T2 slow", etc.
local function debuff_cells(ability, stat)
    local props = stat_to_props[stat]
    local cells = {}
    -- Check if any prop is present in base (outside Upgrades).
    -- If so, this is a full-ability debuff — no note needed.
    for _, prop in ipairs(props) do
        if prop_in_base(ability, prop) then
            return cells
        end
    end
    -- Scan upgrades: collect props found per tier.
    local upgrades = ability["Upgrades"]
    if type(upgrades) ~= "table" then return cells end
    -- tier_debuffs[i] = list of short names found in tier i
    local tier_debuffs = {}
    local seen_names  = {}  -- deduplicate short names across tiers
    for i, tier in ipairs(upgrades) do
        if type(tier) == "table" then
            local names_this_tier = {}
            local seen_this_tier  = {}
            for _, prop in ipairs(props) do
                local v = tier[prop]
                if v ~= nil then
                    if type(v) == "table" then v = v["Value"] end
                    if v ~= nil and v ~= 0 and v ~= "" and v ~= "0" and v ~= "0m" then
                        local short = debuff_short_name[prop] or "debuff"
                        if not seen_this_tier[short] then
                            seen_this_tier[short] = true
                            if not seen_names[short] then
                                seen_names[short] = true
                                table.insert(names_this_tier, short)
                            end
                        end
                    end
                end
            end
            if #names_this_tier > 0 then
                tier_debuffs[i] = names_this_tier
            end
        end
    end
    -- Build note: "T1 slow, T2 silence + burn"
    local parts = {}
    for i = 1, #upgrades do
        if tier_debuffs[i] then
            table.insert(parts, "T" .. i .. " " .. table.concat(tier_debuffs[i], " + "))
        end
    end
    if #parts > 0 then
        cells["Notes"] = table.concat(parts, ", ")
    end
    return cells
end


local function charges_cells(ability)
local function charges_cells(ability)
Line 554: Line 671:
         headers  = { "Heal Reduction", "Notes" },
         headers  = { "Heal Reduction", "Notes" },
         get_cells = healreduce_cells,
         get_cells = healreduce_cells,
    },
    ["debuffresist"] = {
        headers  = { "Notes" },
        get_cells = function(ability) return debuff_cells(ability, "debuffresist") end,
    },
    ["dispelmagic"] = {
        headers  = { "Notes" },
        get_cells = function(ability) return debuff_cells(ability, "dispelmagic") end,
     },
     },
     ["moveslow"] = {
     ["moveslow"] = {