Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions ClassUtil.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ function ClassUtil.GetPlayerResourceType()
return ClassUtil.GetResourceType(class, GetSpecialization(), GetShapeshiftForm())
end

--- Returns whether the player is a Death Knight.
function ClassUtil.IsDeathKnight()
local _, class = UnitClass("player")
return class == "DEATHKNIGHT"
end

--- Gets the max Maelstrom value that can diff based on talents
local function getMaelstromWeaponMax()
if C_SpellBook.IsSpellKnown(C.RESOURCEBAR_RAGING_MAELSTROM_SPELLID) then
Expand Down Expand Up @@ -135,6 +141,7 @@ function ClassUtil.GetCurrentMaxResourceValues(resourceType)
if resourceType then
local max = UnitPowerMax("player", resourceType)
local current = UnitPower("player", resourceType)
---@type number|nil
local safeMax = max
if issecretvalue(max) then
safeMax = nil
Expand Down
14 changes: 0 additions & 14 deletions ColorUtil.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,6 @@ local _, ns = ...
local ColorUtil = {}
ns.ColorUtil = ColorUtil

--- Compares two ECM_Color tables for equality.
---@param c1 ECM_Color|nil
---@param c2 ECM_Color|nil
---@return boolean
function ColorUtil.AreEqual(c1, c2)
if c1 == c2 then
return true
end
if not c1 or not c2 then
return false
end
return c1.r == c2.r and c1.g == c2.g and c1.b == c2.b and c1.a == c2.a
end

