Module:AbilityTable: Difference between revisionsGive feedback
Register "bossdmgscale" column (Damage to Objectives) (with help from vergir-bot LLM) |
Per-prop Spirit scaling: pass card prop labels to renderers (with help from vergir-bot LLM) |
||
| Line 8: | Line 8: | ||
local p = {} | local p = {} | ||
-- get_cells(ability, cardprops) -> { [column header] = cell text, Notes = ... }; most renderers ignore cardprops | |||
local extra_columns = { | local extra_columns = { | ||
["barrier"] = { | ["barrier"] = { | ||
| Line 88: | Line 89: | ||
-- "Ability View" is a main-record + any relevant sub-ability records. | -- "Ability View" is a main-record + any relevant sub-ability records. | ||
-- Views also carry "cardprops" (see card_prop_labels), kept outside the record so membership matching never sees them. | |||
-- ============================================================ | -- ============================================================ | ||
local _views = nil -- card key -> { view = record, heroName = ..., abilityNum = ... } | -- Card prop labels: key -> { name, title, order }, read from the card in AbilityCards.json. | ||
-- Built per card, since a key like "Damage" is labelled differently on different cards. | |||
local function card_prop_labels(card) | |||
local labels, n = {}, 0 | |||
local function walk(node) | |||
if type(node) ~= "table" then return end | |||
local key, name = node["Key"], node["Name"] | |||
if type(key) == "string" and type(name) == "string" and not labels[key] then | |||
n = n + 1 | |||
local title = node["Title"] | |||
if type(title) == "string" then | |||
title = title:gsub(":%s*$", "") | |||
else | |||
title = nil | |||
end | |||
labels[key] = { name = name, title = title, order = n } | |||
end | |||
if node[1] ~= nil then | |||
for _, child in ipairs(node) do walk(child) end | |||
else | |||
-- Keyed sections (Range, Move, ...): { PropKey = { Name = ..., Value = ... } } | |||
local keyed = {} | |||
for k, v in pairs(node) do | |||
if type(k) == "string" and type(v) == "table" and v["Key"] == nil | |||
and type(v["Name"]) == "string" and not labels[k] | |||
then | |||
table.insert(keyed, k) | |||
end | |||
end | |||
table.sort(keyed) | |||
for _, k in ipairs(keyed) do | |||
n = n + 1 | |||
labels[k] = { name = node[k]["Name"], order = n } | |||
end | |||
-- Main props before Alt props, then anything else in key order. | |||
if node["Main"] ~= nil then walk(node["Main"]) end | |||
if node["Alt"] ~= nil then walk(node["Alt"]) end | |||
local rest = {} | |||
for k, v in pairs(node) do | |||
if k ~= "Main" and k ~= "Alt" and k ~= "Upgrades" and type(v) == "table" then | |||
table.insert(rest, k) | |||
end | |||
end | |||
table.sort(rest, function(a, b) return tostring(a) < tostring(b) end) | |||
for _, k in ipairs(rest) do walk(node[k]) end | |||
end | |||
end | |||
for _, section in ipairs({ "Info1", "Info2", "Info3" }) do | |||
walk(card[section]) | |||
end | |||
local rest = {} | |||
for k, v in pairs(card) do | |||
if type(v) == "table" and k ~= "Upgrades" | |||
and k ~= "Info1" and k ~= "Info2" and k ~= "Info3" | |||
then | |||
table.insert(rest, k) | |||
end | |||
end | |||
table.sort(rest, function(a, b) return tostring(a) < tostring(b) end) | |||
for _, k in ipairs(rest) do walk(card[k]) end | |||
-- Header attributes are stored on the card without a Name. | |||
local header_attrs = { | |||
{ "AbilityCastRange", "Cast Range" }, | |||
{ "Radius", "Radius" }, | |||
{ "AbilityDuration", "Duration" }, | |||
{ "AbilityChannelTime", "Channel Time" }, | |||
{ "AbilityCooldown", "Cooldown" }, | |||
{ "AbilityCharges", "Charges" }, | |||
{ "AbilityCooldownBetweenCharge", "Charge Cooldown" }, | |||
} | |||
for _, attr in ipairs(header_attrs) do | |||
if not labels[attr[1]] then | |||
n = n + 1 | |||
labels[attr[1]] = { name = attr[2], order = n } | |||
end | |||
end | |||
return labels | |||
end | |||
local _views = nil -- card key -> { view = record, heroName = ..., abilityNum = ..., cardprops = ... } | |||
local _order = nil -- array of card keys, sorted by hero then slot | local _order = nil -- array of card keys, sorted by hero then slot | ||
| Line 121: | Line 206: | ||
local key = type(ability) == "table" and ability["Key"] or nil | local key = type(ability) == "table" and ability["Key"] or nil | ||
if slot_num and key and ability_data[key] then | if slot_num and key and ability_data[key] then | ||
card_of[key] = { heroName = hero_name, abilityNum = slot_num } | card_of[key] = { heroName = hero_name, abilityNum = slot_num, card = ability } | ||
end | end | ||
end | end | ||
| Line 151: | Line 236: | ||
for k, v in pairs(ability_data[key]) do view[k] = v end | for k, v in pairs(ability_data[key]) do view[k] = v end | ||
view["_subabilities"] = subs[key] | view["_subabilities"] = subs[key] | ||
_views[key] = { view = view, heroName = info.heroName, abilityNum = info.abilityNum } | _views[key] = { | ||
view = view, | |||
heroName = info.heroName, | |||
abilityNum = info.abilityNum, | |||
cardprops = card_prop_labels(info.card), | |||
} | |||
table.insert(_order, key) | table.insert(_order, key) | ||
end | end | ||
| Line 272: | Line 362: | ||
hero_abilities[hero] = {} | hero_abilities[hero] = {} | ||
end | end | ||
table.insert(hero_abilities[hero], views[key] | table.insert(hero_abilities[hero], views[key]) | ||
end | end | ||
| Line 279: | Line 369: | ||
local hero_cell = frame:expandTemplate{ title = "HeroIcon", args = { hero } } | local hero_cell = frame:expandTemplate{ title = "HeroIcon", args = { hero } } | ||
local ability_parts = {} | local ability_parts = {} | ||
for _, | for _, entry in ipairs(hero_abilities[hero]) do | ||
local ability = entry.view | |||
local name = ability["Name"] | local name = ability["Name"] | ||
local ability_cell = frame:expandTemplate{ title = "AbilityIcon", args = { name } } | local ability_cell = frame:expandTemplate{ title = "AbilityIcon", args = { name } } | ||
local extra = get_cells(ability) | local extra = get_cells(ability, entry.cardprops) | ||
enrich_notes_compact(extra, stat_notes and stat_notes[name]) | enrich_notes_compact(extra, stat_notes and stat_notes[name]) | ||
| Line 349: | Line 440: | ||
} | } | ||
local extra = get_cells(ability) | local extra = get_cells(ability, entry.cardprops) | ||
enrich_notes_full(extra, stat_notes and stat_notes[ability["Name"]]) | enrich_notes_full(extra, stat_notes and stat_notes[ability["Name"]]) | ||