fix: enable stance/state bars for CoA custom classes with shapeshift forms

Vanilla Bartender4 assumes only DRUID/WARRIOR/WARLOCK/PRIEST/ROGUE/HERO have
shapeshift forms. CoA custom classes (Witchdoctor, Templar, …) can register
forms late at runtime and aren't in the whitelist, so the stance/state bar
never came up for them.

StanceBar.lua:
  - ApplyConfig() no longer Disable()s the module when GetNumShapeshiftForms()
    is 0 at config time. A disabled module never re-enables on
    UPDATE_SHAPESHIFT_FORMS, so late-registered forms were lost. We now just
    hide the bar frame.
  - Register UPDATE_SHAPESHIFT_FORMS and PLAYER_ENTERING_WORLD on the module
    itself and re-Enable() / show the bar when forms appear after the fact.

Options/Bar.lua:
  - The 'Hide in Stance/Form' visibility option was gated by a hard-coded
    stanceClasses whitelist. Add an OR-fallback on GetNumShapeshiftForms() > 0
    so CoA classes with forms get the UI.

StateBar.lua:
  - DefaultStanceMap only had vanilla entries. For unknown classes with live
    forms, synthesise a generic { id="formN", index=N } map at runtime so
    UpdateStates() can wire stance-based action bar swaps.
This commit is contained in:
2026-05-24 17:39:15 +02:00
parent f8cfedfc06
commit 3fb81c08a0
3 changed files with 54 additions and 4 deletions
+24 -2
View File
@@ -116,12 +116,34 @@ local DefaultStanceMap = setmetatable({}, { __index = function(t,k)
end})
Bartender4.StanceMap = DefaultStanceMap
-- CoA: build a generic runtime stance map for classes the addon doesn't know
-- about (Witchdoctor, Templar, …). We don't have spell-id metadata for them,
-- so synthesise { id = "formN", index = N } entries based on live form count.
local function BuildGenericStanceMap()
local num = GetNumShapeshiftForms()
if not num or num == 0 then return nil end
local map = {}
for i = 1, num do
map[i] = { id = ("form%d"):format(i), name = ("Form %d"):format(i), index = i }
end
return map
end
local stancemap
function StateBar:UpdateStates(returnOnly)
if not self.buttons then return end
self.statebutton = {}
if not stancemap and DefaultStanceMap[playerclass] then
stancemap = DefaultStanceMap[playerclass]
-- CoA: rebuild generic stance maps each call so late-registered forms get
-- picked up; vanilla classes keep their cached DefaultStanceMap entry.
if not stancemap then
if DefaultStanceMap[playerclass] then
stancemap = DefaultStanceMap[playerclass]
elseif GetNumShapeshiftForms() > 0 then
stancemap = BuildGenericStanceMap()
end
elseif not DefaultStanceMap[playerclass] then
-- generic map: refresh on every call in case form count changed
stancemap = BuildGenericStanceMap()
end
local statedriver