Editing Module:AbilityTable/ComplexRenderersGive feedback
The edit can be undone.
Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.
| Latest revision | Your text | ||
| Line 47: | Line 47: | ||
end | end | ||
-- | -- Returns true if prop exists with a non-zero value anywhere in the record | ||
-- | -- excluding the Upgrades key. | ||
local function | local function is_base_property(record, prop) | ||
for k, v in pairs(record) do | |||
for | 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 is_base_property(v, prop) then return true end | |||
elseif type(v) == "string" then | |||
if v == prop then return true end | |||
end | |||
end | end | ||
return | return false | ||
end | end | ||
-- | -- Finds the base-level melee scale value by scanning for Scale.Type == "melee". | ||
local function find_base_melee_scale(ability) | |||
for _, v in pairs(ability) do | |||
if type(v) == "table" then | |||
local function | local scale = v["Scale"] | ||
if type(scale) == "table" | |||
for _, | and scale["Type"] == "melee" | ||
and type(scale["Value"]) == "number" | |||
and scale["Value"] > 0 | |||
local v | then | ||
return scale["Value"] | |||
if type( | |||
end | end | ||
end | end | ||
end | end | ||
return nil | |||
end | end | ||
-- | -- ============================================================ | ||
-- | -- Debuff short names (used by RenderDebuff) | ||
-- | -- ============================================================ | ||
local debuff_short_name = { | |||
["StunDuration"] = "stun", | |||
["SleepDuration"] = "sleep", | |||
["SilenceDuration"] = "silence", | |||
["SilenceDebuff"] = "silence", | |||
["PetrifyDuration"] = "petrify", | |||
["HexDuration"] = "hex", | |||
["ImmobilizeDuration"] = "immobilize", | |||
["LiftDuration"] = "lift", | |||
["HoldInPlaceDuration"] = "immobilize", | |||
["RestrictionDuration"] = "immobilize", | |||
["SlowPercent"] = "slow", | |||
["EnemySlowPct"] = "slow", | |||
["MoveSlowPercent"] = "slow", | |||
["GroundDashReductionPercent"] = "dash slow", | |||
["SlowDuration"] = "slow", | |||
["MaxSlowDuration"] = "slow", | |||
["BulletDamageAmpDuration"] = "bullet amp", | |||
["BulletResistReduction"] = "bullet resist reduction", | |||
["TimeSlowDuration"] = "time slow", | |||
["LateCheckoutStun"] = "stun", | |||
["BurnDuration"] = "burn", | |||
["BleedDuration"] = "bleed", | |||
["VenomDuration"] = "venom", | |||
["TossDuration"] = "knockback", | |||
} | |||
-- ============================================================ | -- ============================================================ | ||
| Line 168: | Line 171: | ||
local p = {} | local p = {} | ||
-- Renders charge count and time between charges. | -- Renders charge count and time between charges. | ||
| Line 206: | Line 176: | ||
function p.RenderCharges(ability) | function p.RenderCharges(ability) | ||
local base_charges = unwrap_value(ability["AbilityCharges"]) | local base_charges = unwrap_value(ability["AbilityCharges"]) | ||
local base_cooldown = | local base_cooldown = ability["AbilityCooldownBetweenCharge"] | ||
local has_base = base_charges ~= nil and base_charges > 0 | local has_base = base_charges ~= nil and base_charges > 0 | ||
local upgrade_info = find_in_upgrades(ability, "AbilityCharges") | local upgrade_info = find_in_upgrades(ability, "AbilityCharges") | ||
| Line 404: | Line 374: | ||
end | end | ||
-- Renders | -- Renders base damage and heavy melee scaling. | ||
-- | -- Notes when heavy melee is only available via upgrade. | ||
function p. | function p.RenderHeavyMelee(ability) | ||
-- Find base heavy_melee property | |||
local base_damage, base_scale | |||
-- Find base | |||
for k, v in pairs(ability) do | for k, v in pairs(ability) do | ||
if k ~= "Upgrades" and type(v) == "table" then | if k ~= "Upgrades" and type(v) == "table" then | ||
local scale = v["Scale"] | local scale = v["Scale"] | ||
if type(scale) == "table" | if type(scale) == "table" and scale["Type"] == "heavy_melee" | ||
and type(scale["Value"]) == "number" then | |||
and type(scale["Value"]) == "number" | base_damage = v["Value"] or 0 | ||
base_scale = scale["Value"] | base_scale = scale["Value"] | ||
break | break | ||
end | end | ||
| Line 427: | Line 393: | ||
local cells = {} | local cells = {} | ||
if base_scale then | -- Active at base | ||
cells[" | if base_scale and base_scale > 0 then | ||
cells["Base Damage"] = tostring(base_damage) | |||
cells["Heavy Melee Scaling"] = "×" .. base_scale | |||
return cells | |||
end | end | ||
-- Not at base — find in upgrades | |||
local upgrades = ability["Upgrades"] | local upgrades = ability["Upgrades"] | ||
if type(upgrades) ~= "table" then return cells end | if type(upgrades) ~= "table" then return cells end | ||
for i, tier in ipairs(upgrades) do | for i, tier in ipairs(upgrades) do | ||
if type(tier) == "table" then | if type(tier) == "table" then | ||
for k, v in pairs(tier) do | for k, v in pairs(tier) do | ||
if type(v) == "table" then | if type(v) == "table" then | ||
local scale = v["Scale"] | local scale = v["Scale"] | ||
if type(scale) == "table" | if type(scale) == "table" and scale["Type"] == "heavy_melee" | ||
and type(scale["Value"]) == "number" and scale["Value"] > 0 then | |||
and type(scale["Value"]) == "number" | cells["Base Damage"] = tostring(v["Value"] or 0) | ||
cells["Heavy Melee Scaling"] = "×" .. scale["Value"] | |||
cells["Notes"] = "Only becomes '''Heavy Melee''' on T" .. i .. " upgrade" | |||
return cells | |||
end | end | ||
end | end | ||
end | end | ||
end | end | ||
end | end | ||
| Line 486: | Line 443: | ||
end | end | ||
return render_upgradable_stat(ability, "Heal Reduction", filtered, "%") | return render_upgradable_stat(ability, "Heal Reduction", filtered, "%") | ||
end | |||
-- Shows a note if an ability acquires a debuff via upgrades. | |||
-- Shared by debuffresist and dispelmagic. | |||
function p.RenderDebuff(ability, stat) | |||
local stat_props = Lists.lists[stat] | |||
local cells = {} | |||
-- If any prop exists in base, this is a base-level debuff — no note needed. | |||
for _, prop in ipairs(stat_props) do | |||
if is_base_property(ability, prop) then | |||
return cells | |||
end | |||
end | |||
local upgrades = ability["Upgrades"] | |||
if type(upgrades) ~= "table" then return cells end | |||
local tier_debuffs = {} | |||
local seen_names = {} | |||
for i, tier in ipairs(upgrades) do | |||
if type(tier) == "table" then | |||
local names_this_tier = {} | |||
local seen_this_tier = {} | |||
for _, prop in ipairs(stat_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 | |||
local tier_indices = {} | |||
for i in pairs(tier_debuffs) do table.insert(tier_indices, i) end | |||
table.sort(tier_indices) | |||
local parts = {} | |||
for _, i in ipairs(tier_indices) do | |||
table.insert(parts, "T" .. i .. " " .. table.concat(tier_debuffs[i], " + ")) | |||
end | |||
if #parts > 0 then cells["Notes"] = table.concat(parts, ", ") end | |||
return cells | |||
end | end | ||
| Line 556: | Line 571: | ||
return cells | return cells | ||
end | end | ||
return p | return p | ||