Module:AbilityTable: Difference between revisions

Jump to navigation Jump to search
Vergir (talk | contribs)
Add healreduce stat with Heal Reduction % and Duration columns and upgrade notes (with help from vergir-bot LLM)
Vergir (talk | contribs)
Refine healreduce renderer: show first heal reduction value with upgrade tier in parentheses if upgrade-only; no wiki links in notes (with help from vergir-bot LLM)
Line 153: Line 153:
                             -- Introduces heavy melee scaling (additive on top of zeroed melee)
                             -- Introduces heavy melee scaling (additive on top of zeroed melee)
                             table.insert(notes, "T" .. i .. " upgrade changes scaling to ×"
                             table.insert(notes, "T" .. i .. " upgrade changes scaling to ×"
                                 .. delta .. " of '''[[Heavy Melee]]''' damage.")
                                 .. delta .. " of Heavy Melee damage.")


                         elseif stype == "melee" and delta ~= 0 and base_melee_scale then
                         elseif stype == "melee" and delta ~= 0 and base_melee_scale then
Line 188: Line 188:
end
end


-- Returns the base heal reduction percent (always positive, e.g. 33 for -33%),
-- Returns the base duration value using priority: VenomDuration > DebuffDuration > AbilityDuration > BurnDuration.
-- or nil if the reduction only appears in upgrades.
-- Also returns true if the ability fully disables healing (DisableHealing).
local function find_base_heal_reduce(ability)
    local pct = num_val(ability["HealAmpReceivePenaltyPercent"])
        or num_val(ability["HealAmpRegenPenaltyPercent"])
    if pct and pct ~= 0 then
        return math.abs(pct), false
    end
    if ability["DisableHealing"] and ability["DisableHealing"] ~= 0 then
        return nil, true
    end
    return nil, false
end
 
