diff --git a/.vscode/settings.json b/.vscode/settings.json index f8670bd8..a14a9f0c 100755 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -49,6 +49,7 @@ "RegisterAttributeDriver", "FAILED", "INTERRUPTED", - "CellParent" + "CellParent", + "WOW_PROJECT_MISTS_CLASSIC" ] } \ No newline at end of file diff --git a/Cell_UnitFrames.toc b/Cell_UnitFrames.toc index af1d0867..3dd7bd73 100644 --- a/Cell_UnitFrames.toc +++ b/Cell_UnitFrames.toc @@ -9,6 +9,7 @@ ## X-License: MIT ## X-Curse-Project-ID: 1085605 ## X-Wago-ID: ZKxqRdGk +## X-Flavor: Mainline ## Dependencies: Cell @@ -50,39 +51,8 @@ Menu/AppearanceTab.lua Menu/ColorTab.lua Menu/VisibilityTab.lua -Widgets/Common.lua - -Widgets/Texts/BaseTextWidget.lua -Widgets/Texts/CustomFormats.lua -Widgets/Texts/NameText.lua -Widgets/Texts/HealthText.lua -Widgets/Texts/PowerText.lua -Widgets/Texts/LevelText.lua -Widgets/Texts/CustomText.lua - -Widgets/Bars/HealthBar.lua -Widgets/Bars/PowerBar.lua -Widgets/Bars/AltPowerBar.lua -Widgets/Bars/ShieldBar.lua -Widgets/Bars/CastBar.lua -Widgets/Bars/ClassBar.lua -Widgets/Bars/HealAbsorb.lua -Widgets/Bars/HealPrediction.lua - -Widgets/Icons/RaidIcon.lua -Widgets/Icons/RoleIcon.lua -Widgets/Icons/LeaderIcon.lua -Widgets/Icons/CombatIcon.lua -Widgets/Icons/ReadyCheckIcon.lua -Widgets/Icons/RestingIcon.lua - -Widgets/Auras/Auras.lua -Widgets/Auras/Updater.lua -Widgets/Auras/Dispels.lua -Widgets/Auras/Totems.lua - -Widgets/Misc/Fader.lua -Widgets/Misc/Highlight.lua +Widgets/LoadWidgets_Common.xml +Widgets/LoadWidgets_Retail.xml UnitFrames/UnitButton.xml UnitFrames/UnitButton.lua diff --git a/Cell_UnitFrames_Mists.toc b/Cell_UnitFrames_Mists.toc new file mode 100644 index 00000000..da44c212 --- /dev/null +++ b/Cell_UnitFrames_Mists.toc @@ -0,0 +1,66 @@ +## Interface: 50500 +## SavedVariables: CUF_DB +## IconTexture: Interface\ICONS\spell_progenitor_buff + +## Title: Cell - Unit Frames +## Author: Vollmer +## Version: @project-version@ +## X-Date: @project-date-iso@ +## X-License: MIT +## X-Curse-Project-ID: 1085605 +## X-Wago-ID: ZKxqRdGk +## X-Flavor: Mists + +## Dependencies: Cell + +## Notes: Unitframes for our beloved Cell! + +Locales/LoadLocales.xml +Core/Init.lua +Core/Events.lua + +Data/Constants.lua +Util/Utils.lua +Util/PixelPerfect.lua +Data/Defaults.lua +Data/Database.lua +Data/DBUtil.lua +Data/Revise.lua + +Util/Handler.lua +Util/HideBlizzard.lua +Util/HelpTips.lua +Util/Compat.lua + +Debug/DebugWindow.lua +Debug/Debug.lua + +Core/SlashCommands.lua + +Menu/Builder.lua +Menu/AuraFilterList.lua +Menu/Menu.lua +Menu/ImportExport.lua +Menu/GeneralTab.lua +Menu/UnitFramesTab.lua +Menu/WidgetsTab.lua +Menu/FaderTab.lua +Menu/AppearanceTab.lua +Menu/ColorTab.lua +Menu/VisibilityTab.lua + +Widgets/LoadWidgets_Common.xml +Widgets/LoadWidgets_Mist.xml + +UnitFrames/UnitButton.xml +UnitFrames/UnitButton.lua +UnitFrames/OnLoad.lua +UnitFrames/MenuOptions.lua +UnitFrames/EditMode.lua +UnitFrames/EventMixin.lua +UnitFrames/AurasMixin.lua + +API/Common.lua +API/CustomAnchors.lua + +Core/OnLoad.lua \ No newline at end of file diff --git a/Cell_UnitFrames_Vanilla.toc b/Cell_UnitFrames_Vanilla.toc new file mode 100644 index 00000000..344dbae7 --- /dev/null +++ b/Cell_UnitFrames_Vanilla.toc @@ -0,0 +1,65 @@ +## Interface: 11507 +## SavedVariables: CUF_DB +## IconTexture: Interface\ICONS\spell_progenitor_buff + +## Title: Cell - Unit Frames +## Author: Vollmer +## Version: @project-version@ +## X-Date: @project-date-iso@ +## X-License: MIT +## X-Curse-Project-ID: 1085605 +## X-Wago-ID: ZKxqRdGk +## X-Flavor: Vanilla + +## Dependencies: Cell + +## Notes: Unitframes for our beloved Cell! + +Locales/LoadLocales.xml +Core/Init.lua +Core/Events.lua + +Data/Constants.lua +Util/Utils.lua +Util/PixelPerfect.lua +Data/Defaults.lua +Data/Database.lua +Data/DBUtil.lua +Data/Revise.lua + +Util/Handler.lua +Util/HideBlizzard.lua +Util/HelpTips.lua +Util/Compat.lua + +Debug/DebugWindow.lua +Debug/Debug.lua + +Core/SlashCommands.lua + +Menu/Builder.lua +Menu/AuraFilterList.lua +Menu/Menu.lua +Menu/ImportExport.lua +Menu/GeneralTab.lua +Menu/UnitFramesTab.lua +Menu/WidgetsTab.lua +Menu/FaderTab.lua +Menu/AppearanceTab.lua +Menu/ColorTab.lua +Menu/VisibilityTab.lua + +Widgets/LoadWidgets_Common.xml + +UnitFrames/UnitButton.xml +UnitFrames/UnitButton.lua +UnitFrames/OnLoad.lua +UnitFrames/MenuOptions.lua +UnitFrames/EditMode.lua +UnitFrames/EventMixin.lua +UnitFrames/AurasMixin.lua + +API/Common.lua +API/CustomAnchors.lua + +Core/OnLoad.lua \ No newline at end of file diff --git a/Core/Init.lua b/Core/Init.lua index ce33a19b..5be07b7f 100644 --- a/Core/Init.lua +++ b/Core/Init.lua @@ -49,3 +49,12 @@ CUF.vars = {} ---@field [Unit] CUFUnitButton ---@field boss table CUF.unitButtons = {} + +-- Borrowed from DBM: https://github.com/DeadlyBossMods/DeadlyBossMods/blob/171258b10cd053a3fbb34f5f9fe93a238f4cfaad/DBM-Core/modules/objects/GameVersion.lua +CUF.vars.wowTOC = (select(4, GetBuildInfo())) +CUF.vars.isRetail = WOW_PROJECT_ID == (WOW_PROJECT_MAINLINE or 1) +CUF.vars.isVanilla = WOW_PROJECT_ID == (WOW_PROJECT_CLASSIC or 2) +CUF.vars.isBCC = WOW_PROJECT_ID == (WOW_PROJECT_BURNING_CRUSADE_CLASSIC or 5) +CUF.vars.isWrath = WOW_PROJECT_ID == (WOW_PROJECT_WRATH_CLASSIC or 11) +CUF.vars.isCata = WOW_PROJECT_ID == (WOW_PROJECT_CATACLYSM_CLASSIC or 14) +CUF.vars.isMop = WOW_PROJECT_ID == (WOW_PROJECT_MISTS_CLASSIC or 19) diff --git a/Core/OnLoad.lua b/Core/OnLoad.lua index 011d3a3f..8ddbf2bd 100644 --- a/Core/OnLoad.lua +++ b/Core/OnLoad.lua @@ -29,12 +29,14 @@ local function OnCellInitialUpdateLayout(_layout) -- TODO: This is kinda non-ideal and should be looked into -- Mixin in some extra bleeds/enrages -- These values can be overwritten by the user via snippets - local LibDispel = LibStub("LibDispel") - if Cell.vars.bleedList then - Mixin(LibDispel.bleed, Cell.vars.bleedList) + local LibDispel = LibStub("LibDispel", true) + if LibDispel then + if Cell.vars.bleedList then + Mixin(LibDispel.bleed, Cell.vars.bleedList) + end + Mixin(LibDispel.bleed, CUF.Defaults.Values.extraBleeds) + Mixin(LibDispel.enrage, CUF.Defaults.Values.extraEnrages) end - Mixin(LibDispel.bleed, CUF.Defaults.Values.extraBleeds) - Mixin(LibDispel.enrage, CUF.Defaults.Values.extraEnrages) -- Init Unit Buttons CUF.uFuncs:InitUnitButtons() diff --git a/Data/Constants.lua b/Data/Constants.lua index 512cb05f..ffda4541 100644 --- a/Data/Constants.lua +++ b/Data/Constants.lua @@ -25,6 +25,13 @@ const.UNIT = { BOSS = "boss", } +if CUF.vars.isVanilla then + const.UNIT.FOCUS = nil +end +if CUF.vars.isVanilla or CUF.vars.isBCC then + const.UNIT.BOSS = nil +end + ---@enum TitleCasedUnits -- Used for frame titles const.TITLE_CASED_UNITS = { @@ -87,6 +94,14 @@ const.HealthTextFormat = { CUSTOM = "custom", } +---@type table +const.ValidHealthTextFormats = {} +for _, format in pairs(const.HealthTextFormat) do + -- There is no absorbs API in Vanilla + local isValidFormat = (not CUF.vars.isVanilla) or (not string.match(format, "absorbs")) + const.ValidHealthTextFormats[format] = isValidFormat +end + ---@enum WIDGET_KIND const.WIDGET_KIND = { NAME_TEXT = "nameText", diff --git a/Data/DBUtil.lua b/Data/DBUtil.lua index 02b7516b..c36d4f60 100644 --- a/Data/DBUtil.lua +++ b/Data/DBUtil.lua @@ -223,6 +223,10 @@ function DB.VerifyDB() layoutTable.CUFUnits[unit] = Util:CopyDeep(unitLayout) else Util:AddMissingProps(layoutTable.CUFUnits[unit], unitLayout, DB.PropsToOnlyInit) + + if not CUF.constants.ValidHealthTextFormats[layoutTable.CUFUnits[unit].widgets.healthText.format] then + layoutTable.CUFUnits[unit].widgets.healthText.format = CUF.constants.HealthTextFormat.PERCENTAGE + end end end end diff --git a/Data/Defaults.lua b/Data/Defaults.lua index e5575e10..df8206d2 100644 --- a/Data/Defaults.lua +++ b/Data/Defaults.lua @@ -258,19 +258,21 @@ Defaults.Colors = { }, } +local isRetail = CUF.vars.isRetail +local isVanilla = CUF.vars.isVanilla Defaults.ColorsMenuOrder = { castBar = { { "texture", "texture" }, { "background", "rgb" }, { "interruptible", "rgb" }, { "nonInterruptible", "rgb" }, - { "Empowers", "separator" }, - { "stageZero", "rgb" }, - { "stageOne", "rgb" }, - { "stageTwo", "rgb" }, - { "stageThree", "rgb" }, - { "stageFour", "rgb" }, - { "fullyCharged", "rgb" } + { "Empowers", "separator", isRetail }, + { "stageZero", "rgb", isRetail }, + { "stageOne", "rgb", isRetail }, + { "stageTwo", "rgb", isRetail }, + { "stageThree", "rgb", isRetail }, + { "stageFour", "rgb", isRetail }, + { "fullyCharged", "rgb", isRetail } }, reaction = { { "friendly", "rgb" }, @@ -282,17 +284,17 @@ Defaults.ColorsMenuOrder = { { "swapHostileHealthAndLossColors", "toggle" } }, essence = { - { "1", "rgb" }, - { "2", "rgb" }, - { "3", "rgb" }, - { "4", "rgb" }, - { "5", "rgb" }, - { "6", "rgb" }, + { "1", "rgb", isRetail }, + { "2", "rgb", isRetail }, + { "3", "rgb", isRetail }, + { "4", "rgb", isRetail }, + { "5", "rgb", isRetail }, + { "6", "rgb", isRetail }, }, classResources = { - { "holyPower", "rgb" }, - { "soulShards", "rgb" }, - { "arcaneCharges", "rgb" }, + { "holyPower", "rgb", isRetail }, + { "soulShards", "rgb", isRetail }, + { "arcaneCharges", "rgb", isRetail }, }, comboPoints = { { "1", "rgb" }, @@ -302,46 +304,46 @@ Defaults.ColorsMenuOrder = { { "5", "rgb" }, { "6", "rgb" }, { "7", "rgb" }, - { "charged", "rgb" }, + { "charged", "rgb", isRetail }, }, chi = { - { "1", "rgb" }, - { "2", "rgb" }, - { "3", "rgb" }, - { "4", "rgb" }, - { "5", "rgb" }, - { "6", "rgb" }, + { "1", "rgb", not isVanilla }, + { "2", "rgb", not isVanilla }, + { "3", "rgb", not isVanilla }, + { "4", "rgb", not isVanilla }, + { "5", "rgb", not isVanilla }, + { "6", "rgb", not isVanilla }, }, runes = { - { "bloodRune", "rgb" }, - { "frostRune", "rgb" }, - { "unholyRune", "rgb" }, + { "bloodRune", "rgb", not isVanilla }, + { "frostRune", "rgb", not isVanilla }, + { "unholyRune", "rgb", not isVanilla }, }, shieldBar = { - { "shieldTexture", "texture" }, - { "overshieldTexture", "texture" }, - { "overlayTexture", "texture" }, - { "shieldColor", "rgb" }, - { "overshieldColor", "rgb" }, - { "", "newline" }, - { "overlayColor", "rgb" }, - { "useOverlay", "toggle" }, - { "overshieldOffset", "slider" }, - { "overshieldReverseOffset", "slider" }, - { "overshieldSize", "slider" }, + { "shieldTexture", "texture", not isVanilla }, + { "overshieldTexture", "texture", not isVanilla }, + { "overlayTexture", "texture", not isVanilla }, + { "shieldColor", "rgb", not isVanilla }, + { "overshieldColor", "rgb", not isVanilla }, + { "", "newline", not isVanilla }, + { "overlayColor", "rgb", not isVanilla }, + { "useOverlay", "toggle", not isVanilla }, + { "overshieldOffset", "slider", not isVanilla }, + { "overshieldReverseOffset", "slider", not isVanilla }, + { "overshieldSize", "slider", not isVanilla }, }, healPrediction = { - { "texture", "texture" }, - { "color", "rgb" }, - { "overHeal", "rgb" }, + { "texture", "texture", not isVanilla }, + { "color", "rgb", not isVanilla }, + { "overHeal", "rgb", not isVanilla }, }, healAbsorb = { - { "absorbTexture", "texture" }, - { "overabsorbTexture", "texture" }, - { "absorbColor", "rgb" }, - { "overabsorbColor", "rgb" }, - { "", "newline" }, - { "invertColor", "toggle" }, + { "absorbTexture", "texture", not isVanilla }, + { "overabsorbTexture", "texture", not isVanilla }, + { "absorbColor", "rgb", not isVanilla }, + { "overabsorbColor", "rgb", not isVanilla }, + { "", "newline", not isVanilla }, + { "invertColor", "toggle", not isVanilla }, }, unitFrames = { { "barColor", "rgb" }, @@ -360,7 +362,7 @@ Defaults.ColorsMenuOrder = { { "powerLossAlpha", "slider-percent" }, }, classBar = { - { "texture", "texture" }, + { "texture", "texture", isRetail }, }, highlight = { { "target", "rgb" }, @@ -368,6 +370,17 @@ Defaults.ColorsMenuOrder = { } } +for section, rows in pairs(Defaults.ColorsMenuOrder) do + local filtered = {} + for _, row in ipairs(rows) do + local condition = row[3] + if condition == nil or condition then + table.insert(filtered, row) + end + end + Defaults.ColorsMenuOrder[section] = filtered +end + ---@class Defaults.BlizzardFrames Defaults.BlizzardFrames = {} for _, unit in pairs(CUF.constants.BlizzardFrameTypes) do @@ -421,7 +434,7 @@ Defaults.Widgets = { enabled = true, font = Defaults.Options.smallFontOpt, color = Defaults.Options.colorOpt, - format = "percentage", + format = CUF.constants.HealthTextFormat.PERCENTAGE, textFormat = "", hideIfFull = false, hideIfEmpty = false, @@ -439,7 +452,7 @@ Defaults.Widgets = { enabled = true, font = Defaults.Options.smallFontOpt, color = Defaults.Options.colorOpt, - format = "percentage", + format = CUF.constants.PowerTextFormat.PERCENTAGE, hideIfEmptyOrFull = false, anchorToPowerBar = false, powerFilter = false, diff --git a/Menu/Builder.lua b/Menu/Builder.lua index 7c8db039..8bf03d4e 100644 --- a/Menu/Builder.lua +++ b/Menu/Builder.lua @@ -905,13 +905,20 @@ function Builder:CreateHealthFormatOptions(parent, widgetName) { L["Custom"], const.HealthTextFormat.CUSTOM } } + local filteredHealthFormats = {} + for _, format in ipairs(healthFormats) do + if const.ValidHealthTextFormats[format[2]] then + table.insert(filteredHealthFormats, format) + end + end + ---@class HealthFormatOptions: OptionsFrame local f = CUF:CreateFrame(nil, parent, 1, 1, true, true) f.optionHeight = 120 f.id = "HealthFormatOptions" f.formatDropdown = self:CreateDropdown(parent, widgetName, "Format", 200, - healthFormats, const.OPTION_KIND.FORMAT) + filteredHealthFormats, const.OPTION_KIND.FORMAT) f.formatDropdown:SetPoint("TOPLEFT", f) f.formatEditBox = self:CreateEditBox(parent, widgetName, L["Text Format"], 300, const.OPTION_KIND.TEXT_FORMAT) @@ -1576,7 +1583,7 @@ function Builder:CreateAuraFilterOptions(parent, widgetName) L.WhiteListPriorityTooltip) self:AnchorBelowCB(f.whiteListPriority, f.useBlacklistCB) - if widgetName == const.WIDGET_KIND.BUFFS then + if widgetName == const.WIDGET_KIND.BUFFS and CUF.vars.isRetail then f.tempEnchant = self:CreateCheckBox(f, widgetName, L.tempEnchant, const.AURA_OPTION_KIND.FILTER .. "." .. const.AURA_OPTION_KIND.TEMP_ENCHANT, L.tempEnchantTooltip) diff --git a/Menu/ColorTab.lua b/Menu/ColorTab.lua index 7a0e4d96..2cea7fc5 100644 --- a/Menu/ColorTab.lua +++ b/Menu/ColorTab.lua @@ -228,143 +228,147 @@ function ColorTab:CreateSections() local colorOrder = CUF.Defaults.ColorsMenuOrder for which, order in pairs(colorOrder) do - ---@class CUF.ColorSection: Frame - local section = CUF:CreateFrame(colorSection:GetName() .. "_" .. Util:ToTitleCase(which), - colorSection.scrollFrame.content, self.window:GetWidth() - 10, 1, false, true) - section.id = which - section.cps = {} ---@type (CUF.ColorSection.ColorPicker|CUF.ColorSection.Checkbox)[] - section.dropdowns = {} ---@type CUF.ColorSection.Dropdown[] - section.sliders = {} ---@type CUF.ColorSection.Slider[] - - local sectionTitle = CUF:CreateFrame(nil, section, 1, 1, true, true) --[[@as OptionTitle]] - sectionTitle:SetPoint("TOPLEFT", sectionGap, -sectionGap) - sectionTitle.title = sectionTitle:CreateFontString(nil, "OVERLAY", "CELL_FONT_CLASS_TITLE") - sectionTitle.title:SetText(L[which]) - sectionTitle.title:SetScale(1.2) - sectionTitle.title:SetPoint("TOPLEFT") - sectionTitle:SetHeight(sectionTitle.title:GetStringHeight()) - - local gridLayout = { - maxColumns = 3, - currentRow = 1, - currentColumn = 1, - currentColumnWidth = sectionGap * 2, - firstInRow = nil - } - local baseHeight = 35 - - ---@type table - local colorTable = colorTables[which] - for _, info in ipairs(order) do - local colorName, colorType = info[1], info[2] - local element, elementWidth - - if colorType == "separator" then - element = CreateSeparatorTitle(colorName, section) - gridLayout.currentColumn = 1 - gridLayout.currentColumnWidth = section:GetWidth() - gridLayout.currentRow = gridLayout.currentRow + 1 - - element:SetPoint("TOPLEFT", gridLayout.firstInRow, "BOTTOMLEFT", 0, -sectionGap) - gridLayout.firstInRow = element - baseHeight = baseHeight + element:GetHeight() + sectionGap - elseif colorType == "newline" then - gridLayout.currentColumn = 0 - gridLayout.currentRow = gridLayout.currentRow + 1 - gridLayout.currentColumnWidth = 0 - elseif colorType == "texture" then - element = CreateTextureDropdown(which, colorName, colorTable, section) - gridLayout.currentColumn = 1 - gridLayout.currentColumnWidth = section:GetWidth() - - if gridLayout.currentRow > 1 then + -- Oh how I wish for a continue + if #order > 0 then + ---@class CUF.ColorSection: Frame + local section = CUF:CreateFrame(colorSection:GetName() .. "_" .. Util:ToTitleCase(which), + colorSection.scrollFrame.content, self.window:GetWidth() - 10, 1, false, true) + section.id = which + section.cps = {} ---@type (CUF.ColorSection.ColorPicker|CUF.ColorSection.Checkbox)[] + section.dropdowns = {} ---@type CUF.ColorSection.Dropdown[] + section.sliders = {} ---@type CUF.ColorSection.Slider[] + + local sectionTitle = CUF:CreateFrame(nil, section, 1, 1, true, true) --[[@as OptionTitle]] + sectionTitle:SetPoint("TOPLEFT", sectionGap, -sectionGap) + sectionTitle.title = sectionTitle:CreateFontString(nil, "OVERLAY", "CELL_FONT_CLASS_TITLE") + sectionTitle.title:SetText(L[which]) + sectionTitle.title:SetScale(1.2) + sectionTitle.title:SetPoint("TOPLEFT") + sectionTitle:SetHeight(sectionTitle.title:GetStringHeight()) + + + local gridLayout = { + maxColumns = 3, + currentRow = 1, + currentColumn = 1, + currentColumnWidth = sectionGap * 2, + firstInRow = nil + } + local baseHeight = 35 + + ---@type table + local colorTable = colorTables[which] + for _, info in ipairs(order) do + local colorName, colorType = info[1], info[2] + local element, elementWidth + + if colorType == "separator" then + element = CreateSeparatorTitle(colorName, section) + gridLayout.currentColumn = 1 + gridLayout.currentColumnWidth = section:GetWidth() gridLayout.currentRow = gridLayout.currentRow + 1 - end - - -- Start of a new row - if not gridLayout.firstInRow then - element:SetPoint("TOPLEFT", sectionTitle, "BOTTOMLEFT", 0, -sectionGap * 2.5) - else - element:SetPoint("TOPLEFT", gridLayout.firstInRow, "BOTTOMLEFT", 0, -sectionGap * 2.5) - end - gridLayout.firstInRow = element - - baseHeight = baseHeight + element:GetHeight() + sectionGap * 2.5 - table.insert(section.dropdowns, element) - elseif colorType:match("slider") then - element = CreateSlider(which, colorName, colorTable, section, colorType:match("percent")) - gridLayout.currentColumn = 1 - gridLayout.currentColumnWidth = section:GetWidth() - - if gridLayout.currentRow > 1 then + element:SetPoint("TOPLEFT", gridLayout.firstInRow, "BOTTOMLEFT", 0, -sectionGap) + gridLayout.firstInRow = element + baseHeight = baseHeight + element:GetHeight() + sectionGap + elseif colorType == "newline" then + gridLayout.currentColumn = 0 gridLayout.currentRow = gridLayout.currentRow + 1 - end + gridLayout.currentColumnWidth = 0 + elseif colorType == "texture" then + element = CreateTextureDropdown(which, colorName, colorTable, section) + gridLayout.currentColumn = 1 + gridLayout.currentColumnWidth = section:GetWidth() - -- Start of a new row - if not gridLayout.firstInRow then - element:SetPoint("TOPLEFT", sectionTitle, "BOTTOMLEFT", 0, -sectionGap * 2.5) - baseHeight = baseHeight + element:GetHeight() + sectionGap * 3 - else - if gridLayout.firstInRow.type == "slider" then - element:SetPoint("TOPLEFT", gridLayout.firstInRow, "BOTTOMLEFT", 0, -sectionGap * 4.5) - baseHeight = baseHeight + element:GetHeight() * 3 + sectionGap * 3 + if gridLayout.currentRow > 1 then + gridLayout.currentRow = gridLayout.currentRow + 1 + end + + -- Start of a new row + if not gridLayout.firstInRow then + element:SetPoint("TOPLEFT", sectionTitle, "BOTTOMLEFT", 0, -sectionGap * 2.5) else element:SetPoint("TOPLEFT", gridLayout.firstInRow, "BOTTOMLEFT", 0, -sectionGap * 2.5) - baseHeight = baseHeight + element:GetHeight() + sectionGap * 3 end - end - gridLayout.firstInRow = element - - table.insert(section.sliders, element) - elseif colorType == "rgb" or colorType == "toggle" then - if colorType == "toggle" then - element, elementWidth = CreateCheckbox(which, colorName, colorTable, section) - else - element, elementWidth = CreateColorPicker(which, colorName, colorTable, section) - end + gridLayout.firstInRow = element + + baseHeight = baseHeight + element:GetHeight() + sectionGap * 2.5 - -- Move to the next column, or wrap to the next row if necessary - if gridLayout.currentColumn > gridLayout.maxColumns - or (gridLayout.currentColumnWidth + elementWidth) > (section:GetWidth()) then + table.insert(section.dropdowns, element) + elseif colorType:match("slider") then + element = CreateSlider(which, colorName, colorTable, section, colorType:match("percent")) gridLayout.currentColumn = 1 - gridLayout.currentRow = gridLayout.currentRow + 1 - gridLayout.currentColumnWidth = sectionGap * 2 - end + gridLayout.currentColumnWidth = section:GetWidth() - gridLayout.currentColumnWidth = gridLayout.currentColumnWidth + elementWidth - table.insert(section.cps, element) + if gridLayout.currentRow > 1 then + gridLayout.currentRow = gridLayout.currentRow + 1 + end - -- Position the element in the grid - if gridLayout.currentColumn == 1 then -- Start of a new row if not gridLayout.firstInRow then - element:SetPoint("TOPLEFT", sectionTitle, "BOTTOMLEFT", 0, -sectionGap) + element:SetPoint("TOPLEFT", sectionTitle, "BOTTOMLEFT", 0, -sectionGap * 2.5) + baseHeight = baseHeight + element:GetHeight() + sectionGap * 3 else - element:SetPoint("TOPLEFT", gridLayout.firstInRow, "BOTTOMLEFT", 0, -sectionGap) + if gridLayout.firstInRow.type == "slider" then + element:SetPoint("TOPLEFT", gridLayout.firstInRow, "BOTTOMLEFT", 0, -sectionGap * 4.5) + baseHeight = baseHeight + element:GetHeight() * 3 + sectionGap * 3 + else + element:SetPoint("TOPLEFT", gridLayout.firstInRow, "BOTTOMLEFT", 0, -sectionGap * 2.5) + baseHeight = baseHeight + element:GetHeight() + sectionGap * 3 + end end gridLayout.firstInRow = element - baseHeight = baseHeight + element:GetHeight() + sectionGap - else - -- Position to the right of the previous element - element:SetPoint("TOPLEFT", section.cps[#section.cps - 1], "TOPRIGHT", cpGap, 0) + + table.insert(section.sliders, element) + elseif colorType == "rgb" or colorType == "toggle" then + if colorType == "toggle" then + element, elementWidth = CreateCheckbox(which, colorName, colorTable, section) + else + element, elementWidth = CreateColorPicker(which, colorName, colorTable, section) + end + + -- Move to the next column, or wrap to the next row if necessary + if gridLayout.currentColumn > gridLayout.maxColumns + or (gridLayout.currentColumnWidth + elementWidth) > (section:GetWidth()) then + gridLayout.currentColumn = 1 + gridLayout.currentRow = gridLayout.currentRow + 1 + gridLayout.currentColumnWidth = sectionGap * 2 + end + + gridLayout.currentColumnWidth = gridLayout.currentColumnWidth + elementWidth + table.insert(section.cps, element) + + -- Position the element in the grid + if gridLayout.currentColumn == 1 then + -- Start of a new row + if not gridLayout.firstInRow then + element:SetPoint("TOPLEFT", sectionTitle, "BOTTOMLEFT", 0, -sectionGap) + else + element:SetPoint("TOPLEFT", gridLayout.firstInRow, "BOTTOMLEFT", 0, -sectionGap) + end + gridLayout.firstInRow = element + baseHeight = baseHeight + element:GetHeight() + sectionGap + else + -- Position to the right of the previous element + element:SetPoint("TOPLEFT", section.cps[#section.cps - 1], "TOPRIGHT", cpGap, 0) + end end + + gridLayout.currentColumn = gridLayout.currentColumn + 1 end - gridLayout.currentColumn = gridLayout.currentColumn + 1 - end + section:SetHeight(baseHeight) + self.sectionsHeight = self.sectionsHeight + baseHeight + sectionGap - section:SetHeight(baseHeight) - self.sectionsHeight = self.sectionsHeight + baseHeight + sectionGap + if not prevSection then + section:SetPoint("TOPLEFT", colorSection.scrollFrame.content) + else + section:SetPoint("TOPLEFT", prevSection, "BOTTOMLEFT", 0, -sectionGap) + end - if not prevSection then - section:SetPoint("TOPLEFT", colorSection.scrollFrame.content) - else - section:SetPoint("TOPLEFT", prevSection, "BOTTOMLEFT", 0, -sectionGap) + prevSection = section + table.insert(self.colorSections, section) end - - prevSection = section - table.insert(self.colorSections, section) end self.colorSection = colorSection diff --git a/Menu/UnitFramesTab.lua b/Menu/UnitFramesTab.lua index b858a65e..848cc415 100644 --- a/Menu/UnitFramesTab.lua +++ b/Menu/UnitFramesTab.lua @@ -94,6 +94,7 @@ function unitFramesTab:InitUnits() local prevButton local prevAnchor local idx = 1 + local rows = 1 for _, fn in pairs(self.unitsToAdd) do ---@type UnitsMenuPage @@ -104,6 +105,7 @@ function unitFramesTab:InitUnits() if prevButton then -- Max 4 buttons per row if idx % 4 == 0 then + rows = rows + 1 unit.pageButton:SetPoint("BOTTOMLEFT", prevAnchor, "TOPLEFT", 0, 0) idx = 1 prevAnchor = unit.pageButton @@ -122,6 +124,12 @@ function unitFramesTab:InitUnits() table.insert(self.unitPageButtons, unit.pageButton) end + + -- Prevent the edit mode button from colliding with the unitPane CreateTitledPane + if rows == 1 then + self.window:SetHeight(self.window:GetHeight() + self.paneHeight) + self.unitPane:SetHeight(self.unitPane:GetHeight() + self.paneHeight) + end end ---@param unit function diff --git a/UnitFrames/AurasMixin.lua b/UnitFrames/AurasMixin.lua index 4753a580..d7a27d67 100644 --- a/UnitFrames/AurasMixin.lua +++ b/UnitFrames/AurasMixin.lua @@ -1,7 +1,7 @@ ---@class CUF local CUF = select(2, ...) -local LibDispel = LibStub("LibDispel") +local LibDispel = LibStub("LibDispel", true) ---@class CUF.Mixin local Mixin = CUF.Mixin @@ -9,9 +9,101 @@ local Mixin = CUF.Mixin local const = CUF.constants local GetAuraDataByAuraInstanceID = C_UnitAuras.GetAuraDataByAuraInstanceID -local ForEachAura = AuraUtil.ForEachAura local wipe = table.wipe +local AuraUpdateChangedType = AuraUtil.AuraUpdateChangedType or { + None = 1, + Debuff = 2, + Buff = 3, + Dispel = 4 +} + +local AuraFilters = AuraUtil.AuraFilters or { + Helpful = "HELPFUL", + Harmful = "HARMFUL", + Raid = "RAID", + IncludeNameplateOnly = "INCLUDE_NAME_PLATE_ONLY", + Player = "PLAYER", + Cancelable = "CANCELABLE", + NotCancelable = "NOT_CANCELABLE", + Maw = "MAW", +} + +local ForEachAura = AuraUtil.ForEachAura +-- One to one copy of AuraUtil.ForEachAura, since it's only available for Retail flavors +if not ForEachAura then + ---@param auraData AuraData + function UnpackAuraData(auraData) + if not auraData then + return nil + end + + return auraData.name, + auraData.icon, + auraData.applications, + auraData.dispelName, + auraData.duration, + auraData.expirationTime, + auraData.sourceUnit, + auraData.isStealable, + auraData.nameplateShowPersonal, + auraData.spellId, + auraData.canApplyAura, + auraData.isBossAura, + auraData.isFromPlayerOrPlayerPet, + auraData.nameplateShowAll, + auraData.timeMod, + unpack(auraData.points) + end + + ---@param unit string + ---@param filter AuraUtil.AuraFilters + ---@param func function + ---@param usePackedAura boolean + ---@param continuationToken number? + ---@return number? continuationToken + local function ForEachAuraHelper(unit, filter, func, usePackedAura, continuationToken, ...) + -- continuationToken is the first return value of UnitAuraSlots() + local n = select('#', ...) + for i = 1, n do + local slot = select(i, ...) + local done + local auraInfo = C_UnitAuras.GetAuraDataBySlot(unit, slot) + + -- Protect against GetAuraDataBySlot desyncing with GetAuraSlots + if auraInfo then + if usePackedAura then + done = func(auraInfo) + else + done = func(UnpackAuraData(auraInfo)) + end + end + if done then + -- if func returns true then no further slots are needed, so don't return continuationToken + return nil + end + end + return continuationToken + end + + ---@param unit string + ---@param filter AuraUtil.AuraFilters + ---@param maxCount number? + ---@param func function + ---@param usePackedAura boolean + ForEachAura = function(unit, filter, maxCount, func, usePackedAura) + if maxCount and maxCount <= 0 then + return + end + local continuationToken + repeat + -- continuationToken is the first return value of UnitAuraSlots + continuationToken = ForEachAuraHelper(unit, filter, func, usePackedAura, + C_UnitAuras.GetAuraSlots(unit, filter, maxCount, continuationToken)) + until continuationToken == nil + end +end + ---@class CUFUnitButton local AurasMixin = {} Mixin.AurasMixin = AurasMixin @@ -24,11 +116,44 @@ AurasMixin._auraDebuffCallbacks = {} AurasMixin._ignoreBuffs = true AurasMixin._ignoreDebuffs = true ----@param dispelName string? ----@param spellID number ----@return string -local function CheckDebuffType(dispelName, spellID) - return LibDispel:GetDispelType(spellID, dispelName) +local CheckDebuffType, IsDispellable + +do + if LibDispel then + ---@param dispelName string? + ---@param spellID number + ---@return string + CheckDebuffType = function(dispelName, spellID) + return LibDispel:GetDispelType(spellID, dispelName) + end + + ---@param unit UnitToken + ---@param spellID number + ---@param dispelName string? + ---@param isHarmful boolean + ---@return boolean + IsDispellable = function(unit, spellID, dispelName, isHarmful) + return LibDispel:IsDispelable(unit, spellID, dispelName, isHarmful) + end + else + local I = Cell.iFuncs + + ---@param dispelName string? + ---@param spellID number + ---@return string + CheckDebuffType = function(dispelName, spellID) + return I.CheckDebuffType(dispelName, spellID) + end + + ---@param unit UnitToken + ---@param spellID number + ---@param dispelName string? + ---@param isHarmful boolean + ---@return boolean + IsDispellable = function(unit, spellID, dispelName, isHarmful) + return I.CanDispel(dispelName) + end + end end function AurasMixin:ResetAuraTables() @@ -49,30 +174,30 @@ end ---@return AuraUtil.AuraUpdateChangedType local function ProcessAura(aura, ignoreBuffs, ignoreDebuffs, unit) if aura == nil then - return AuraUtil.AuraUpdateChangedType.None; + return AuraUpdateChangedType.None end if aura.isNameplateOnly then - return AuraUtil.AuraUpdateChangedType.None; + return AuraUpdateChangedType.None end if aura.isHarmful and not ignoreDebuffs then aura.dispelName = CheckDebuffType(aura.dispelName, aura.spellId) - aura.isDispellable = LibDispel:IsDispelable(unit, aura.spellId, aura.dispelName, true) + aura.isDispellable = IsDispellable(unit, aura.spellId, aura.dispelName, true) if aura.dispelName ~= "" and aura.dispelName ~= "none" then - return AuraUtil.AuraUpdateChangedType.Dispel + return AuraUpdateChangedType.Dispel end - return AuraUtil.AuraUpdateChangedType.Debuff + return AuraUpdateChangedType.Debuff elseif aura.isHelpful and not ignoreBuffs then aura.dispelName = CheckDebuffType(aura.dispelName, aura.spellId) - aura.isDispellable = LibDispel:IsDispelable(unit, aura.spellId, aura.dispelName, false) + aura.isDispellable = IsDispellable(unit, aura.spellId, aura.dispelName, false) - return AuraUtil.AuraUpdateChangedType.Buff + return AuraUpdateChangedType.Buff end - return AuraUtil.AuraUpdateChangedType.None; + return AuraUpdateChangedType.None end --- Perform a full aura update for a unit @@ -88,20 +213,20 @@ function AurasMixin:ParseAllAuras(ignoreBuffs, ignoreDebuffs, unit) ---@param aura AuraData local function HandleAura(aura) local type = ProcessAura(aura, ignoreBuffs, ignoreDebuffs, unit) - if type == AuraUtil.AuraUpdateChangedType.Debuff or type == AuraUtil.AuraUpdateChangedType.Dispel then + if type == AuraUpdateChangedType.Debuff or type == AuraUpdateChangedType.Dispel then self._auraDebuffCache[aura.auraInstanceID] = aura - elseif type == AuraUtil.AuraUpdateChangedType.Buff then + elseif type == AuraUpdateChangedType.Buff then self._auraBuffCache[aura.auraInstanceID] = aura end end if not ignoreDebuffs then - ForEachAura(self.states.unit, AuraUtil.AuraFilters.Harmful, batchCount, + ForEachAura(self.states.unit, AuraFilters.Harmful, batchCount, HandleAura, usePackedAura) end if not ignoreBuffs then - ForEachAura(self.states.unit, AuraUtil.AuraFilters.Helpful, batchCount, + ForEachAura(self.states.unit, AuraFilters.Helpful, batchCount, HandleAura, usePackedAura) end @@ -136,11 +261,11 @@ function AurasMixin:UpdateAurasInternal(event, unit, unitAuraUpdateInfo) for _, aura in ipairs(unitAuraUpdateInfo.addedAuras) do local type = ProcessAura(aura, self._ignoreBuffs, self._ignoreDebuffs, unit) - if type == AuraUtil.AuraUpdateChangedType.Debuff or type == AuraUtil.AuraUpdateChangedType.Dispel then + if type == AuraUpdateChangedType.Debuff or type == AuraUpdateChangedType.Dispel then self._auraDebuffCache[aura.auraInstanceID] = aura debuffsChanged = true - dispelsChanged = dispelsChanged or type == AuraUtil.AuraUpdateChangedType.Dispel - elseif type == AuraUtil.AuraUpdateChangedType.Buff then + dispelsChanged = dispelsChanged or type == AuraUpdateChangedType.Dispel + elseif type == AuraUpdateChangedType.Buff then self._auraBuffCache[aura.auraInstanceID] = aura buffsChanged = true stealableChanged = stealableChanged or aura.isDispellable diff --git a/UnitFrames/EditMode.lua b/UnitFrames/EditMode.lua index 9c0eb4d9..94c3b0c9 100644 --- a/UnitFrames/EditMode.lua +++ b/UnitFrames/EditMode.lua @@ -436,14 +436,6 @@ end ---@type table local overlays = {} -local colors = { - [const.UNIT.PLAYER] = { 1, 0, 0 }, - [const.UNIT.TARGET] = { 1, 0.5, 0 }, - [const.UNIT.TARGET_TARGET] = { 1, 1, 0 }, - [const.UNIT.FOCUS] = { 0, 1, 0 }, - [const.UNIT.PET] = { 0, 0.5, 1 }, -} - ---@param widget Widget ---@param unit Unit ---@param unitOverlay CUFOverlayBox diff --git a/UnitFrames/OnLoad.lua b/UnitFrames/OnLoad.lua index ff2a0c73..197882bf 100644 --- a/UnitFrames/OnLoad.lua +++ b/UnitFrames/OnLoad.lua @@ -313,12 +313,14 @@ function CUFUnitButton_OnLoad(button) button.healthBarColorType = const.UnitButtonColorType.CELL button.healthLossColorType = const.UnitButtonColorType.CELL - -- ping system - Mixin(button, PingableType_UnitFrameMixin) - button:SetAttribute("ping-receiver", true) + if CUF.vars.isRetail then + -- ping system + Mixin(button, PingableType_UnitFrameMixin) + button:SetAttribute("ping-receiver", true) - function button:GetTargetPingGUID() - return button.__unitGuid + function button:GetTargetPingGUID() + return button.__unitGuid + end end ---@param widget WIDGET_KIND diff --git a/Util/HelpTips.lua b/Util/HelpTips.lua index 665a4bd6..2551cdc1 100644 --- a/Util/HelpTips.lua +++ b/Util/HelpTips.lua @@ -7,6 +7,14 @@ local DB = CUF.DB local HelpTips = {} CUF.HelpTips = HelpTips +if not CUF.vars.isRetail then + function HelpTips:Show() end + + function HelpTips:Acknowledge() end + + return +end + local function HelpTipReset(framePool, frame) frame:ClearAllPoints() frame:Hide() diff --git a/Util/HideBlizzard.lua b/Util/HideBlizzard.lua index 481a9809..2e564357 100644 --- a/Util/HideBlizzard.lua +++ b/Util/HideBlizzard.lua @@ -68,15 +68,17 @@ function CUF:HideBlizzardUnitFrame(type) if type == "player" and _G.PlayerFrame then HideFrame(_G.PlayerFrame) elseif type == "playerCastBar" then - if _G.PlayerCastingBarFrame then - HideFrame(_G.PlayerCastingBarFrame) - end + HideFrame(_G.PlayerCastingBarFrame) -- Retail + HideFrame(_G.CastingBarFrame) -- Non Retail elseif type == "target" and _G.TargetFrame then HideFrame(_G.TargetFrame) + HideFrame(_G.ComboFrame) elseif type == "focus" and _G.FocusFrame then HideFrame(_G.FocusFrame) + HideFrame(_G.TargetofFocusFrame) elseif type == "pet" and _G.PetFrame then HideFrame(_G.PetFrame) + HideFrame(_G.PetCastingBarFrame) elseif type == "boss" then HideFrame(_G.BossTargetFrameContainer) for i = 1, MAX_BOSS_FRAMES do @@ -86,6 +88,7 @@ function CUF:HideBlizzardUnitFrame(type) end elseif type == "buffFrame" then HideFrame(_G.BuffFrame) + HideFrame(_G.TemporaryEnchantFrame) elseif type == "debuffFrame" then HideFrame(_G.DebuffFrame) end diff --git a/Util/Utils.lua b/Util/Utils.lua index 46939ce3..6f38ef56 100644 --- a/Util/Utils.lua +++ b/Util/Utils.lua @@ -15,6 +15,16 @@ local const = CUF.constants local GetWeaponEnchantInfo = GetWeaponEnchantInfo local GetClassColor = GetClassColor +local UnitSelectionType = UnitSelectionType or + ---@param unit UnitToken + function(unit) + -- Helper fallback function for older game versions, blizzards function was introduced with BFA + if UnitIsFriend(unit, "player") then return 3 end + if UnitIsEnemy(unit, "player") then return 0 end + if UnitIsUnit(unit, "pet") or UnitIsOtherPlayersPet(unit) then return 4 end + return 999 + end + ------------------------------------------------- -- MARK: Prop Hunting ------------------------------------------------- @@ -155,6 +165,17 @@ function Util:Mixin(object, ...) end end +---@param enum table +---@param val any +---@return boolean? +function Util:EnumHasValue(enum, val) + if not enum or not val then return false end + + for _, value in pairs(enum) do + if val == value then return true end + end +end + ------------------------------------------------- -- MARK: IterateAllUnitButtons ------------------------------------------------- @@ -761,6 +782,21 @@ function Util:GetUnitClassificationIcon(unit) return typeIcon[UnitClassification(unit)] end +-- Helper function to get a aura index by auraInstanceID +-- Currently only used for non-retail tooltips +---@param unit string +---@param auraInstanceID number +---@param filter string +---@return number? auraIndex +function Util:GetAuraIndexByAuraInstanceID(unit, auraInstanceID, filter) + for index = 1, select("#", C_UnitAuras.GetAuraSlots(unit, filter)) do + local auraInfo = C_UnitAuras.GetAuraDataByIndex(unit, index, filter); + if auraInfo and auraInfo.auraInstanceID == auraInstanceID then + return index + end + end +end + ------------------------------------------------- -- MARK: Frames ------------------------------------------------- diff --git a/Widgets/Auras/Auras.lua b/Widgets/Auras/Auras.lua index 4699904f..85567118 100644 --- a/Widgets/Auras/Auras.lua +++ b/Widgets/Auras/Auras.lua @@ -81,16 +81,30 @@ local function Icons_ShowTooltip(icons, show, hideInCombat) if (hideInCombat and InCombatLockdown()) or icons._isSelected then return end GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT") - if icons.id == "buffs" then - if self.isTempEnchant then - GameTooltip:SetInventoryItem("player", self.auraInstanceID); + + if self.isTempEnchant then + -- Why is this a thing, but we cant set auras by auraInstanceID??? + GameTooltip:SetInventoryItem("player", self.auraInstanceID); + return + end + + if CUF.vars.isRetail then + if icons.id == "buffs" then + GameTooltip:SetUnitBuffByAuraInstanceID(icons._owner.states.displayedUnit, + self.auraInstanceID, + icons.auraFilter); else - GameTooltip:SetUnitBuffByAuraInstanceID(icons._owner.states.displayedUnit, self.auraInstanceID, + GameTooltip:SetUnitDebuffByAuraInstanceID(icons._owner.states.displayedUnit, self.auraInstanceID, icons.auraFilter); end else - GameTooltip:SetUnitDebuffByAuraInstanceID(icons._owner.states.displayedUnit, self.auraInstanceID, - icons.auraFilter); + local index = Util:GetAuraIndexByAuraInstanceID(icons._owner.states.displayedUnit, + self.auraInstanceID, icons.auraFilter) + if not index then return end + + GameTooltip:SetUnitAura(icons._owner.states.displayedUnit, + index, + icons.auraFilter) end end) @@ -225,7 +239,7 @@ end ---@param icons CellAuraIcons ---@param show boolean local function Icons_SetShowTempEnchant(icons, show) - if icons._owner._baseUnit == "player" and icons.id == "buffs" then + if CUF.vars.isRetail and icons._owner._baseUnit == "player" and icons.id == "buffs" then icons.showTempEnchant = show icons:UpdateTempEnchantListener() end diff --git a/Widgets/Bars/ClassBar.lua b/Widgets/Bars/ClassBar.lua index 73525db4..bbadac12 100644 --- a/Widgets/Bars/ClassBar.lua +++ b/Widgets/Bars/ClassBar.lua @@ -238,7 +238,7 @@ local function TogglePowerEvents(self, enable) self._owner:AddEventListener("UNIT_POWER_FREQUENT", self.UpdateEssence) else -- Check for Charged Combo Points - if self._owner.states.class == "ROGUE" then + if self._owner.states.class == "ROGUE" and CUF.vars.isRetail then self._owner:AddEventListener("UNIT_POWER_POINT_CHARGE", self.UpdateChargedComboPoints) end self._owner:AddEventListener("UNIT_POWER_UPDATE", self.UpdatePower) @@ -250,7 +250,9 @@ local function TogglePowerEvents(self, enable) self._owner:RemoveEventListener("UNIT_POWER_UPDATE", self.UpdatePower) self._owner:RemoveEventListener("RUNE_POWER_UPDATE", self.UpdateRunes) self._owner:RemoveEventListener("UNIT_POWER_FREQUENT", self.UpdateEssence) - self._owner:RemoveEventListener("UNIT_POWER_POINT_CHARGE", self.UpdateChargedComboPoints) + if CUF.vars.isRetail then + self._owner:RemoveEventListener("UNIT_POWER_POINT_CHARGE", self.UpdateChargedComboPoints) + end end end diff --git a/Widgets/Bars/HealthBar.lua b/Widgets/Bars/HealthBar.lua index c08ea1c9..7e1504a3 100644 --- a/Widgets/Bars/HealthBar.lua +++ b/Widgets/Bars/HealthBar.lua @@ -101,7 +101,6 @@ local function UpdateUnitHealthState(button) button.states.health = health button.states.healthMax = healthMax - button.states.totalAbsorbs = UnitGetTotalAbsorbs(unit) if healthMax == 0 then button.states.healthPercent = 0 diff --git a/Widgets/Bars/PowerBar.lua b/Widgets/Bars/PowerBar.lua index da78ce9e..4cef7daf 100644 --- a/Widgets/Bars/PowerBar.lua +++ b/Widgets/Bars/PowerBar.lua @@ -18,6 +18,8 @@ local DB = CUF.DB local Builder = CUF.Builder local Handler = CUF.Handler +local GetSpecialization = GetSpecialization or C_SpecializationInfo.GetSpecialization + --[[ local SPEC_ROLES = { -- Melee [251] = "DAMAGER", -- Death Knight - Frost diff --git a/Widgets/LoadWidgets_Common.xml b/Widgets/LoadWidgets_Common.xml new file mode 100644 index 00000000..7cac2385 --- /dev/null +++ b/Widgets/LoadWidgets_Common.xml @@ -0,0 +1,36 @@ + +