Files
coa-exporter/CoaExporter/Catalogs/Skills.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

193 lines
6.5 KiB
Lua

-- CoaExporter / Catalogs / Skills.lua
--
-- Dumps the per-class skill catalog: abilities, level passives, and
-- dispel abilities, for all 21 CoA classes. Plugs into Catalogs/Common.lua
-- so it shares the entry-walk with Catalogs/Talents.lua.
--
-- Output (in CoaExporterCatalog):
-- skills = { [class][tab] = { abilities, levelPassives, talents } }
-- dispels = { [class] = { skillData... } }
-- levelPassives = { [class] = { skillData... } }
CoaExporter = _G.CoaExporter or {}
_G.CoaExporter = CoaExporter
local AE = CoaExporter
local C = AE.Catalog
local DISPEL_KEYWORDS = {
"dispel", "dispels", "dispelling",
"removes 1", "removes 2", "removes 3",
"removing 1", "removing 2", "removing 3",
"purify", "cleanse", "cleansing",
"purge",
}
local function HasDispel(tooltip)
if not tooltip then return false end
local lower = string.lower(tooltip)
for _, kw in ipairs(DISPEL_KEYWORDS) do
if string.find(lower, kw) then return true end
end
return false
end
local function GetDispelSnippet(tooltip)
if not tooltip then return "" end
for line in string.gmatch(tooltip, "[^\n]+") do
local lower = string.lower(line)
if string.find(lower, "dispel") or
string.find(lower, "removes") or
string.find(lower, "purify") or
string.find(lower, "cleanse") then
return string.sub(line, 1, 150)
end
end
return ""
end
local function IsLevelPassive(name)
return name and string.find(name, "Level") and string.find(name, "Passive")
end
local skillsByClass, dispelsByClass, levelPassivesByClass
C.Register({
name = "skills",
onStart = function(_)
skillsByClass = {}
dispelsByClass = {}
levelPassivesByClass = {}
end,
onEntry = function(_, entry, info)
local cls = info.cls
local tab = info.tab
skillsByClass[cls] = skillsByClass[cls] or {}
skillsByClass[cls][tab] = skillsByClass[cls][tab] or { abilities = {}, levelPassives = {}, talents = {} }
dispelsByClass[cls] = dispelsByClass[cls] or {}
levelPassivesByClass[cls] = levelPassivesByClass[cls] or {}
local skill = {
name = info.name,
spellId = info.spellId,
advId = entry.ID or 0,
icon = info.icon,
tier = info.tier,
col = info.col,
type = info.entryType,
tab = tab,
tooltip = info.tooltip,
hasDispel = HasDispel(info.tooltip),
dispelSnippet = GetDispelSnippet(info.tooltip),
isLevelPassive = IsLevelPassive(info.name) and true or false,
}
if skill.isLevelPassive then
table.insert(skillsByClass[cls][tab].levelPassives, skill)
table.insert(levelPassivesByClass[cls], skill)
elseif info.entryType == "Ability" then
table.insert(skillsByClass[cls][tab].abilities, skill)
else
table.insert(skillsByClass[cls][tab].talents, skill)
end
if skill.hasDispel then
table.insert(dispelsByClass[cls], skill)
end
end,
onFinish = function(ctx)
CoaExporterCatalog.skills = skillsByClass
CoaExporterCatalog.dispels = dispelsByClass
CoaExporterCatalog.levelPassives = levelPassivesByClass
CoaExporterCatalog.skillsMeta = {
scanAt = ctx.startedAt,
}
local classCount, totalDispels, totalPassives = 0, 0, 0
for _, dispels in pairs(dispelsByClass) do
classCount = classCount + 1
totalDispels = totalDispels + #dispels
end
for _, p in pairs(levelPassivesByClass) do
totalPassives = totalPassives + #p
end
C._log(string.format("skills: %d classes, %d dispels, %d level passives",
classCount, totalDispels, totalPassives))
end,
})
-- Read-only helpers used by /coae catalog dispels|passives commands.
function AE.CatalogListDispels(arg)
local dispels = CoaExporterCatalog.dispels
if not dispels then
C._log("no skill catalog yet - run /coae catalog skills")
return
end
if arg and arg ~= "" then
local found = false
for cls, skills in pairs(dispels) do
if string.lower(cls) == string.lower(arg) then
found = true
C._log("=== DISPELS FOR " .. cls:upper() .. " ===")
for _, sk in ipairs(skills) do
local cat = sk.isLevelPassive and "[PASSIVE]"
or (sk.type == "Ability" and "[ABILITY]" or "[TALENT]")
C._log(" " .. cat .. " " .. sk.name .. " (" .. sk.tab .. ")")
if sk.dispelSnippet ~= "" then
C._log(" -> " .. sk.dispelSnippet)
end
end
end
end
if not found then C._log("class not found: " .. arg) end
else
C._log("=== DISPEL SUMMARY (ALL CLASSES) ===")
local sorted = {}
for cls in pairs(dispels) do table.insert(sorted, cls) end
table.sort(sorted)
for _, cls in ipairs(sorted) do
local sk = dispels[cls]
local a, p, t = 0, 0, 0
for _, s in ipairs(sk) do
if s.isLevelPassive then p = p + 1
elseif s.type == "Ability" then a = a + 1
else t = t + 1 end
end
C._log(string.format(" %s: %d total (A:%d P:%d T:%d)", cls, #sk, a, p, t))
end
end
end
function AE.CatalogListPassives(arg)
local passives = CoaExporterCatalog.levelPassives
if not passives then
C._log("no skill catalog yet - run /coae catalog skills")
return
end
if arg and arg ~= "" then
for cls, skills in pairs(passives) do
if string.lower(cls) == string.lower(arg) then
C._log("=== LEVEL PASSIVES FOR " .. cls:upper() .. " ===")
for _, sk in ipairs(skills) do
C._log(" " .. sk.name .. " (" .. sk.tab .. ")")
end
end
end
else
C._log("=== LEVEL PASSIVES SUMMARY ===")
local sorted = {}
for cls in pairs(passives) do table.insert(sorted, cls) end
table.sort(sorted)
for _, cls in ipairs(sorted) do
C._log(string.format(" %s: %d level passives", cls, #passives[cls]))
end
end
end
AE._loadedCatalogSkills = true