Module:AbilityTable: Difference between revisions

Remove spurious Key and abilityNum=9999 from manual entry injection; simplify sort comparator (with help from vergir-bot LLM)
Replace key-based hero lookup with name-based; drop _hero_lookup entirely (with help from vergir-bot LLM)
Line 439: Line 439:


-- ============================================================
-- ============================================================
-- Hero lookup
-- Name lookup: ability name -> { heroName, abilityNum }
--  _hero_lookup : ability key  -> { heroName, abilityNum }
-- Built from HeroData (active hero filter) + AbilityCards.
--  _name_lookup : ability name -> { heroName, abilityNum }
-- Used for both prop-matched and manual abilities.
-- Both are built together from HeroData + AbilityCards.
-- _name_lookup is used to resolve heroes for manual_entries.
-- ============================================================
-- ============================================================


local _hero_lookup = nil
local _name_lookup = nil
local _name_lookup = nil


local function build_hero_lookup()
local function build_name_lookup()
     if _hero_lookup then return _hero_lookup, _name_lookup end
     if _name_lookup then return _name_lookup end
    _hero_lookup = {}
     _name_lookup = {}
     _name_lookup = {}


Line 473: Line 469:
                 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" then
                     if slot_num and type(ability) == "table" and ability["Name"] then
                        local info = { heroName = hero_name, abilityNum = slot_num }
                         _name_lookup[ability["Name"]] = {
                        if ability["Key"] then _hero_lookup[ability["Key"]]  = info end
                            heroName  = hero_name,
                         if ability["Name"] then _name_lookup[ability["Name"]] = info end
                            abilityNum = slot_num,
                        }
                     end
                     end
                 end
                 end
Line 483: Line 480:
     end
     end


     return _hero_lookup, _name_lookup
     return _name_lookup
end
end


Line 504: Line 501:
     end
     end


     local lookup, name_lookup = build_hero_lookup()
     local name_lookup = build_name_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 {}
Line 527: Line 524:
     local filtered_names = {}
     local filtered_names = {}
     for _, ability in ipairs(abilities) do
     for _, ability in ipairs(abilities) do
         local key = ability["Key"]
         if ability["Name"] and name_lookup[ability["Name"]] then
        if key and lookup[key] then
             table.insert(filtered, ability)
             table.insert(filtered, ability)
             filtered_names[ability["Name"]] = true
             filtered_names[ability["Name"]] = true
Line 540: Line 536:
         for name, _ in pairs(stat_manual) do
         for name, _ in pairs(stat_manual) do
             if not filtered_names[name] then
             if not filtered_names[name] then
                 table.insert(filtered, {
                 table.insert(filtered, { Name = name })
                    Name       = name,
                    _manualInfo = name_lookup[name],
                })
             end
             end
         end
         end
Line 553: Line 546:


     -- Sort by hero name, then ability slot number.
     -- Sort by hero name, then ability slot number.
     -- Abilities with no info (not in lookup or AbilityCards) sort to the end.
     -- Abilities not in name_lookup sort to the end alphabetically.
     table.sort(filtered, function(a, b)
     table.sort(filtered, function(a, b)
         local ia = lookup[a["Key"]] or a._manualInfo
         local ia = name_lookup[a["Name"]]
         local ib = lookup[b["Key"]] or b._manualInfo
         local ib = name_lookup[b["Name"]]
         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 600: Line 593:


     for _, ability in ipairs(filtered) do
     for _, ability in ipairs(filtered) do
         local info = lookup[ability["Key"]] or ability._manualInfo
         local info = name_lookup[ability["Name"]]


         local hero_cell
         local hero_cell
         if info and info.heroName then
         if info then
             hero_cell = frame:expandTemplate{ title = "HeroIcon", args = { info.heroName } }
             hero_cell = frame:expandTemplate{ title = "HeroIcon", args = { info.heroName } }
         else
         else