HideCoA = {} local f = CreateFrame("Frame") HideCoA.CUSTOM_CLASSES = { "NECROMANCER", "PYROMANCER", "CULTIST", "STARCALLER", "SUNCLERIC", "TINKER", "SPIRITMAGE", "WILDWALKER", "REAPER", "PROPHET", "CHRONOMANCER", "SONOFARUGAL", "GUARDIAN", "STORMBRINGER", "DEMONHUNTER", "BARBARIAN", "WITCHDOCTOR", "WITCHHUNTER", "FLESHWARDEN", "MONK", "RANGER", } HideCoA.FRAMES = { "CoAResourceSegmentBar", "CoAResourceOrb", "CoAResourceBar", } local function CreateDefaultClassSettings() local classSettings = {} for _, class in ipairs(HideCoA.CUSTOM_CLASSES) do classSettings[class] = {} for _, frameName in ipairs(HideCoA.FRAMES) do classSettings[class][frameName] = true end end return classSettings end local function EnsureClassSettingsComplete(classSettings) for _, class in ipairs(HideCoA.CUSTOM_CLASSES) do if type(classSettings[class]) ~= "table" then classSettings[class] = {} end for _, frameName in ipairs(HideCoA.FRAMES) do if classSettings[class][frameName] == nil then classSettings[class][frameName] = true end end end end local function GetCharacterKey() return UnitName("player") .. " - " .. GetRealmName() end HideCoA.GetCharacterKey = GetCharacterKey local function GetActiveProfileName() local charKey = GetCharacterKey() local assigned = HideCoADB.charProfile and HideCoADB.charProfile[charKey] if assigned and HideCoADB.profiles[assigned] then return assigned end return charKey end HideCoA.GetActiveProfileName = GetActiveProfileName local function SetActiveProfileName(name) HideCoADB.charProfile[GetCharacterKey()] = name end HideCoA.SetActiveProfileName = SetActiveProfileName local function GetActiveClassSettings() local name = GetActiveProfileName() local profile = HideCoADB.profiles[name] if not profile then profile = { classSettings = CreateDefaultClassSettings() } HideCoADB.profiles[name] = profile end if not profile.classSettings then profile.classSettings = CreateDefaultClassSettings() end return profile.classSettings end HideCoA.GetActiveClassSettings = GetActiveClassSettings local function CopyProfile(sourceName, destName) local source = HideCoADB.profiles[sourceName] if not source or not source.classSettings then return end local copy = {} for class, settings in pairs(source.classSettings) do copy[class] = {} for frameName, value in pairs(settings) do copy[class][frameName] = value end end if not HideCoADB.profiles[destName] then HideCoADB.profiles[destName] = {} end HideCoADB.profiles[destName].classSettings = copy HideCoA.ApplySetting() end HideCoA.CopyProfile = CopyProfile local function ResetProfile() local name = GetActiveProfileName() if not HideCoADB.profiles[name] then HideCoADB.profiles[name] = {} end HideCoADB.profiles[name].classSettings = CreateDefaultClassSettings() HideCoA.ApplySetting() end HideCoA.ResetProfile = ResetProfile local function DeleteProfile(name) if name == "Default" then return end local wasActive = (name == GetActiveProfileName()) HideCoADB.profiles[name] = nil for charKey, assigned in pairs(HideCoADB.charProfile) do if assigned == name then HideCoADB.charProfile[charKey] = nil end end if wasActive then HideCoADB.charProfile[GetCharacterKey()] = "Default" end end HideCoA.DeleteProfile = DeleteProfile local function EnsureCharacterOverride(charKey) if not HideCoADB.characterOverrides then HideCoADB.characterOverrides = {} end local override = HideCoADB.characterOverrides[charKey] if not override then override = { enabled = false, frameSettings = {} } HideCoADB.characterOverrides[charKey] = override end for _, frameName in ipairs(HideCoA.FRAMES) do if override.frameSettings[frameName] == nil then override.frameSettings[frameName] = true end end return override end local function GetCharacterOverride() return EnsureCharacterOverride(GetCharacterKey()) end HideCoA.GetCharacterOverride = GetCharacterOverride local function SetCharacterOverrideEnabled(enabled) GetCharacterOverride().enabled = enabled HideCoA.ApplySetting() end HideCoA.SetCharacterOverrideEnabled = SetCharacterOverrideEnabled local function SetCharacterOverrideFrameHidden(frameName, hide) GetCharacterOverride().frameSettings[frameName] = hide HideCoA.ApplySetting() end HideCoA.SetCharacterOverrideFrameHidden = SetCharacterOverrideFrameHidden local function SetAllClassesHidden(hide) local classSettings = GetActiveClassSettings() for _, class in ipairs(HideCoA.CUSTOM_CLASSES) do for _, frameName in ipairs(HideCoA.FRAMES) do classSettings[class][frameName] = hide end end end local function HideAllFrames() SetAllClassesHidden(true) HideCoA.ApplySetting() end HideCoA.HideAllFrames = HideAllFrames local function ShowAllFrames() SetAllClassesHidden(false) HideCoA.ApplySetting() end HideCoA.ShowAllFrames = ShowAllFrames local function ShouldHideForClass(playerClass, frameName) local classSettings = GetActiveClassSettings()[playerClass] if not classSettings or classSettings[frameName] == nil then return true end return classSettings[frameName] end local function ShouldHideFrame(frameName) local override = GetCharacterOverride() if override.enabled then return override.frameSettings[frameName] end local _, playerClass = UnitClass("player") return ShouldHideForClass(playerClass, frameName) end local hookedFrames = {} local seenNaturalShow = {} local function ApplySetting() for _, frameName in ipairs(HideCoA.FRAMES) do local frame = _G[frameName] if frame then if not hookedFrames[frameName] then frame:HookScript("OnShow", function(self) seenNaturalShow[frameName] = true if ShouldHideFrame(frameName) then self:Hide() end end) hookedFrames[frameName] = true end local hide = ShouldHideFrame(frameName) if hide then frame:Hide() elseif seenNaturalShow[frameName] then -- The server never Show()s a frame the current class doesn't use, -- so its data (powerType, maxValue, ...) is never populated. Forcing -- Show() on it exposes that uninitialized state and crashes the -- server's own OnUpdate handler. Only force-show a frame we've -- already seen the game display naturally at least once. frame:Show() end if frame.EnableMouse then frame:EnableMouse(not hide) end end end end HideCoA.ApplySetting = ApplySetting f:RegisterEvent("ADDON_LOADED") f:RegisterEvent("PLAYER_LOGIN") f:SetScript("OnEvent", function(self, event, arg1) if event == "ADDON_LOADED" and arg1 == "HideCoA" then if not HideCoADB then HideCoADB = {} end if not HideCoADB.profiles then HideCoADB.profiles = {} end if not HideCoADB.charProfile then HideCoADB.charProfile = {} end -- Legacy pre-profile saved variables stored a single flat classSettings -- table shared by every character. Fold it into "Default" so nobody's -- existing hide/show choices vanish when profiles were introduced. if HideCoADB.classSettings and not HideCoADB.profiles["Default"] then HideCoADB.profiles["Default"] = { classSettings = HideCoADB.classSettings } end HideCoADB.classSettings = nil if not HideCoADB.profiles["Default"] then HideCoADB.profiles["Default"] = { classSettings = CreateDefaultClassSettings() } end local charKey = GetCharacterKey() -- The profile-name syntax used to be "realm - character"; rename any -- existing profile created under that scheme to the new ordering -- instead of leaving it orphaned in the list. local oldCharKey = GetRealmName() .. " - " .. UnitName("player") if HideCoADB.profiles[oldCharKey] and not HideCoADB.profiles[charKey] then HideCoADB.profiles[charKey] = HideCoADB.profiles[oldCharKey] HideCoADB.profiles[oldCharKey] = nil end if not HideCoADB.profiles[charKey] then HideCoADB.profiles[charKey] = { classSettings = CreateDefaultClassSettings() } end for _, profile in pairs(HideCoADB.profiles) do if not profile.classSettings then profile.classSettings = CreateDefaultClassSettings() end EnsureClassSettingsComplete(profile.classSettings) end if not HideCoADB.charProfile[charKey] then HideCoADB.charProfile[charKey] = charKey end EnsureCharacterOverride(charKey) HideCoADB.selectedProfile = nil elseif event == "PLAYER_LOGIN" then ApplySetting() end end)