From 376da30df075d0fc0b3c72a768402e62b07fee2c Mon Sep 17 00:00:00 2001 From: Vollmer Date: Wed, 20 Nov 2024 14:39:11 +0100 Subject: [PATCH] [Feature] Add toggle for showing Temporary Enchants (#183) * add tempEnchant prop to aura filter * add widget update for tempEnchant * add util function for getting weapon enchant info * add function for updating temp enchants * update tooltip func * add guard clause for Icons_SetShowTempEnchant to prevent it from being enabled on unwanted units/frames * fix TEMP_ENCHANT const * add temp enchant toggle for menu * locale * add event listeners * make sure .isTempEnchant doesn't stick so tooltips function properly --- Data/Constants.lua | 1 + Data/Defaults.lua | 2 + Locales/enUS.lua | 3 + Menu/Builder.lua | 16 +++++ Util/Utils.lua | 43 +++++++++++++ WidgetAnnotations.lua | 1 + Widgets/Auras/Auras.lua | 125 +++++++++++++++++++++++++++++++++++++- Widgets/Auras/Updater.lua | 3 + 8 files changed, 191 insertions(+), 3 deletions(-) diff --git a/Data/Constants.lua b/Data/Constants.lua index 845975f..888c8e6 100644 --- a/Data/Constants.lua +++ b/Data/Constants.lua @@ -211,6 +211,7 @@ const.AURA_OPTION_KIND = { CAST_BY_NPC = "castByNPC", HIDE_IN_COMBAT = "hideInCombat", WHITE_LIST_PRIORITY = "whiteListPriority", + TEMP_ENCHANT = "tempEnchant", } ---@enum GrowthOrientation diff --git a/Data/Defaults.lua b/Data/Defaults.lua index 33da6be..a4d5fa0 100644 --- a/Data/Defaults.lua +++ b/Data/Defaults.lua @@ -444,6 +444,7 @@ Defaults.Widgets = { castByNPC = false, personal = true, boss = false, + tempEnchant = false, }, position = { point = "BOTTOMLEFT", @@ -489,6 +490,7 @@ Defaults.Widgets = { castByNPC = false, personal = true, boss = false, + tempEnchant = false, }, position = { point = "BOTTOMRIGHT", diff --git a/Locales/enUS.lua b/Locales/enUS.lua index c916aa8..caa1073 100644 --- a/Locales/enUS.lua +++ b/Locales/enUS.lua @@ -97,6 +97,9 @@ The priority goes from top of the list to the bottom]] L.OverrideImportTooltip = "Will override the current list" L.AdditiveImportTooltip = "Will add to the current list" +L.tempEnchant = "Temporary Enchants" +L.tempEnchantTooltip = "Show temporary enchants" + -- Cast Bar L.Reverse = "Reverse" L.Spark = "Spark" diff --git a/Menu/Builder.lua b/Menu/Builder.lua index dd741c9..e03149e 100644 --- a/Menu/Builder.lua +++ b/Menu/Builder.lua @@ -1395,6 +1395,22 @@ function Builder:CreateAuraFilterOptions(parent, widgetName) L.WhiteListPriorityTooltip) self:AnchorBelowCB(f.whiteListPriority, f.useBlacklistCB) + if widgetName == const.WIDGET_KIND.BUFFS then + f.tempEnchant = self:CreateCheckBox(f, widgetName, L.tempEnchant, + const.AURA_OPTION_KIND.FILTER .. "." .. const.AURA_OPTION_KIND.TEMP_ENCHANT, + L.tempEnchantTooltip) + self:AnchorRightOfCB(f.tempEnchant, f.whiteListPriority) + + local function LoadPageDB() + if CUF.vars.selectedUnit == const.UNIT.PLAYER then + f.tempEnchant:Show() + else + f.tempEnchant:Hide() + end + end + Handler:RegisterOption(LoadPageDB, widgetName, "AuraFilterOptions") + end + return f end diff --git a/Util/Utils.lua b/Util/Utils.lua index a51dc97..e0518c3 100644 --- a/Util/Utils.lua +++ b/Util/Utils.lua @@ -12,6 +12,8 @@ local Util = CUF.Util local const = CUF.constants +local GetWeaponEnchantInfo = GetWeaponEnchantInfo + ------------------------------------------------- -- MARK: Prop Hunting ------------------------------------------------- @@ -594,6 +596,47 @@ function Util:GetHealthBarColor(healthBarColorType, healthLossColorType, percent return barR, barG, barB, lossR, lossG, lossB end +---@class WeaponEnchantInfo +---@field hasMainHandEnchant boolean +---@field mainHandExpiration number? +---@field mainHandCharges number? +---@field mainHandEnchantID number? +---@field hasOffHandEnchant boolean? +---@field offHandExpiration number? +---@field offHandCharges number? +---@field offHandEnchantID number? +---@field hasRangedEnchant boolean? +---@field rangedExpiration number? +---@field rangedCharges number? +---@field rangedEnchantID number? + +--- Returns weapon enchant info as a table +--- Returns nil if no weapon enchant info can be found +---@return WeaponEnchantInfo? +function Util:GetWeaponEnchantInfo() + local hasMainHandEnchant, mainHandExpiration, mainHandCharges, mainHandEnchantID, + hasOffHandEnchant, offHandExpiration, offHandCharges, offHandEnchantID, + hasRangedEnchant, rangedExpiration, rangedCharges, rangedEnchantID = + GetWeaponEnchantInfo() + + if hasMainHandEnchant ~= nil then + return { + hasMainHandEnchant = hasMainHandEnchant, + mainHandExpiration = mainHandExpiration, + mainHandCharges = mainHandCharges, + mainHandEnchantID = mainHandEnchantID, + hasOffHandEnchant = hasOffHandEnchant, + offHandExpiration = offHandExpiration, + offHandCharges = offHandCharges, + offHandEnchantID = offHandEnchantID, + hasRangedEnchant = hasRangedEnchant, + rangedExpiration = rangedExpiration, + rangedCharges = rangedCharges, + rangedEnchantID = rangedEnchantID, + } + end +end + ------------------------------------------------- -- MARK: Unit Info ------------------------------------------------- diff --git a/WidgetAnnotations.lua b/WidgetAnnotations.lua index a23b53e..baacd2b 100644 --- a/WidgetAnnotations.lua +++ b/WidgetAnnotations.lua @@ -208,6 +208,7 @@ ---@field castByNPC boolean ---@field personal boolean ---@field boss boolean +---@field tempEnchant boolean ---@class AuraFontOpt ---@field stacks BigFontOpt diff --git a/Widgets/Auras/Auras.lua b/Widgets/Auras/Auras.lua index 7d53d03..e6743c1 100644 --- a/Widgets/Auras/Auras.lua +++ b/Widgets/Auras/Auras.lua @@ -78,8 +78,12 @@ local function Icons_ShowTooltip(icons, show, hideInCombat) GameTooltip:SetOwner(self, "ANCHOR_TOPLEFT") if icons.id == "buffs" then - GameTooltip:SetUnitBuffByAuraInstanceID(icons._owner.states.displayedUnit, self.auraInstanceID, - icons.auraFilter); + if self.isTempEnchant then + GameTooltip:SetInventoryItem("player", self.auraInstanceID); + else + GameTooltip:SetUnitBuffByAuraInstanceID(icons._owner.states.displayedUnit, self.auraInstanceID, + icons.auraFilter); + end else GameTooltip:SetUnitDebuffByAuraInstanceID(icons._owner.states.displayedUnit, self.auraInstanceID, icons.auraFilter); @@ -196,6 +200,15 @@ local function Icons_ShowDuration(icons, show) end end +---@param icons CellAuraIcons +---@param show boolean +local function Icons_SetShowTempEnchant(icons, show) + if icons._owner._baseUnit == "player" and icons.id == "buffs" then + icons.showTempEnchant = show + icons:UpdateTempEnchantListener() + end +end + -- We need to override this so we can format the duration for really long auras local function Icon_OnUpdate(frame, elapsed) frame._remain = frame._duration - (GetTime() - frame._start) @@ -364,6 +377,85 @@ end -- MARK: UpdateAuraIcons ------------------------------------------------- +local textureMapping = { + [1] = 16, --Main hand + [2] = 17, --Off-hand + [3] = 18, --Ranged +} + +---@param icons CellAuraIcons +local function UpdateTempEnchants(icons) + if not icons.showTempEnchant then return end + + local temp = Util:GetWeaponEnchantInfo() + if not temp then return end + + local id + + if temp.hasMainHandEnchant then + if temp.mainHandExpiration then + temp.mainHandExpiration = temp.mainHandExpiration / 1000; + end + local expirationTime = GetTime() + temp.mainHandExpiration; + + id = textureMapping[1] + + local tempAura = { + expirationTime = expirationTime, + duration = temp.mainHandExpiration, + icon = GetInventoryItemTexture("player", id), + applications = temp.mainHandCharges, + refreshing = false, + isTempEnchant = true, + spellId = -id, + } + tinsert(icons._auraInstanceIDs, -id) + icons._auraCache[-id] = tempAura + end + + if temp.hasOffHandEnchant then + if temp.offHandExpiration then + temp.offHandExpiration = temp.offHandExpiration / 1000; + end + local expirationTime = GetTime() + temp.offHandExpiration; + + id = textureMapping[2] + + local tempAura = { + expirationTime = expirationTime, + duration = temp.offHandExpiration, + icon = GetInventoryItemTexture("player", id), + applications = temp.offHandCharges, + refreshing = false, + isTempEnchant = true, + spellId = -id, + } + tinsert(icons._auraInstanceIDs, -id) + icons._auraCache[-id] = tempAura + end + + if temp.hasRangedEnchant then + if temp.rangedExpiration then + temp.rangedExpiration = temp.rangedExpiration / 1000; + end + local expirationTime = GetTime() + temp.rangedExpiration; + + id = textureMapping[3] + + local tempAura = { + expirationTime = expirationTime, + duration = temp.rangedExpiration, + icon = GetInventoryItemTexture("player", id), + applications = temp.rangedCharges, + refreshing = false, + isTempEnchant = true, + spellId = -id, + } + tinsert(icons._auraInstanceIDs, -id) + icons._auraCache[-id] = tempAura + end +end + ---@param icons CellAuraIcons local function UpdateAuraIcons(icons) -- Preview @@ -379,6 +471,8 @@ local function UpdateAuraIcons(icons) -- Update aura cache icons._owner:IterateAuras(icons.id, HandleAura, icons) + UpdateTempEnchants(icons) + -- Sort table.sort(icons._auraInstanceIDs, function(a, b) local aData = icons._auraCache[a] @@ -416,7 +510,16 @@ local function UpdateAuraIcons(icons) auraData.applications, auraData.refreshing ) - icons[icons._auraCount].auraInstanceID = auraInstanceID -- Tooltip + + -- Tooltip + ---@diagnostic disable-next-line: undefined-field + if auraData.isTempEnchant then + icons[icons._auraCount].auraInstanceID = math.abs(auraInstanceID) + icons[icons._auraCount].isTempEnchant = true + else + icons[icons._auraCount].auraInstanceID = auraInstanceID + icons[icons._auraCount].isTempEnchant = false + end icons[icons._auraCount]:PostUpdate(auraData) end @@ -483,10 +586,23 @@ end -- MARK: Update ------------------------------------------------- +---@param self CellAuraIcons +local function UpdateTempEnchantListener(self) + if self.showTempEnchant then + self._owner:AddEventListener("WEAPON_ENCHANT_CHANGED", self.Update, true) + self._owner:AddEventListener("WEAPON_SLOT_CHANGED", self.Update, true) + else + self._owner:RemoveEventListener("WEAPON_ENCHANT_CHANGED", self.Update) + self._owner:RemoveEventListener("WEAPON_SLOT_CHANGED", self.Update) + end +end + ---@param self CellAuraIcons local function Enable(self) self._owner:RegisterAuraCallback(self.id, self.Update) + self:UpdateTempEnchantListener() + self:Show() return true end @@ -514,6 +630,7 @@ function W:CreateAuraIcons(button, type) auraIcons.auraFilter = type == "buffs" and "HELPFUL" or "HARMFUL" auraIcons._maxNum = CUF.Defaults.Values.maxAuraIcons auraIcons._isSelected = false + auraIcons.showTempEnchant = false ---@type table auraIcons._auraCache = {} @@ -575,6 +692,7 @@ function W:CreateAuraIcons(button, type) auraIcons.SetUseBlacklist = Icons_SetUseBlacklist auraIcons.SetUseWhitelist = Icons_SetUseWhitelist auraIcons.SetWhiteListPriority = Icons_SetWhiteListPriority + auraIcons.SetShowTempEnchant = Icons_SetShowTempEnchant auraIcons.SetBoss = Icons_SetBoss auraIcons.SetCastByPlayers = Icons_SetCastByPlayers @@ -612,6 +730,7 @@ function W:CreateAuraIcons(button, type) else auraIcons.Update = UpdateAuras_Debuffs end + auraIcons.UpdateTempEnchantListener = UpdateTempEnchantListener return auraIcons end diff --git a/Widgets/Auras/Updater.lua b/Widgets/Auras/Updater.lua index 980d73d..e78eb74 100644 --- a/Widgets/Auras/Updater.lua +++ b/Widgets/Auras/Updater.lua @@ -89,6 +89,9 @@ function W.UpdateAuraWidget(button, unit, which, setting, subSetting, ...) if not subSetting or subSetting == const.AURA_OPTION_KIND.WHITE_LIST_PRIORITY then auras:SetWhiteListPriority(styleTable.filter.whiteListPriority) end + if not subSetting or subSetting == const.AURA_OPTION_KIND.TEMP_ENCHANT then + auras:SetShowTempEnchant(styleTable.filter.tempEnchant) + end end auras.Update(button)