local function clamp(v, minV, maxV)
return math.max(minV, math.min(maxV, v))
end
Expand Down
47 changes: 20 additions & 27 deletions Constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -177,19 +177,19 @@ local constants = {

--- Predefined icon stacks resolved at runtime by stackKey.
--- Each entry defines an icon kind and its candidate sources.
local BUILTIN_STACKS = {
constants.BUILTIN_STACKS = {
trinket1 = { kind = "equipSlot", slotId = 13, label = "Trinket 1" },
trinket2 = { kind = "equipSlot", slotId = 14, label = "Trinket 2" },
}

--- Default display order for builtin stack keys (matches default viewers.utility order).
local BUILTIN_STACK_ORDER = { "trinket1", "trinket2" }
constants.BUILTIN_STACK_ORDER = { "trinket1", "trinket2" }

local DRACTHYR_WING_BUFFET_IDS = { 357214, 368970 } -- Base and enhanced evoker variants.
local dracthyrWingBuffetIds = { 357214, 368970 } -- Base and enhanced evoker variants.

--- Racial ability lookup keyed by UnitRace("player") raceFileName.
--- One primary active racial per race.
local RACIAL_ABILITIES = {
constants.RACIAL_ABILITIES = {
Human = { spellId = 59752 }, -- Every Man for Himself
Orc = { spellId = 33697 }, -- Blood Fury
Dwarf = { spellId = 20594 }, -- Stoneform
Expand All @@ -213,25 +213,25 @@ local RACIAL_ABILITIES = {
Vulpera = { spellId = 312411 }, -- Bag of Tricks
MagharOrc = { spellId = 274738 }, -- Ancestral Call
Mechagnome = { spellId = 312924 }, -- Hyper Organic Light Originator
Dracthyr = { spellIds = DRACTHYR_WING_BUFFET_IDS }, -- Wing Buffet
Dracthyr = { spellIds = dracthyrWingBuffetIds }, -- Wing Buffet
EarthenDwarf = { spellId = 436717 }, -- Azerite Surge
}

--- Some racial abilities have different spell IDs. For example, Dracthyr evokers
--- have a more potent wing buffet compared to other classes.
local RACIAL_SPELL_ALIASES = {
[357214] = DRACTHYR_WING_BUFFET_IDS,
[368970] = DRACTHYR_WING_BUFFET_IDS,
constants.RACIAL_SPELL_ALIASES = {
[357214] = dracthyrWingBuffetIds,
[368970] = dracthyrWingBuffetIds,
}

local BLIZZARD_FRAMES = {
constants.BLIZZARD_FRAMES = {
"EssentialCooldownViewer",
"UtilityCooldownViewer",
"BuffIconCooldownViewer",
"BuffBarCooldownViewer",
}

local CLASS_COLORS = {
constants.CLASS_COLORS = {
DEATHKNIGHT = "C41F3B",
DEMONHUNTER = "A330C9",
DRUID = "FF7D0A",
Expand All @@ -249,19 +249,19 @@ local CLASS_COLORS = {

-- Resource types that support a separate color when at maximum value.
-- Code-level gate; user toggle is stored in the profile (maxColorsEnabled).
local resourceBarMaxColorTypes = {
constants.RESOURCEBAR_MAX_COLOR_TYPES = {
[constants.RESOURCEBAR_TYPE_ICICLES] = true,
[constants.RESOURCEBAR_TYPE_DEVOURER_META] = true,
[constants.RESOURCEBAR_TYPE_DEVOURER_NORMAL] = true,
}

local resourceBarCastableMaxColorSpells = {
constants.RESOURCEBAR_CASTABLE_MAX_COLOR_SPELLS = {
[constants.RESOURCEBAR_TYPE_DEVOURER_META] = constants.SPELLID_COLLAPSING_STAR,
[constants.RESOURCEBAR_TYPE_DEVOURER_NORMAL] = constants.SPELLID_VOID_META,
}

--- Authoritative mapping from module name to its profile config key.
local moduleConfigKeys = {
--- Maps modules to their respective profile config key.
constants.MODULE_CONFIG_KEYS = {
[constants.POWERBAR] = "powerBar",
[constants.RESOURCEBAR] = "resourceBar",
[constants.RUNEBAR] = "runeBar",
Expand All @@ -273,33 +273,26 @@ local moduleConfigKeys = {
--- Returns the profile config key for a module name.
--- Uses the authoritative lookup; falls back to lowercasing the first character.
function constants.ConfigKeyForModule(name)
return moduleConfigKeys[name] or (name:sub(1, 1):lower() .. name:sub(2))
return constants.MODULE_CONFIG_KEYS[name] or (name:sub(1, 1):lower() .. name:sub(2))
end

local chainOrder = {
-- Defines the ordering of modules for chained anchoring.
constants.CHAIN_ORDER = {
constants.POWERBAR,
constants.RESOURCEBAR,
constants.RUNEBAR,
constants.BUFFBARS,
constants.EXTERNALBARS,
}
constants.CHAIN_ORDER = chainOrder
constants.MODULE_ORDER = {

-- Controls the order that modules are loaded in.
constants.MODULE_LOAD_ORDER = {
constants.POWERBAR,
constants.RESOURCEBAR,
constants.RUNEBAR,
constants.BUFFBARS,
constants.EXTERNALBARS,
constants.EXTRAICONS,
}
constants.MODULE_CONFIG_KEYS = moduleConfigKeys
constants.BLIZZARD_FRAMES = BLIZZARD_FRAMES
constants.BUILTIN_STACKS = BUILTIN_STACKS
constants.BUILTIN_STACK_ORDER = BUILTIN_STACK_ORDER
constants.RACIAL_ABILITIES = RACIAL_ABILITIES
constants.RACIAL_SPELL_ALIASES = RACIAL_SPELL_ALIASES
constants.RESOURCEBAR_CASTABLE_MAX_COLOR_SPELLS = resourceBarCastableMaxColorSpells
constants.CLASS_COLORS = CLASS_COLORS
constants.RESOURCEBAR_MAX_COLOR_TYPES = resourceBarMaxColorTypes

ns.Constants = constants
6 changes: 0 additions & 6 deletions ECM.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ function ns.AreWarningsEnabled()
return not gc or gc.warnings ~= false
end

--- Returns whether the player is a Death Knight.
function ns.IsDeathKnight()
local _, class = UnitClass("player")
return class == "DEATHKNIGHT"
end

local function getAddonVersion()
return C_AddOns.GetAddOnMetadata(ADDON_NAME, C.ADDON_METADATA_VERSION_KEY)
end
Expand Down
3 changes: 2 additions & 1 deletion EnhancedCooldownManager.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@
"SettingsPanel",
"SettingsSliderControlMixin",
"CreateSettingsListSectionHeaderInitializer",
"Round"
"Round",
"CLASS_COLORS"
],
"Lua.diagnostics.disable": [
"assign-type-mismatch"
Expand Down
4 changes: 2 additions & 2 deletions Modules/RuneBar.lua
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ function RuneBar:CreateFrame()
end

function RuneBar:ShouldShow()
return ns.IsDeathKnight() and ns.BarMixin.FrameProto.ShouldShow(self)
return ns.ClassUtil.IsDeathKnight() and ns.BarMixin.FrameProto.ShouldShow(self)
end

function RuneBar:Refresh(why, force)
Expand Down Expand Up @@ -359,7 +359,7 @@ function RuneBar:OnInitialize()
end

function RuneBar:OnEnable()
if not ns.IsDeathKnight() then
if not ns.ClassUtil.IsDeathKnight() then
return
end

Expand Down
2 changes: 1 addition & 1 deletion Runtime.lua
Original file line number Diff line number Diff line change
Expand Up @@ -694,7 +694,7 @@ end
function Runtime.Enable(addon)
local profile = addon.db and addon.db.profile

for _, moduleName in ipairs(C.MODULE_ORDER) do
for _, moduleName in ipairs(C.MODULE_LOAD_ORDER) do
local configKey = C.MODULE_CONFIG_KEYS[moduleName]
local moduleConfig = profile and profile[configKey]
local shouldEnable = (not moduleConfig) or (moduleConfig.enabled ~= false)
Expand Down
18 changes: 18 additions & 0 deletions Tests/ClassUtil_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,24 @@ describe("ClassUtil", function()
end
end)

describe("IsDeathKnight", function()
it("returns true when the player's class token is DEATHKNIGHT", function()
_G.UnitClass = function()
return "Death Knight", "DEATHKNIGHT", 6
end

assert.is_true(ns.ClassUtil.IsDeathKnight())
end)

it("returns false when the player's class token is not DEATHKNIGHT", function()
_G.UnitClass = function()
return "Warrior", "WARRIOR", 1
end

assert.is_false(ns.ClassUtil.IsDeathKnight())
end)
end)

describe("GetResourceType", function()
local function setAvailablePowerType(powerType)
UnitStub.Reset()
Expand Down
11 changes: 1 addition & 10 deletions Tests/ColorUtil_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,12 @@ describe("ColorUtil", function()
end)

before_each(function()
ns = {}
ns = {}

TestHelpers.LoadChunk("ColorUtil.lua", "Unable to load ColorUtil.lua")(nil, ns)
ColorUtil = assert(ns.ColorUtil, "ColorUtil did not initialize")
end)

it("AreEqual handles identical, nil, and distinct colors", function()
local color = { r = 1, g = 0.5, b = 0.25, a = 1 }

assert.is_true(ColorUtil.AreEqual(color, color))
assert.is_true(ColorUtil.AreEqual(nil, nil))
assert.is_false(ColorUtil.AreEqual(color, nil))
assert.is_false(ColorUtil.AreEqual(color, { r = 1, g = 0.5, b = 0.25, a = 0.5 }))
end)

it("ColorToHex converts normalized RGB values to lowercase hex", function()
local hex = ColorUtil.ColorToHex({ r = 1, g = 0.5, b = 0, a = 1 })
assert.are.equal("ff8000", hex)
Expand Down
10 changes: 0 additions & 10 deletions Tests/FrameUtil_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,6 @@ describe("FrameUtil", function()
secretValues = {}

ns = {}
ns.ColorUtil = {}
ns.ColorUtil.AreEqual = function(a, b)
if a == nil and b == nil then
return true
end
if a == nil or b == nil then
return false
end
return a.r == b.r and a.g == b.g and a.b == b.b and a.a == b.a
end
ns.DebugAssert = function(condition, message)
if not condition then
error(message or "ECM.DebugAssert failed")
Expand Down
8 changes: 5 additions & 3 deletions Tests/Modules/RuneBar_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,11 @@ describe("RuneBar real source", function()
target.EnsureFrame = target.EnsureFrame or function() end
end,
},
IsDeathKnight = function()
return isDeathKnight
end,
ClassUtil = {
IsDeathKnight = function()
return isDeathKnight
end,
},
Runtime = {
RegisterFrame = function()
registerFrameCalls = registerFrameCalls + 1
Expand Down
11 changes: 6 additions & 5 deletions Tests/TestHelpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1851,11 +1851,12 @@ function TestHelpers.SetupOptionsEnv(profile, defaults)
ns.GetGlobalConfig = function()
return mod.db.profile and mod.db.profile.global
end
ns.IsDeathKnight = function()
local _, classToken = UnitClass("player")
return classToken == "DEATHKNIGHT"
end
ns.ClassUtil = {}
ns.ClassUtil = {
IsDeathKnight = function()
local _, classToken = UnitClass("player")
return classToken == "DEATHKNIGHT"
end,
}

TestHelpers.LoadChunk("UI/OptionUtil.lua", "Unable to load UI/OptionUtil.lua")(nil, ns)
TestHelpers.LoadChunk("UI/ExtraIconsShared.lua", "Unable to load UI/ExtraIconsShared.lua")(nil, ns)
Expand Down
2 changes: 1 addition & 1 deletion UI/ResourceBarOptions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ rows[#rows + 1] = {

ResourceBarOptions.key = "resourceBar"
ResourceBarOptions.name = L["RESOURCE_BAR"]
ResourceBarOptions.disabled = ns.IsDeathKnight
ResourceBarOptions.disabled = ns.ClassUtil.IsDeathKnight
ResourceBarOptions.pages = {
{
key = "main",
Expand Down
4 changes: 2 additions & 2 deletions UI/RuneBarOptions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ for _, row in ipairs(ns.OptionUtil.CreateBarRows(isDisabled, { showText = false,
rows[#rows + 1] = row
end

if not ns.IsDeathKnight() then
if not ns.ClassUtil.IsDeathKnight() then
table.insert(rows, 1, {
type = "subheader",
name = L["DK_ONLY_WARNING"],
Expand Down Expand Up @@ -79,7 +79,7 @@ rows[#rows + 1] = {
RuneBarOptions.key = "runeBar"
RuneBarOptions.name = L["RUNE_BAR"]
RuneBarOptions.disabled = function()
return not ns.IsDeathKnight()
return not ns.ClassUtil.IsDeathKnight()
end
RuneBarOptions.pages = {
{
Expand Down