Files
coa-exporter/CoaExporter/Collectors/Talents.lua
T
florian.berthold 2b97a68317 Initial CoaExporter: merge AscensionExporter + CoA skill/talent dumpers
Folds three previously-separate Lua addons into one for guild-member use:

  - ascension-char-exporter (per-character JSON/Wiki.js Markdown via /ascx)
  - CoA_SkillExporter      (skills/dispels/passives catalog via /skilldump)
  - CoA_TalentExporter     (talent-tree catalog via /talentdumpall)

The two CoA catalog dumpers were ~90% identical entry-walkers. Pulled the
shared C_CharacterAdvancement.GetAllEntries() loop into Catalogs/Common.lua
and have Skills.lua / Talents.lua register collectors that share a single
scan pass (so /coae catalog all walks the entry list once, not twice).

Per-character collectors (Talents, Gear, Enchants, MysticScrolls,
MysticScrollProbe) and the AtlasLootAscension-derived ScrollCatalog data
are kept verbatim, just rebranded.

Slash interface:

  /coae export {all|talents|gear|enchants|mdgear|mdenchants|md}
  /coae catalog {all|skills|talents|dispels [class]|passives [class]|status}
  /coae scrolls {scan|export|reset|status}
  /coae sv on|off | debug | help

Aliases: /coaexp, /ascx, /asxc, plus legacy /skilldump /talentdumpall
/dispels /passives that map to the catalog subcommands.

SavedVariables: CoaExporterSaved, CoaExporterConfig, CoaExporterScrollCache,
CoaExporterCatalog (skills/dispels/levelPassives/talents/_meta).
2026-05-07 10:43:16 +02:00

143 lines
5.0 KiB
Lua

-- CoaExporter - Talents collector (active spec only)
CoaExporter = _G.CoaExporter or {}
_G.CoaExporter = CoaExporter
local AE = CoaExporter
local function get_active_group()
if GetActiveTalentGroup then
local g = GetActiveTalentGroup()
if g == 0 then g = 1 end
return g or 1
end
return 1
end
local function collect_selected_for_tab(tabIndex, talentGroup)
local arr = {}
local debug = {}
local numTalents = GetNumTalents(tabIndex)
for talentIndex = 1, numTalents do
local name, iconTexture, tier, column, rank, maxRank
name, iconTexture, tier, column, rank, maxRank = GetTalentInfo(tabIndex, talentIndex)
if rank == 0 or rank == nil then
name, iconTexture, tier, column, rank, maxRank = GetTalentInfo(tabIndex, talentIndex, nil, nil, talentGroup)
end
if rank == 0 or rank == nil then
name, iconTexture, tier, column, rank, maxRank = GetTalentInfo(tabIndex, talentIndex, false, nil, talentGroup)
end
if rank == 0 or rank == nil then
name, iconTexture, tier, column, rank, maxRank = GetTalentInfo(tabIndex, talentIndex, false, false)
end
if rank and rank > 0 then
local link = GetTalentLink(tabIndex, talentIndex)
local spellId = 0
if link then
spellId = tonumber(string.match(link, "talent:(%d+)")) or 0
end
table.insert(arr, {
tabIndex = tabIndex,
talentIndex = talentIndex,
name = name or "",
rank = rank or 0,
maxRank = maxRank or 0,
spellId = spellId,
})
end
end
return arr, debug
end
function AE.CollectTalents()
local out = {
selected = {},
debug = {},
buildString = nil,
talents = {},
}
if C_CharacterAdvancement and C_CharacterAdvancement.ExportBuild then
local buildString = C_CharacterAdvancement.ExportBuild(true)
out.buildString = buildString
table.insert(out.debug, "Ascension API: C_CharacterAdvancement.ExportBuild() = " .. tostring(buildString))
local ca = C_CharacterAdvancement
if ca.GetKnownTalentEntries then
local entries = ca.GetKnownTalentEntries()
table.insert(out.debug, string.format("Found %d known talent entries", #entries))
for _, entry in ipairs(entries) do
local id = entry.ID or entry.id or 0
local name = entry.name or ""
local icon = entry.icon or ""
local rank, maxRank, tabIndex, tier, column
for _, fname in ipairs({ "GetTalentEntryInfo", "GetTalentEntry",
"GetAdvancementEntry", "GetEntryInfo" }) do
if type(ca[fname]) == "function" then
local ok, a, b, c, d, e, f = pcall(ca[fname], id)
if ok and a then
name = name ~= "" and name or (type(a) == "string" and a or name)
icon = icon ~= "" and icon or (type(b) == "string" and b or icon)
rank = rank or (type(c) == "number" and c or nil)
maxRank = maxRank or (type(d) == "number" and d or nil)
tabIndex = tabIndex or (type(e) == "number" and e or nil)
tier = tier or (type(f) == "number" and f or nil)
break
end
end
end
local talent = {
id = id,
name = name,
icon = icon,
rank = rank or 0,
maxRank = maxRank or 0,
tabIndex = tabIndex or 0,
tier = tier or 0,
column = column or 0,
}
table.insert(out.talents, talent)
table.insert(out.selected, {
id = id,
name = name,
tabIndex = tabIndex or 0,
rank = rank or 1,
maxRank = maxRank or 5,
icon = icon,
})
end
end
if buildString and buildString ~= "" then
out.hasTalents = true
end
return out
end
local active = get_active_group()
out.activeTalentGroup = active
local numTabs = GetNumTalentTabs()
table.insert(out.debug, "Fallback: using GetNumTalentTabs, numTabs=" .. tostring(numTabs))
for tabIndex = 1, numTabs do
local tabName, _, pointsSpent = GetTalentTabInfo(tabIndex, false, false, active)
table.insert(out.debug, string.format("tab%d: name=%s points=%d", tabIndex, tostring(tabName), tonumber(pointsSpent) or 0))
local selected = collect_selected_for_tab(tabIndex, active)
for _, v in ipairs(selected) do
table.insert(out.selected, v)
end
end
return out
end
AE._loadedTalents = true