Add per-character spellbook collector

New Collectors/Spellbook.lua walks GetNumSpellTabs() and emits one entry
per tab with name, texture, offset, numSpells, and a spells[] array of
{ slot, name, rank, spellID, icon }.

3.3.5/Ascension API differences are handled defensively: name comes
from GetSpellBookItemInfo or vanilla GetSpellName; spellID is parsed
out of GetSpellLink (3.3.5 doesn't return it from GetSpellBookItemInfo);
icon falls back to GetSpellTexture if GetSpellInfo doesn't have it yet.

Wiring:
  - CoaExporter.toc: load Collectors/Spellbook.lua after Talents
  - Core.lua: AssembleExport() includes spellbook for all + spellbook
  - Core.lua: HandleExport() accepts /coae export spellbook
  - Core.lua: debug output shows tab + spell counts
  - UI/ExportFrame.lua: "Spellbook" button in the Character section
This commit is contained in:
2026-05-07 12:08:23 +02:00
parent cc5a87d2fb
commit 6badf0e7ea
5 changed files with 124 additions and 7 deletions
+16 -6
View File
@@ -47,6 +47,9 @@ function AE:AssembleExport(which)
if wantAll or which == "talents" then
if AE.CollectTalents then out.talents = SafeCall(AE.CollectTalents) or {} end
end
if wantAll or which == "spellbook" then
if AE.CollectSpellbook then out.spellbook = SafeCall(AE.CollectSpellbook) or {} end
end
if wantAll or which == "gear" then
if AE.CollectGear then out.gear = SafeCall(AE.CollectGear) or {} end
end
@@ -331,7 +334,7 @@ end
local HELP = [[
CoaExporter commands:
/coae export all|talents|gear|enchants
/coae export all|talents|spellbook|gear|enchants
/coae export mdgear|mdenchants|md (full wiki)
/coae catalog all|skills|talents
/coae catalog dispels [class]|passives [class]|status
@@ -349,7 +352,7 @@ local function HandleExport(rest)
AE:ShowExport(AE:GenerateMarkdownEnchants(), "CoaExporter - Markdown Enchants (Ctrl+C)")
elseif rest == "md" or rest == "mdfull" or rest == "wiki" then
AE:ShowExport(AE:GenerateMarkdownFull(), "CoaExporter - Wiki Markdown (Ctrl+C)")
elseif rest == "all" or rest == "talents" or rest == "gear" or rest == "enchants" then
elseif rest == "all" or rest == "talents" or rest == "spellbook" or rest == "gear" or rest == "enchants" then
AE:Export(rest)
else
DEFAULT_CHAT_FRAME:AddMessage("CoaExporter: unknown export target '" .. tostring(rest) .. "'")
@@ -442,10 +445,10 @@ local function HandleDebug()
add(string.format("- AddOn: %s", tostring(ADDON_NAME)))
add(string.format("- UI: %s", type(_G.CoaExporter_ShowExportFrame) == "function" and "yes" or "no"))
add(string.format("- JSON: %s", type(_G.CoaExporter_Json_Encode) == "function" and "yes" or "no"))
add(string.format("- Loaded: talents=%s gear=%s enchants=%s scrolls=%s probe=%s catCommon=%s catSkills=%s catTalents=%s",
tostring(AE._loadedTalents or false), tostring(AE._loadedGear or false),
tostring(AE._loadedEnchants or false), tostring(AE._loadedMysticScrolls or false),
tostring(AE._loadedMysticScrollProbe or false),
add(string.format("- Loaded: talents=%s spellbook=%s gear=%s enchants=%s scrolls=%s probe=%s catCommon=%s catSkills=%s catTalents=%s",
tostring(AE._loadedTalents or false), tostring(AE._loadedSpellbook or false),
tostring(AE._loadedGear or false), tostring(AE._loadedEnchants or false),
tostring(AE._loadedMysticScrolls or false), tostring(AE._loadedMysticScrollProbe or false),
tostring(AE._loadedCatalogCommon or false), tostring(AE._loadedCatalogSkills or false),
tostring(AE._loadedCatalogTalents or false)))
@@ -456,6 +459,13 @@ local function HandleDebug()
else
add("Talents: MISSING")
end
if type(AE.CollectSpellbook) == "function" then
local sb = SafeCall(AE.CollectSpellbook) or {}
add(string.format("Spellbook: OK, tabs=%d, spells=%d",
#(sb.tabs or {}), sb.totalSpells or 0))
else
add("Spellbook: MISSING")
end
if type(AE.CollectGear) == "function" then
local g = SafeCall(AE.CollectGear) or {}
add(string.format("Gear: OK, slots=%d", #(g.slots or {})))