Module:AbilityTable: Difference between revisionsGive feedback
mNo edit summary |
Drop Effects column from debuff; manual_entries becomes array of names; restore key-based lookup; name→key resolution for manuals (with help from vergir-bot LLM) |
||
| Line 25: | Line 25: | ||
} | } | ||
-- Manually specified | -- Manually specified abilities to include even if they match no props. | ||
-- Listed by ability name; the key and hero are resolved from AbilityCards.json. | |||
-- | |||
local manual_entries = { | local manual_entries = { | ||
["debuff"] = { | ["debuff"] = { | ||
"Combo", | |||
"Sand Blast", | |||
"Spirit Lasso", | |||
}, | }, | ||
} | } | ||
| Line 274: | Line 265: | ||
if #notes > 0 then cells["Notes"] = table.concat(notes, " ") end | if #notes > 0 then cells["Notes"] = table.concat(notes, " ") end | ||
return cells | return cells | ||
end | end | ||
| Line 359: | Line 282: | ||
}, | }, | ||
["debuff"] = { | ["debuff"] = { | ||
headers = { | headers = {}, | ||
get_cells = | get_cells = function() return {} end, | ||
}, | }, | ||
} | } | ||
-- ============================================================ | -- ============================================================ | ||
-- | -- Hero lookup | ||
-- | -- _key_lookup : ability key -> { heroName, abilityNum } | ||
-- | -- _name_to_key : ability name -> ability key | ||
-- Both built together from HeroData + AbilityCards. | |||
-- manual_entries resolve name -> key via _name_to_key, then use _key_lookup normally. | |||
-- ============================================================ | -- ============================================================ | ||
local | local _key_lookup = nil | ||
local _name_to_key = nil | |||
local function | local function build_lookup() | ||
if | if _key_lookup then return _key_lookup, _name_to_key end | ||
_key_lookup = {} | |||
_name_to_key = {} | |||
local hero_data = mw.loadJsonData("Data:HeroData.json") | local hero_data = mw.loadJsonData("Data:HeroData.json") | ||
| Line 395: | Line 322: | ||
for slot_str, ability in pairs(hero_entry) do | for slot_str, ability in pairs(hero_entry) do | ||
local slot_num = tonumber(slot_str) | local slot_num = tonumber(slot_str) | ||
if slot_num and type(ability) == "table" | if slot_num and type(ability) == "table" then | ||
local info = { heroName = hero_name, abilityNum = slot_num } | |||
if ability["Key"] then | |||
_key_lookup[ability["Key"]] = info | |||
end | |||
if ability["Name"] and ability["Key"] then | |||
_name_to_key[ability["Name"]] = ability["Key"] | |||
end | |||
end | end | ||
end | end | ||
| Line 406: | Line 336: | ||
end | end | ||
return | return _key_lookup, _name_to_key | ||
end | end | ||
| Line 427: | Line 357: | ||
end | end | ||
local | local key_lookup, name_to_key = build_lookup() | ||
local spec = extra_columns[stat] | local spec = extra_columns[stat] | ||
local headers = spec and spec.headers or {} | local headers = spec and spec.headers or {} | ||
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 stat_manual = manual_entries[stat] | local stat_manual = manual_entries[stat] | ||
local abilities = GameData.get_entities(GameData.Dataset.ABILITIES, internal_keys) | local abilities = GameData.get_entities(GameData.Dataset.ABILITIES, internal_keys) | ||
| Line 448: | Line 368: | ||
-- Keep only abilities belonging to active, released heroes | -- Keep only abilities belonging to active, released heroes | ||
local filtered = {} | local filtered = {} | ||
local | local filtered_keys = {} | ||
for _, ability in ipairs(abilities) do | for _, ability in ipairs(abilities) do | ||
local key = ability["Key"] | |||
if key and key_lookup[key] then | |||
table.insert(filtered, ability) | table.insert(filtered, ability) | ||
filtered_keys[key] = true | |||
end | end | ||
end | end | ||
-- Inject manual entries not already covered by prop-matching. | -- Inject manual entries not already covered by prop-matching. | ||
-- | -- Resolve ability name -> key via name_to_key, then verify key is in key_lookup. | ||
if stat_manual then | if stat_manual then | ||
for name | for _, name in ipairs(stat_manual) do | ||
if not | local key = name_to_key[name] | ||
table.insert(filtered, { Name = name }) | if key and key_lookup[key] and not filtered_keys[key] then | ||
-- Inject a minimal record; no cell renderer needs fields from it. | |||
table.insert(filtered, { Key = key, Name = name }) | |||
filtered_keys[key] = true | |||
end | end | ||
end | end | ||
| Line 472: | Line 395: | ||
-- Sort by hero name, then ability slot number. | -- Sort by hero name, then ability slot number. | ||
table.sort(filtered, function(a, b) | table.sort(filtered, function(a, b) | ||
local ia = | local ia = key_lookup[a["Key"]] | ||
local ib = | local ib = key_lookup[b["Key"]] | ||
if not ia and not ib then return (a["Name"] or "") < (b["Name"] or "") end | if not ia and not ib then return (a["Name"] or "") < (b["Name"] or "") end | ||
if not ia then return false end | if not ia then return false end | ||
| Line 519: | Line 441: | ||
for _, ability in ipairs(filtered) do | for _, ability in ipairs(filtered) do | ||
local info = | local info = key_lookup[ability["Key"]] | ||
local hero_cell | local hero_cell | ||