CoA: mirror RAID_CLASS_COLORS for the 21 custom classes

Vanilla Altoholic hardcodes a 10-entry ChatColor table keyed by the
englishClass tokens MAGE/WARRIOR/.../DEATHKNIGHT. On the CoA Voljin/PTR
realm UnitClass / GetGuildRosterInfo return tokens like BARBARIAN,
WITCHDOCTOR, CHRONOMANCER, … so the lookup falls through:

  * Altoholic:GetClassColor (Altoholic.lua:580) returns WHITE for all
    21 CoA classes via the `or WHITE` fallback — guild/character/
    profession panes lose their per-class colours.
  * DataStore_Characters._GetColoredCharacterName had no fallback at
    all — `ClassColors[englishClass] .. character.name` hard-crashed
    on nil-concat for any CoA-class character.
  * Altoholic.lua:710 read CLASS_ICON_TCOORDS[class] for the character
    portrait without a fallback; CoA classes aren't in the vanilla
    sprite sheet's coord table, so the next line `tc[1]` crashed.

Fix follows the established Exiles addon-port pattern (see
coa-omen/CoAClassColors.lua, coa-shadowedunitframes/.../CoAClassColors.lua,
coa-kui-nameplates/.../CoAClassColors.lua): mirror _G.RAID_CLASS_COLORS
into the addon's private table at load. The CoA client itself ships
the realm-authoritative 32-token palette (10 vanilla + HERO + 21 CoA)
in Interface/SharedXML/SharedConstants.lua inside patch-B.MPQ, which
populates RAID_CLASS_COLORS at FrameXML load time — see
db.exil.es /coa/dev for the full table.

- Altoholic/CoAClassColors.lua: new file, mirrors source palette into
  Altoholic.ClassInfo as "|cFFRRGGBB" ChatColor escapes. Never
  overwrites — preserves the addon's vanilla defaults and any future
  user overrides.
- Altoholic/Altoholic.xml: loads CoAClassColors.lua after Altoholic.lua
  so Altoholic.ClassInfo exists.
