Files
coa-exporter/CoaExporter/Collectors/Gear.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

130 lines
4.5 KiB
Lua

-- CoaExporter - Gear collector (equipped items only)
CoaExporter = _G.CoaExporter or {}
_G.CoaExporter = CoaExporter
local AE = CoaExporter
local SLOT_NAMES = {
[1] = "HEAD", [2] = "NECK", [3] = "SHOULDER", [4] = "SHIRT", [5] = "CHEST",
[6] = "WAIST", [7] = "LEGS", [8] = "FEET", [9] = "WRIST", [10] = "HANDS",
[11] = "FINGER1", [12] = "FINGER2", [13] = "TRINKET1", [14] = "TRINKET2",
[15] = "BACK", [16] = "MAINHAND", [17] = "OFFHAND", [18] = "RANGED", [19] = "TABARD",
}
local function parse_item_link(itemLink)
if not itemLink then return nil end
local itemString = itemLink:match("Hitem:([%d:]+)")
if not itemString then return nil end
local parts = {}
for v in string.gmatch(itemString, "([^:]+)") do
parts[#parts+1] = tonumber(v) or 0
end
local itemId = parts[1] or 0
local enchantId = parts[2] or 0
local gems = { parts[3] or 0, parts[4] or 0, parts[5] or 0, parts[6] or 0 }
local suffixId = parts[7] or 0
return {
itemId = itemId,
enchantId = enchantId,
gems = gems,
suffixId = suffixId,
}
end
local function EnsureGearScanner()
if not AE._gearScanner then
AE._gearScanner = CreateFrame("GameTooltip", "CoaExpGearScanner", nil, "GameTooltipTemplate")
AE._gearScanner:SetOwner(WorldFrame, "ANCHOR_NONE")
end
return AE._gearScanner
end
-- Slots that cannot carry a permanent enchant in 3.3.5. Scanning these
-- picks up green-coloured "Equip: ..." effect text on neck/rings/trinkets
-- which would pollute the gear table's Enchant column.
local SLOTS_WITH_NO_ENCHANT = {
[2] = true, [11] = true, [12] = true, [13] = true, [14] = true, [19] = true,
}
local function scan_enchant_name(itemLink, slot)
if not itemLink then return nil end
if slot and SLOTS_WITH_NO_ENCHANT[slot] then return nil end
local tt = EnsureGearScanner()
tt:ClearLines()
tt:SetHyperlink(itemLink)
local n = tt:NumLines() or 0
for i = 2, n do
local l = _G["CoaExpGearScannerTextLeft" .. i]
if l then
local r, g, b = l:GetTextColor()
local text = l:GetText()
if text and text ~= "" and r and g and b then
if r < 0.2 and g > 0.8 and b < 0.2 then
local lower = text:lower()
if not text:match("^Socket Bonus")
and not lower:match("^%(%d+%)%s*set")
and not lower:match("^set:")
and not lower:match("^equip:")
and not lower:match("^use:")
and not lower:match("^chance on hit:") then
return text
end
end
end
end
end
return nil
end
local function resolve_gems(itemLink, gemIds)
local arr = {}
for i = 1, 4 do
local gid = gemIds[i] or 0
if gid and gid > 0 then
local name, gemLink = GetItemGem(itemLink, i)
local gemItemId = 0
if gemLink then
local id = tonumber(string.match(gemLink, "item:(%d+)"))
if id then gemItemId = id end
end
table.insert(arr, { itemId = gemItemId, enchantId = gid, name = name or "", link = gemLink or "" })
end
end
return arr
end
function AE.CollectGear()
local out = { slots = {} }
for slot = 1, 19 do
local itemLink = GetInventoryItemLink("player", slot)
if itemLink then
local parsed = parse_item_link(itemLink) or {}
local itemId = parsed.itemId or 0
local itemName, _, itemQuality, itemLevel, _, itemType, itemSubType, _, equipSlot, texture = GetItemInfo(itemLink)
local gems = resolve_gems(itemLink, parsed.gems or {})
local enchantName = scan_enchant_name(itemLink, slot)
table.insert(out.slots, {
slot = slot,
slotName = SLOT_NAMES[slot] or tostring(slot),
itemId = itemId,
name = itemName or "",
quality = itemQuality or 0,
itemLevel = itemLevel or 0,
type = itemType or "",
subType = itemSubType or "",
equipSlot = equipSlot or "",
texture = texture or "",
link = itemLink,
gems = gems,
enchantId = parsed.enchantId or 0,
enchantName = enchantName or "",
})
end
end
return out
end
AE._loadedGear = true