-- Returns the base duration value using priority: VenomDuration > DebuffDuration > AbilityDuration.
-- Also returns the field name that was found (for upgrade scanning).
-- Also returns the field name that was found (for upgrade scanning).
local function find_base_duration(ability)
local function find_base_duration(ability)
Line 219: Line 204:
     local notes = {}
     local notes = {}


    local base_pct, is_disable = find_base_heal_reduce(ability)
     local base_dur, dur_field = find_base_duration(ability)
     local base_dur, dur_field = find_base_duration(ability)


     -- Heal Reduction % column
     -- Determine the first heal reduction value and where it comes from.
     if is_disable then
    -- Check base fields first, then scan upgrades in order.
         cells["Heal Reduction"] = "100% (suppressed)"
    local first_pct      = nil  -- absolute percent value (positive)
     elseif base_pct then
    local first_tier      = nil  -- nil = base ability, N = upgrade tier
         cells["Heal Reduction"] = tostring(base_pct) .. "%"
    local first_is_disable = false
 
    local base_receive = num_val(ability["HealAmpReceivePenaltyPercent"])
    local base_regen  = num_val(ability["HealAmpRegenPenaltyPercent"])
    local base_pct_raw = base_receive or base_regen
     if base_pct_raw and base_pct_raw ~= 0 then
         first_pct  = math.abs(base_pct_raw)
        first_tier = nil
    elseif ability["DisableHealing"] and ability["DisableHealing"] ~= 0 then
        first_is_disable = true
        first_tier = nil
    else
        -- Scan upgrades for first occurrence
        local upgrades = ability["Upgrades"]
        if type(upgrades) == "table" then
            for i, tier in ipairs(upgrades) do
                if type(tier) == "table" then
                    local up_receive = num_val(tier["HealAmpReceivePenaltyPercent"])
                    local up_regen  = num_val(tier["HealAmpRegenPenaltyPercent"])
                    local up_raw     = up_receive or up_regen
                    if up_raw and up_raw ~= 0 then
                        first_pct  = math.abs(up_raw)
                        first_tier = i
                        break
                    elseif tier["DisableHealing"] and tier["DisableHealing"] ~= 0 then
                        first_is_disable = true
                        first_tier = i
                        break
                    end
                end
            end
        end
    end
 
    -- Build Heal Reduction cell value
    if first_is_disable then
        local val = "100%"
        if first_tier then val = val .. " (T" .. first_tier .. ")" end
         cells["Heal Reduction"] = val
    elseif first_pct then
        local val = tostring(first_pct) .. "%"
        if first_tier then val = val .. " (T" .. first_tier .. ")" end
        cells["Heal Reduction"] = val
     end
     end
    -- (if neither, it's upgrade-only — cell stays nil → "—")


     -- Duration column
     -- Duration column
Line 235: Line 260:
     end
     end


     -- Scan upgrades for changes to heal reduction or duration
     -- Upgrade notes: percent changes AFTER the first value, and duration changes.
    -- We skip the tier that introduced the first value (already shown in the cell).
     local upgrades = ability["Upgrades"]
     local upgrades = ability["Upgrades"]
     if type(upgrades) == "table" then
     if type(upgrades) == "table" then
         local running_pct = base_pct  -- track cumulative percent for additive deltas
         local running_pct = first_pct  -- track cumulative for additive note text
         local running_dur = base_dur
         local running_dur = base_dur
        local first_pct_seen = (first_tier == nil)  -- if base, we've already "seen" it


         for i, tier in ipairs(upgrades) do
         for i, tier in ipairs(upgrades) do
Line 246: Line 273:


                 -- Heal reduction changes
                 -- Heal reduction changes
                 local pct_delta = num_val(tier["HealAmpReceivePenaltyPercent"])
                 local up_receive = num_val(tier["HealAmpReceivePenaltyPercent"])
                    or num_val(tier["HealAmpRegenPenaltyPercent"])
                local up_regen  = num_val(tier["HealAmpRegenPenaltyPercent"])
                 local disable  = tier["DisableHealing"]
                 local pct_delta  = up_receive or up_regen
                local is_this_first = (first_tier == i)


                 if disable and disable ~= 0 then
                 if is_this_first then
                     table.insert(tier_notes, "T" .. i .. " upgrade fully suppresses [[Healing]].")
                     -- This tier introduced the first value; already shown in cell, skip note.
                 elseif pct_delta and pct_delta ~= 0 then
                    first_pct_seen = true
                    if first_pct then running_pct = first_pct end
                 elseif first_pct_seen and pct_delta and pct_delta ~= 0 then
                    -- Subsequent percent change — note the new total
                     local delta_abs = math.abs(pct_delta)
                     local delta_abs = math.abs(pct_delta)
                     if running_pct then
                     local total = (running_pct or 0) + delta_abs
                        -- Additive change to existing base
                    table.insert(tier_notes, "T" .. i .. " upgrade increases heal reduction to " .. total .. "%.")
                        local total = running_pct + delta_abs
                    running_pct = total
                        table.insert(tier_notes, "T" .. i .. " upgrade increases heal reduction by "
                            .. delta_abs .. "% (total " .. total .. "%).")
                        running_pct = total
                    else
                        -- Introduces heal reduction for the first time
                        table.insert(tier_notes, "T" .. i .. " upgrade adds "
                            .. delta_abs .. "% [[Healing Reduction]].")
                        running_pct = delta_abs
                    end
                 end
                 end


Line 271: Line 293:
                 if dur_field then
                 if dur_field then
                     local dur_delta = num_val(tier[dur_field])
                     local dur_delta = num_val(tier[dur_field])
                     if dur_delta and dur_delta ~= 0 then
                     if dur_delta and dur_delta ~= 0 and running_dur then
                         if running_dur then
                         local total_dur = running_dur + dur_delta
                            local total_dur = running_dur + dur_delta
                        table.insert(tier_notes,
                            table.insert(tier_notes, "T" .. i .. " upgrade "
                            "T" .. i .. " upgrade "
                                .. (dur_delta > 0 and "increases" or "decreases")
                            .. (dur_delta > 0 and "increases" or "decreases")
                                .. " duration by " .. math.abs(dur_delta)
                            .. " duration by " .. math.abs(dur_delta)
                                .. "s (total " .. total_dur .. "s).")
                            .. "s (total " .. total_dur .. "s).")
                            running_dur = total_dur
                        running_dur = total_dur
                        end
                     end
                     end
                 end
                 end