- Altoholic/Altoholic.lua: defensive CLASS_ICON_TCOORDS lookup with
  WARRIOR fallback (wrong icon beats crash; CoA character creation
  uses its own sprite sheet which doesn't extend the vanilla table).
- DataStore_Characters/DataStore_Characters.lua: inline mirror after
  the local ClassColors table (can't be touched from a sibling file
  because the table is file-local), plus `or WHITE` defensive fallback
  in _GetColoredCharacterName and _GetClassColor.

Does not touch DataStore_Talents — CoA's MoA system uses
C_CharacterAdvancement, not GetNumTalentTabs/GetTalentInfo, so that
module needs a full API rewrite rather than a data patch.
This commit is contained in:
2026-05-17 16:37:57 +02:00
parent 0fa1293223
commit f53f3e3f0f
4 changed files with 87 additions and 10 deletions
+4 -1
View File
@@ -707,7 +707,10 @@ function Altoholic:ShowClassIcons()
end) end)
local _, class = DS:GetCharacterClass(character) local _, class = DS:GetCharacterClass(character)
local tc = CLASS_ICON_TCOORDS[class] -- CoA: CLASS_ICON_TCOORDS only carries the vanilla 10 + DK on Voljin.
-- For the 21 CoA custom classes the lookup is nil; fall back to
-- WARRIOR's coords so we render *something* rather than crashing.
local tc = CLASS_ICON_TCOORDS[class] or CLASS_ICON_TCOORDS["WARRIOR"]
local itemTexture = _G[itemName .. "IconTexture"] local itemTexture = _G[itemName .. "IconTexture"]
itemTexture:SetTexture("Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Classes"); itemTexture:SetTexture("Interface\\Glues\\CharacterCreate\\UI-CharacterCreate-Classes");
itemTexture:SetTexCoord(tc[1], tc[2], tc[3], tc[4]); itemTexture:SetTexCoord(tc[1], tc[2], tc[3], tc[4]);
+2 -1
View File
@@ -17,7 +17,8 @@
<Script file="Suggestions_koKR.lua"></Script> <Script file="Suggestions_koKR.lua"></Script>
<Script file="Characters.lua"></Script> <Script file="Characters.lua"></Script>
<Script file="Altoholic.lua"></Script> <Script file="Altoholic.lua"></Script>
<Script file="CoAClassColors.lua"></Script>
<GameTooltip name="AltoTooltip" inherits="GameTooltipTemplate" parent="UIParent" hidden="true" /> <GameTooltip name="AltoTooltip" inherits="GameTooltipTemplate" parent="UIParent" hidden="true" />
<Button name="AltoholicMinimapButton" parent="Minimap" toplevel="true"> <Button name="AltoholicMinimapButton" parent="Minimap" toplevel="true">
@@ -0,0 +1,47 @@
-- CoAClassColors.lua
--
-- Mirrors the live client's RAID_CLASS_COLORS palette into
-- Altoholic.ClassInfo so the guild/character/profession panes render
-- the 21 Conquest-of-Azeroth custom classes (plus HERO) instead of
-- defaulting to WHITE via the `or WHITE` fallback at
-- Altoholic.lua:581.
--
-- Background
-- ----------
-- Altoholic ships a hardcoded ChatColor table keyed by the 10 vanilla
-- englishClass tokens (Altoholic.lua:23-32). On the CoA Voljin/PTR
-- realm, UnitClass / GetGuildRosterInfo return tokens like BARBARIAN,
-- WITCHDOCTOR, CHRONOMANCER, … which fall through the table.
--
-- The realm-authoritative palette is shipped by the client itself in
-- _G.RAID_CLASS_COLORS (Interface/SharedXML/SharedConstants.lua inside
-- patch-B.MPQ — 10 vanilla + HERO + 21 CoA = 32 entries on Voljin).
-- Other Exiles addon ports follow the same mirror pattern
-- (coa-omen/CoAClassColors.lua → CUSTOM_CLASS_COLORS,
-- coa-shadowedunitframes/.../CoAClassColors.lua → SUF profile,
-- coa-kui-nameplates/.../CoAClassColors.lua → !ClassColors).
--
-- Source of truth: db.exil.es /coa/dev for the full palette;
-- _G.RAID_CLASS_COLORS at FrameXML load time for the running client.
local AC = _G.Altoholic and _G.Altoholic.ClassInfo
if type(AC) ~= "table" then return end
local source = _G.RAID_CLASS_COLORS
if type(source) ~= "table" then return end
local function unpackColor(c)
if type(c) ~= "table" then return end
if c.GetRGB then return c:GetRGB() end
return c.r, c.g, c.b
end
for token, color in pairs(source) do
if AC[token] == nil then
local r, g, b = unpackColor(color)
if r and g and b then
AC[token] = string.format("|cFF%02X%02X%02X",
r * 255 + 0.5, g * 255 + 0.5, b * 255 + 0.5)
end
end
end
@@ -129,26 +129,52 @@ local function _GetCharacterClass(character)
return character.class or "", character.englishClass or "" return character.class or "", character.englishClass or ""
end end
local WHITE = "|cFFFFFFFF"
local ClassColors = { local ClassColors = {
["MAGE"] = "|cFF69CCF0", ["MAGE"] = "|cFF69CCF0",
["WARRIOR"] = "|cFFC79C6E", ["WARRIOR"] = "|cFFC79C6E",
["HUNTER"] = "|cFFABD473", ["HUNTER"] = "|cFFABD473",
["ROGUE"] = "|cFFFFF569", ["ROGUE"] = "|cFFFFF569",
["WARLOCK"] = "|cFF9482CA", ["WARLOCK"] = "|cFF9482CA",
["DRUID"] = "|cFFFF7D0A", ["DRUID"] = "|cFFFF7D0A",
["SHAMAN"] = "|cFF2459FF", ["SHAMAN"] = "|cFF2459FF",
["PALADIN"] = "|cFFF58CBA", ["PALADIN"] = "|cFFF58CBA",
["PRIEST"] = "|cFFFFFFFF", ["PRIEST"] = WHITE,
["DEATHKNIGHT"] = "|cFFC41F3B" ["DEATHKNIGHT"] = "|cFFC41F3B"
} }
local function _GetColoredCharacterName(character) -- CoA: mirror _G.RAID_CLASS_COLORS (10 vanilla + HERO + 21 CoA tokens on
return ClassColors[character.englishClass] .. character.name -- the Voljin/PTR realm) into ClassColors so guild/character rows for
-- BARBARIAN, WITCHDOCTOR, CHRONOMANCER, … render with the
-- realm-canonical palette instead of nil-concat-crashing in
-- _GetColoredCharacterName below. Source of truth is the client's
-- Interface/SharedXML/SharedConstants.lua; same pattern as
-- coa-omen/CoAClassColors.lua and the Altoholic UI's CoAClassColors.lua.
do
local source = _G.RAID_CLASS_COLORS
if type(source) == "table" then
for token, color in pairs(source) do
if ClassColors[token] == nil and type(color) == "table" then
local r, g, b
if color.GetRGB then r, g, b = color:GetRGB()
else r, g, b = color.r, color.g, color.b end
if r and g and b then
ClassColors[token] = string.format("|cFF%02X%02X%02X",
r * 255 + 0.5, g * 255 + 0.5, b * 255 + 0.5)
end
end
end
end
end end
local function _GetColoredCharacterName(character)
return (ClassColors[character.englishClass] or WHITE) .. character.name
end
local function _GetClassColor(character) local function _GetClassColor(character)
-- return just the color of this character's class -- return just the color of this character's class
return ClassColors[character.englishClass] return ClassColors[character.englishClass] or WHITE
end end
local function _GetCharacterFaction(character) local function _GetCharacterFaction(character)