diff --git a/CoaExporter/Catalogs/Common.lua b/CoaExporter/Catalogs/Common.lua index dc47e98..6c34f23 100644 --- a/CoaExporter/Catalogs/Common.lua +++ b/CoaExporter/Catalogs/Common.lua @@ -89,7 +89,22 @@ function C.Run(filter, callback) return false end - local ctx = { startedAt = date(), filter = filter or "all" } + -- Ascension's GetEntryByInternalID returns the active character's + -- *own* class entries with `Class` unset (the API treats the player's + -- class as implicit). Cache the player's class so we can substitute + -- it when entry.Class is missing — otherwise an export from a + -- Venomancer alt would correctly capture the 41 *other* classes but + -- silently drop every Venomancer talent at the gate. + local playerLocalizedClass, playerClassFile = UnitClass("player") + playerLocalizedClass = playerLocalizedClass or "Unknown" + playerClassFile = playerClassFile or "UNKNOWN" + + local ctx = { + startedAt = date(), + filter = filter or "all", + playerClass = playerLocalizedClass, + playerClassFile = playerClassFile, + } for _, col in ipairs(collectors) do if col.onStart then col.onStart(ctx) end end @@ -100,7 +115,9 @@ function C.Run(filter, callback) local total = #entryKeys local idx = 1 - log(string.format("scanning %d entries for [%s]", total, ctx.filter)) + log(string.format( + "scanning %d entries for [%s] (active class: %s/%s)", + total, ctx.filter, playerLocalizedClass, playerClassFile)) C._isRunning = true local frame = CreateFrame("Frame") @@ -124,7 +141,16 @@ function C.Run(filter, callback) if id then entry = C_CharacterAdvancement.GetEntryByInternalID(id) end end - if entry and entry.Class then + -- Pre-relax: keep entries whose Class field is missing/empty. + -- They're typically the active character's own class (see the + -- comment near `playerLocalizedClass` above). We bucket them + -- under the player's class string further down. + local entryClass = entry and entry.Class + if entry and (not entryClass or entryClass == "") then + entryClass = playerLocalizedClass + end + + if entry and entryClass and entryClass ~= "" then -- Build a normalized info bag every collector can use. local spellId = 0 local allSpells = {} @@ -150,20 +176,27 @@ function C.Run(filter, callback) local tierVal = tonumber(entry.PositionY) or tonumber(entry.Row) or tonumber(entry.y) or 0 local colVal = tonumber(entry.PositionX) or tonumber(entry.Column) or tonumber(entry.x) or tonumber(entry.Col) or 0 - -- Garbage filter: tier=0/col=0/no-icon AND no-spell entries + local entryIcon = (type(entry.Icon) == "string" and entry.Icon ~= "") and entry.Icon or "" + local hasAnyIcon = (icon and icon ~= "") or entryIcon ~= "" + + -- Garbage filter: drop entries that have no spell/coords AND + -- no icon from either source (GetSpellInfo or entry.Icon). + -- entry.Icon catches spec-root talents whose only identity + -- is a server-resolved icon (e.g. Venomancer/Fortitude root). local valid = true - if tierVal == 0 and colVal == 0 and (not icon or icon == "") then valid = false end - if spellId == 0 and (not icon or icon == "") then valid = false end + if tierVal == 0 and colVal == 0 and not hasAnyIcon then valid = false end + if spellId == 0 and not hasAnyIcon then valid = false end if valid then local info = { - cls = tostring(entry.Class), + cls = tostring(entryClass), tab = tostring(entry.Tab or "General"), entryType = tostring(entry.Type or "Talent"), name = name, spellId = spellId, allSpells = allSpells, icon = icon or "", + entryIcon = entryIcon, tier = tierVal, col = colVal, tooltip = tooltip,