From bf2b33bd46cbce85ce61a4af201ec71db33f08c0 Mon Sep 17 00:00:00 2001 From: JerichoR Date: Wed, 11 Sep 2024 20:18:59 +0200 Subject: [PATCH 1/7] oUF_RaidDebuffs for retail --- .../Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua | 4 +- .../oUF_RaidDebuffs_Retail.lua | 208 ++++++++++++++++++ Tukui/Tukui-Mainline.toc | 1 + 3 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs_Retail.lua diff --git a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua index df0144b4..4df5d37f 100644 --- a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua +++ b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua @@ -369,4 +369,6 @@ local function Disable(self) end end -oUF:AddElement("RaidDebuffs", Update, Enable, Disable) +if not oUF.isRetail then + oUF:AddElement("RaidDebuffs", Update, Enable, Disable) +end \ No newline at end of file diff --git a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs_Retail.lua b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs_Retail.lua new file mode 100644 index 00000000..729c10af --- /dev/null +++ b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs_Retail.lua @@ -0,0 +1,208 @@ +--[=[ + Shows Debuffs on Unit Frames + + Sub Widgets + .icon Icon/Texture of the debuff + .cd Cooldown frame + .count Number of Stacks +--]=] +local _, ns = ... +local oUF = ns.oUF or oUF + + +local IsPlayerSpell = _G.IsPlayerSpell +local UnitCanAssist = _G.UnitCanAssist +local playerClass = UnitClassBase("player") +local debuffColor = DebuffTypeColor +local debuffCache = {} + +-- dispel priority? magic <- curse <- poison <- disease + + +-- Holds which dispell types can currently be handled +-- Initialized to false for all types +local dispellist = { + Magic = false, + Poison = false, + Disease = false, + Curse = false +} + + +-- Class functions to update the dispell types which can be handled +local CanDispel = { + DRUID = function() + dispellist["Magic"] = IsPlayerSpell(88423) -- Nature's Cure + dispellist["Poison"] = IsPlayerSpell(392378) or IsPlayerSpell(2782) -- Improved Nature's Cure or Remove Corruption + dispellist["Disease"] = false + dispellist["Curse"] = IsPlayerSpell(392378) or IsPlayerSpell(2782) -- Improved Nature's Cure or Remove Corruption + end, + MAGE = function() + dispellist["Magic"] = false + dispellist["Poison"] = false + dispellist["Disease"] = false + dispellist["Curse"] = IsPlayerSpell(475) -- Remove Curse + end, + MONK = function() + dispellist["Magic"] = IsPlayerSpell(115450) -- Detox + dispellist["Poison"] = IsPlayerSpell(388874) or IsPlayerSpell(218164) -- Improved Detox or Detox + dispellist["Disease"] = IsPlayerSpell(388874) or IsPlayerSpell(218164) -- Improved Detox or Detox + dispellist["Curse"] = false + end, + PALADIN = function() + dispellist["Magic"] = IsPlayerSpell(4987) -- Cleanse + dispellist["Poison"] = IsPlayerSpell(393024) or IsPlayerSpell(213644) -- Improved Cleanse or Cleanse Toxins + dispellist["Disease"] = IsPlayerSpell(393024) or IsPlayerSpell(213644) -- Improved Cleanse or Cleanse Toxins + dispellist["Curse"] = false + end, + PRIEST = function() + dispellist["Magic"] = IsPlayerSpell(527) -- Purify + dispellist["Poison"] = false + dispellist["Disease"] = IsPlayerSpell(390632) or IsPlayerSpell(213634) -- Improved Purify or Purify Disease + dispellist["Curse"] = false + end, + SHAMAN = function() + dispellist["Magic"] = IsPlayerSpell(77130) -- Purify Spirit + dispellist["Poison"] = IsPlayerSpell(383013) -- Poison Cleansing Totem + dispellist["Disease"] = false + dispellist["Curse"] = IsPlayerSpell(383016) or IsPlayerSpell(51886) -- Improved Purify Spirit or Cleanse Spirit + end, + EVOKER = function() + dispellist["Magic"] = IsPlayerSpell(360823) -- Naturalize + dispellist["Poison"] = IsPlayerSpell(360823) or IsPlayerSpell(365585) or IsPlayerSpell(374251) -- Naturalize or Expunge or Cauterizing Flame + dispellist["Disease"] = IsPlayerSpell(374251) -- Cauterizing Flame + dispellist["Curse"] = IsPlayerSpell(374251) -- Cauterizing Flame + end +} + + +-- Event handler for Player Login and Speels Changed +local function UpdateDispelList(self, event) + if event == "PLAYER_LOGIN" or event == "SPELLS_CHANGED" then + CanDispel[playerClass]() + end +end + + +-- Show the debuff +-- @self UnitFrame +-- @AuraData AuraData object provided by UNIT_AURA event +local function Set(self, AuraData) + local element = self.RaidDebuffs + + local count = AuraData.applications + local duration = AuraData.duration + local color = debuffColor[AuraData.dispelName] + + element.icon:SetTexture(AuraData.icon) + element.Backdrop:SetBorderColor(color.r, color.g, color.b) + + if duration and duration > 0 then + element.cd:SetCooldown(AuraData.expirationTime - duration, duration) + end + + if count and count > 1 then + element.count:SetText(count) + end + + element:Show() +end + + +-- Hide the debuff +-- @self UnitFrame +local function Reset(self) + local element = self.RaidDebuffs + local color = debuffColor["none"] + + element.Backdrop:SetBorderColor(color.r, color.g, color.b) + element.cd:SetCooldown(0, 0) + element.count:SetText("") + + element:Hide() +end + + +-- Event handler for Unit Aura +-- @self UnitFrame +-- @event UNIT_AURA +-- @unit payload of event: unitTarget +-- @updateInfo payload of event: UnitAuraUpdateInfo +local function Update(self, event, unit, updateInfo) + -- Exit when unit doesn't match or no updateInfo provided or target can't be assisted + if event ~= "UNIT_AURA" or self.unit ~= unit or not updateInfo or not UnitCanAssist("player", unit) then return end + local element = self.RaidDebuffs + + if updateInfo.removedAuraInstanceIDs then + for _, auraInstanceID in pairs(updateInfo.removedAuraInstanceIDs) do + if debuffCache[auraInstanceID] then + debuffCache[auraInstanceID] = nil + Reset(self) + end + end + end + + if updateInfo.addedAuras then + for _, AuraData in pairs(updateInfo.addedAuras) do + if AuraData.dispelName and dispellist[AuraData.dispelName] then + debuffCache[AuraData.auraInstanceID] = true + Set(self, AuraData) + end + end + end +end + + +-- oUF Enable function +local function Enable(self) + local element = self.RaidDebuffs + + if oUF.isRetail and element and CanDispel[playerClass] then + element:CreateBackdrop() + + if not element.icon then + element.icon = element:CreateTexture(nil, "ARTWORK") + element.icon:SetTexCoord(.1, .9, .1, .9) + element.icon:SetInside(element) + end + + if not element.cd then + element.cd = CreateFrame("Cooldown", nil, element, "CooldownFrameTemplate") + element.cd:SetInside(element, 1, 0) + element.cd:SetReverse(true) + element.cd:SetHideCountdownNumbers(false) + element.cd:SetAlpha(.7) + end + + if not element.count then + element.count = element:CreateFontString(nil, "OVERLAY") + element.count:SetFont(C.Medias.Font, 12, "OUTLINE") + element.count:SetPoint("BOTTOMRIGHT", element, "BOTTOMRIGHT", 2, 0) + element.count:SetTextColor(1, .9, 0) + end + + -- Update the dispelList at login and whenever spells change (talent or spec change) + self:RegisterEvent("PLAYER_LOGIN", UpdateDispelList, true) + self:RegisterEvent("SPELLS_CHANGED", UpdateDispelList, true) + self:RegisterEvent("UNIT_AURA", Update) + + return true + end +end + + +-- oUF Disable function +local function Disable(self) + local element = self.DebuffHighlight + + if element then + self:UnregisterEvent("PLAYER_LOGIN", UpdateDispelList, true) + self:UnregisterEvent("SPELLS_CHANGED", UpdateDispelList, true) + self:UnregisterEvent("UNIT_AURA", Update) + end +end + + +if oUF.isRetail then + oUF:AddElement("RaidDebuffs", Update, Enable, Disable) +end \ No newline at end of file diff --git a/Tukui/Tukui-Mainline.toc b/Tukui/Tukui-Mainline.toc index 1a859266..1b930762 100644 --- a/Tukui/Tukui-Mainline.toc +++ b/Tukui/Tukui-Mainline.toc @@ -66,6 +66,7 @@ Libs\oUF_Retail\finalize.lua Libs\oUF_ComboPointsBar\oUF_ComboPointsBar.lua Libs\oUF_CombatFeedback\oUF_CombatFeedback.lua Libs\oUF_RaidDebuffs\oUF_RaidDebuffs.lua +Libs\oUF_RaidDebuffs\oUF_RaidDebuffs_Retail.lua Libs\oUF_FloatingCombatFeedback\oUF_FloatingCombatFeedback.lua Libs\oUF_AuraBars\oUF_AuraBars.lua Libs\oUF_ArcaneCharge\oUF_ArcaneCharge.lua From 1af0629e47cfcd8c1d2676b6abc332ba18a3c32a Mon Sep 17 00:00:00 2001 From: JerichoR Date: Fri, 13 Sep 2024 22:58:45 +0200 Subject: [PATCH 2/7] Added Classic dispel spells --- .../Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua | 569 ++++++++---------- .../oUF_RaidDebuffs_Retail.lua | 208 ------- Tukui/Libs/oUF_Retail/init.lua | 3 + Tukui/Modules/UnitFrames/Groups/Raid.lua | 11 - Tukui/Tukui-Mainline.toc | 1 - 5 files changed, 263 insertions(+), 529 deletions(-) delete mode 100644 Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs_Retail.lua diff --git a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua index 4df5d37f..b2f5a03b 100644 --- a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua +++ b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua @@ -1,374 +1,325 @@ -local _, ns = ... -local oUF = ns.oUF or oUF - -local _G = _G -local addon = {} -ns.oUF_RaidDebuffs = addon -_G.oUF_RaidDebuffs = ns.oUF_RaidDebuffs -if not _G.oUF_RaidDebuffs then - _G.oUF_RaidDebuffs = addon -end +--[=[ + Shows Debuffs on Unit Frames. -local format, floor = format, floor -local type, pairs, wipe = type, pairs, wipe - -local GetActiveSpecGroup = _G.GetActiveSpecGroup -local GetSpecialization = _G.GetSpecialization -local IsSpellKnown = _G.IsSpellKnown -local GetSpellInfo = C_Spell.GetSpellInfo or GetSpellInfo -local GetTime = _G.GetTime -local UnitAura = _G.UnitAura -local UnitCanAttack = _G.UnitCanAttack -local UnitIsCharmed = _G.UnitIsCharmed - -local debuff_data = {} -addon.DebuffData = debuff_data -addon.ShowDispellableDebuff = true -addon.FilterDispellableDebuff = true -addon.MatchBySpellName = false -addon.priority = 10 - -local UnitAura = UnitAura - -if not UnitAura then - UnitAura = function(unitToken, index, filter) - local auraData = C_UnitAuras.GetAuraDataByIndex(unitToken, index, filter); - - if not auraData then - return nil - end - - return AuraUtil.UnpackAuraData(auraData) - end -end + Sub-Widgets will be created if not provided. -local function add(spell, priority, stackThreshold) - if addon.MatchBySpellName and type(spell) == "number" then - spell = GetSpellInfo(spell) - end - - if(spell) then - debuff_data[spell] = { - priority = (addon.priority + priority), - stackThreshold = (stackThreshold or 0), - } - end -end + Sub-Widgets + .icon The Icon/Texture of the debuff + .cd A Cooldown frame showing the duration + .count A Text showing the number of stacks + .Backdrop Backdrop +--]=] +local _, ns = ... +local oUF = ns.oUF or oUF -function addon:RegisterDebuffs(t) - for spell, value in pairs(t) do - if type(t[spell]) == "boolean" then - local oldValue = t[spell] - t[spell] = { enable = oldValue, priority = 0, stackThreshold = 0 } - else - if t[spell].enable then - add(spell, t[spell].priority, t[spell].stackThreshold) - end - end - end -end +local IsPlayerSpell = _G.IsPlayerSpell +local UnitCanAssist = _G.UnitCanAssist +local playerClass = UnitClassBase("player") +local debuffColor = DebuffTypeColor +local debuffCache = {} -function addon:ResetDebuffData() - wipe(debuff_data) -end +-- dispel priority? magic <- curse <- poison <- disease -local DispellColor = { - ["Magic"] = {.2, .6, 1}, - ["Curse"] = {.6, 0, 1}, - ["Poison"] = {0, .6, 0}, - ["Disease"] = {.6, .4, 0}, - ["none"] = {1, 0, 0} -} +--[[ Holds which dispel types can currently be handled -local DispellPriority = { - ["Magic"] = 4, - ["Curse"] = 3, - ["Poison"] = 1, - ["Disease"] = 2 +Initialized to false for all types +--]] +local dispelList = { + Magic = false, + Poison = false, + Disease = false, + Curse = false, } -local class = select(2, UnitClass("player")) - -local DispellFilterClasses = { - ["DRUID"] = { - ["Magic"] = false, - ["Curse"] = true, - ["Poison"] = true, - ["Disease"] = false +--[[ Class functions to update the dispel types which can be handled ]]-- +local canDispel = { + DRUID = { + retail = function() + dispelList["Magic"] = IsPlayerSpell(88423) -- Nature's Cure + dispelList["Poison"] = IsPlayerSpell(392378) or IsPlayerSpell(2782) -- Improved Nature's Cure or Remove Corruption + dispelList["Disease"] = false + dispelList["Curse"] = IsPlayerSpell(392378) or IsPlayerSpell(2782) -- Improved Nature's Cure or Remove Corruption + end, + classic = function() + dispelList["Magic"] = false + dispelList["Poison"] = IsPlayerSpell(8946) or IsPlayerSpell(2893) -- Cure Poison or Abolish Poison + dispelList["Disease"] = false + dispelList["Curse"] = IsPlayerSpell(2782) -- Remove Curse + end, + other = function() + dispelList["Magic"] = IsPlayerSpell(88423) -- Nature's Cure + dispelList["Poison"] = IsPlayerSpell(2782) -- Remove Corruption + dispelList["Disease"] = false + dispelList["Curse"] = IsPlayerSpell(2782) -- Remove Corruption + end }, - ["EVOKER"] = { - ["Magic"] = true, - ["Curse"] = true, - ["Poison"] = true, - ["Disease"] = true + MAGE = { + retail = function() + dispelList["Magic"] = false + dispelList["Poison"] = false + dispelList["Disease"] = false + dispelList["Curse"] = IsPlayerSpell(475) -- Remove Curse + end, + classic = function() + dispelList["Magic"] = false + dispelList["Poison"] = false + dispelList["Disease"] = false + dispelList["Curse"] = IsPlayerSpell(475) -- Remove Curse + end, + other = function() + dispelList["Magic"] = false + dispelList["Poison"] = false + dispelList["Disease"] = false + dispelList["Curse"] = IsPlayerSpell(475) -- Remove Curse + end }, - ["MAGE"] = { - ["Curse"] = true + MONK = { + retail = function() + dispelList["Magic"] = IsPlayerSpell(115450) -- Detox + dispelList["Poison"] = IsPlayerSpell(388874) or IsPlayerSpell(218164) -- Improved Detox or Detox + dispelList["Disease"] = IsPlayerSpell(388874) or IsPlayerSpell(218164) -- Improved Detox or Detox + dispelList["Curse"] = false + end, + classic = function() + dispelList["Magic"] = false + dispelList["Poison"] = false + dispelList["Disease"] = false + dispelList["Curse"] = false + end, + other = function() + dispelList["Magic"] = false + dispelList["Poison"] = false + dispelList["Disease"] = false + dispelList["Curse"] = false + end }, - ["MONK"] = { - ["Magic"] = (oUF.isRetail and true or false), - ["Poison"] = true, - ["Disease"] = true + PALADIN = { + retail = function() + dispelList["Magic"] = IsPlayerSpell(4987) -- Cleanse + dispelList["Poison"] = IsPlayerSpell(393024) or IsPlayerSpell(213644) -- Improved Cleanse or Cleanse Toxins + dispelList["Disease"] = IsPlayerSpell(393024) or IsPlayerSpell(213644) -- Improved Cleanse or Cleanse Toxins + dispelList["Curse"] = false + end, + classic = function() + dispelList["Magic"] = IsPlayerSpell(4987) -- Cleanse + dispelList["Poison"] = IsPlayerSpell(4987) or IsPlayerSpell(1152) -- Cleanse or Purify + dispelList["Disease"] = IsPlayerSpell(4987) or IsPlayerSpell(1152) -- Cleanse or Purify + dispelList["Curse"] = false + end, + other = function() + dispelList["Magic"] = IsPlayerSpell(53551) -- Sacred Cleansing + dispelList["Poison"] = IsPlayerSpell(4987) -- Cleanse + dispelList["Disease"] = IsPlayerSpell(4987) -- Cleanse + dispelList["Curse"] = false + end }, - ["PALADIN"] = { - ["Magic"] = true, - ["Poison"] = true, - ["Disease"] = true + PRIEST = { + retail = function() + dispelList["Magic"] = IsPlayerSpell(527) or IsPlayerSpell(32375) -- Purify or Mass Dispel + dispelList["Poison"] = false + dispelList["Disease"] = IsPlayerSpell(390632) or IsPlayerSpell(213634) -- Improved Purify or Purify Disease + dispelList["Curse"] = false + end, + classic = function() + dispelList["Magic"] = IsPlayerSpell(988) -- Dispel Magic + dispelList["Poison"] = false + dispelList["Disease"] = IsPlayerSpell(528) or IsPlayerSpell(552) -- Cure Disease or Abolish Disease + dispelList["Curse"] = false + end, + other = function() + dispelList["Magic"] = IsPlayerSpell(527) and IsPlayerSpell(33167) or IsPlayerSpell(32375) -- Dispel Magic and Absolution or Mass Dispel + dispelList["Poison"] = false + dispelList["Disease"] = IsPlayerSpell(528) -- Cure Disease + dispelList["Curse"] = false + end }, - ["PRIEST"] = { - ["Magic"] = true, - ["Disease"] = true + SHAMAN = { + retail = function() + dispelList["Magic"] = IsPlayerSpell(77130) -- Purify Spirit + dispelList["Poison"] = IsPlayerSpell(383013) -- Poison Cleansing Totem + dispelList["Disease"] = false + dispelList["Curse"] = IsPlayerSpell(383016) or IsPlayerSpell(51886) -- Improved Purify Spirit or Cleanse Spirit + end, + classic = function() + dispelList["Magic"] = false + dispelList["Poison"] = IsPlayerSpell(526) or IsPlayerSpell(8166) -- Cure Poison or Poison Cleansing Totem + dispelList["Disease"] = IsPlayerSpell(2870) or IsPlayerSpell(8170) -- Cure Disease or Disease Cleansing Totem + dispelList["Curse"] = false + end, + other = function() + dispelList["Magic"] = IsPlayerSpell(77130) -- Improved Cleanse Spirit + dispelList["Poison"] = false + dispelList["Disease"] = false + dispelList["Curse"] = IsPlayerSpell(51886) -- Cleanse Spirit + end }, - ["SHAMAN"] = { - ["Magic"] = false, - ["Curse"] = (oUF.isRetail and true) or (oUF.isClassic and true) or false, - ["Poison"] = true, - ["Disease"] = true + EVOKER = { + retail = function() + dispelList["Magic"] = IsPlayerSpell(360823) -- Naturalize + dispelList["Poison"] = IsPlayerSpell(360823) or IsPlayerSpell(365585) or IsPlayerSpell(374251) -- Naturalize or Expunge or Cauterizing Flame + dispelList["Disease"] = IsPlayerSpell(374251) -- Cauterizing Flame + dispelList["Curse"] = IsPlayerSpell(374251) -- Cauterizing Flame + end, + classic = function() + dispelList["Magic"] = false + dispelList["Poison"] = false + dispelList["Disease"] = false + dispelList["Curse"] = false + end, + other = function() + dispelList["Magic"] = false + dispelList["Poison"] = false + dispelList["Disease"] = false + dispelList["Curse"] = false + end } } -local DispellFilter = DispellFilterClasses[class] or {} - -local function CheckTalentTree(tree) - local activeSpecGroup = GetActiveSpecGroup(false) - local currentSpec = GetSpecialization(false, false, activeSpecGroup) - return (currentSpec == tree) -end +--[[ Event handler for SPELLS_CHANGED -local function CheckSpecialization() - if (class == "DRUID") then - local isRestoration = CheckTalentTree(4) - DispellFilter.Magic = isRestoration - elseif (class == "EVOKER") then - local isPreservation = CheckTalentTree(2) - DispellFilter.Magic = isPreservation - DispellFilter.Curse = isPreservation - DispellFilter.Poison = isPreservation - DispellFilter.Disease = isPreservation - elseif (class == "MONK") then - local isMistweaver = CheckTalentTree(2) - DispellFilter.Magic = isMistweaver - elseif (class == "PALADIN") then - local isHoly = CheckTalentTree(1) - DispellFilter.Magic = isHoly - elseif (class == "PRIEST") then - -- do nothing - elseif (class == "SHAMAN") then - local isRestoration = CheckTalentTree(3) - DispellFilter.Magic = isRestoration +* self - Parent UnitFrame +* event - SPELLS_CHANGED +--]] +local function UpdateDispelList(self, event) + if event == "SPELLS_CHANGED" then + local project = (oUF.isRetail and "retail") or (oUF.isClassic and "classic") or "other" + canDispel[playerClass][project]() end end -local function UpdateDispellFilter(self, event, ...) - if (event == "CHARACTER_POINTS_CHANGED") then - local levels = ... - -- Not interested in gained points from leveling - if (levels > 0) then return end - elseif (event == "UNIT_SPELLCAST_SUCCEEDED") then - local unit, _, spellID = ... - -- watch if player change spec - if (unit ~= "player") then return end - -- 200749 = 'Activating Specialization' - -- 384255 = 'Changing Talents' - if (spellID ~= 200749 and spellID ~= 384255) then return end - end +--[[ Show the debuff - CheckSpecialization() -end +* element - RaidDebuff Frame +* AuraData - AuraData object provided by UNIT_AURA event +--]] +local function ShowElement(element, AuraData) + local count = AuraData.applications + local duration = AuraData.duration + local color = debuffColor[AuraData.dispelName] -local function formatTime(s) - if s > 60 then - return format("%dm", s/60), s%60 - elseif s < 1 then - return format("%.1f", s), s - floor(s) - else - return format("%d", s), s - floor(s) + element.icon:SetTexture(AuraData.icon) + element.Backdrop:SetBorderColor(color.r, color.g, color.b) + element:Show() + + if duration and duration > 0 then + element.cd:SetCooldown(AuraData.expirationTime - duration, duration) end -end -local abs = math.abs -local function OnUpdate(self, elapsed) - self.elapsed = (self.elapsed or 0) + elapsed - if self.elapsed >= 0.1 then - local timeLeft = self.endTime - GetTime() - if self.reverse then timeLeft = abs((self.endTime - GetTime()) - self.duration) end - if timeLeft > 0 then - local text = formatTime(timeLeft) - self.time:SetText(text) - else - self:SetScript("OnUpdate", nil) - self.time:Hide() - end - self.elapsed = 0 + if count and count > 1 then + element.count:SetText(count) end end -local function UpdateDebuff(self, name, icon, count, debuffType, duration, endTime, spellId, stackThreshold) - local f = self.RaidDebuffs - - if name and (count >= stackThreshold) then - f.icon:SetTexture(icon) - f.icon:Show() - f.duration = duration - - if f.count then - if count and (count > 1) then - f.count:SetText(count) - f.count:Show() - else - f.count:SetText("") - f.count:Hide() - end - end +--[[ Hide the debuff - if f.time then - if duration and (duration > 0) and f:GetSize() > 20 then - f.endTime = endTime - f.nextUpdate = 0 - f:SetScript("OnUpdate", OnUpdate) - f.time:Show() - else - f:SetScript("OnUpdate", nil) - f.time:Hide() - end - end +* element - RaidDebuff Frame +--]] +local function HideElement(element) + local color = debuffColor["none"] - if f.cd then - if duration and (duration > 0) then - f.cd:SetCooldown(endTime - duration, duration) - f.cd:Show() - else - f.cd:Hide() - end - end + element.Backdrop:SetBorderColor(color.r, color.g, color.b) + element.cd:SetCooldown(0, 0) + element.count:SetText("") - local c = DispellColor[debuffType] or DispellColor.none + element:Hide() +end - if f.Backdrop then - f.Backdrop:SetBorderColor(c[1], c[2], c[3]) - else - f:SetBackdropBorderColor(c[1], c[2], c[3]) - end +--[[ Filter for dispellable debuffs - f:Show() - else - f:Hide() +* element - RaidDebuff Frame +* AuraData - UNIT_AURA event payload +--]] +local function FilterAura(element, AuraData) + if AuraData.dispelName and dispelList[AuraData.dispelName] then + debuffCache[AuraData.auraInstanceID] = true + ShowElement(element, AuraData) end end -local function Update(self, event, unit) - if unit ~= self.unit then return end - local _name, _icon, _count, _dtype, _duration, _endTime, _spellId, _ - local _priority, priority = 0, 0 - local _stackThreshold = 0 - - -- store if the unit its charmed, mind controlled units (Imperial Vizier Zor'lok: Convert) - local isCharmed = UnitIsCharmed(unit) - - -- store if we cand attack that unit, if its so the unit its hostile (Amber-Shaper Un'sok: Reshape Life) - local canAttack = UnitCanAttack("player", unit) - - for i = 1, 40 do - local name, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellId, canApplyAura, isBossDebuff = UnitAura(unit, i, "HARMFUL") - if (not name) then break end - - -- we coudln't dispell if the unit its charmed, or its not friendly - if addon.ShowDispellableDebuff and (self.RaidDebuffs.showDispellableDebuff ~= false) and debuffType and (not isCharmed) and (not canAttack) then - - if addon.FilterDispellableDebuff then - DispellPriority[debuffType] = (DispellPriority[debuffType] or 0) + addon.priority -- make Dispell buffs on top of Boss Debuffs - priority = DispellFilter[debuffType] and DispellPriority[debuffType] or 0 - if priority == 0 then - debuffType = nil - end - else - priority = DispellPriority[debuffType] or 0 - end - - if priority > _priority then - _priority, _name, _icon, _count, _dtype, _duration, _endTime, _spellId = priority, name, icon, count, debuffType, duration, expirationTime, spellId +--[[ Event handler for UNIT_AURA + +* self - Parent UnitFrame +* event - UNIT_AURA +* unit - payload of event: unitTarget +* updateInfo - payload of event: UnitAuraUpdateInfo +--]] +local function Update(self, event, unit, updateInfo) + -- Exit when unit doesn't match or no updateInfo provided or target can't be assisted + if event ~= "UNIT_AURA" or self.unit ~= unit or not updateInfo or not UnitCanAssist("player", unit) then return end + local element = self.RaidDebuffs + + if updateInfo.removedAuraInstanceIDs then + for _, auraInstanceID in pairs(updateInfo.removedAuraInstanceIDs) do + if debuffCache[auraInstanceID] then + debuffCache[auraInstanceID] = nil + HideElement(element) end end + end - local debuff - if self.RaidDebuffs.onlyMatchSpellID then - debuff = debuff_data[spellId] - else - if debuff_data[spellId] then - debuff = debuff_data[spellId] - else - debuff = debuff_data[name] + if updateInfo.updatedAuraInstanceIDs then + for _, auraInstanceID in pairs(updateInfo.updatedAuraInstanceIDs) do + local AuraData = C_UnitAuras.GetAuraDataByAuraInstanceID(unit, auraInstanceID) + if AuraData then + FilterAura(element, AuraData) end end - - priority = debuff and debuff.priority - if priority and not self.RaidDebuffs.BlackList[spellId] and (priority > _priority) then - _priority, _name, _icon, _count, _dtype, _duration, _endTime, _spellId = priority, name, icon, count, debuffType, duration, expirationTime, spellId - end - end - - if self.RaidDebuffs.forceShow then - _spellId = 47540 - _name, _, _icon = GetSpellInfo(_spellId) - _count, _dtype, _duration, _endTime, _stackThreshold = 5, "Magic", 0, 60, 0 end - if _name then - _stackThreshold = debuff_data[addon.MatchBySpellName and _name or _spellId] and debuff_data[addon.MatchBySpellName and _name or _spellId].stackThreshold or _stackThreshold + if updateInfo.addedAuras then + for _, AuraData in pairs(updateInfo.addedAuras) do + FilterAura(element, AuraData) + end end - - UpdateDebuff(self, _name, _icon, _count, _dtype, _duration, _endTime, _spellId, _stackThreshold) - - -- Reset the DispellPriority - DispellPriority["Magic"] = 4 - DispellPriority["Curse"] = 3 - DispellPriority["Disease"] = 2 - DispellPriority["Poison"] = 1 end local function Enable(self) - if self.RaidDebuffs then - self:RegisterEvent("PLAYER_LOGIN", UpdateDispellFilter, true) + local element = self.RaidDebuffs + + if element then + -- Create missing Sub-Widgets + if not element.icon then + element.icon = element:CreateTexture(nil, "ARTWORK") + element.icon:SetTexCoord(.1, .9, .1, .9) + element.icon:SetInside(element) + end + + if not element.cd then + element.cd = CreateFrame("Cooldown", nil, element, "CooldownFrameTemplate") + element.cd:SetInside(element, 1, 0) + element.cd:SetReverse(true) + element.cd:SetHideCountdownNumbers(false) + element.cd:SetAlpha(.7) + end - if oUF.isRetail then - self:RegisterEvent("PLAYER_TALENT_UPDATE", UpdateDispellFilter, true) - self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", UpdateDispellFilter, true) + if not element.count then + element.count = element:CreateFontString(nil, "OVERLAY") + element.count:SetFont(C.Medias.Font, 12, "OUTLINE") + element.count:SetPoint("BOTTOMRIGHT", element, "BOTTOMRIGHT", 2, 0) + element.count:SetTextColor(1, .9, 0) end - if oUF.isClassic then - self:RegisterEvent("CHARACTER_POINTS_CHANGED", UpdateDispellFilter, true) + if not element.Backdrop then + element:CreateBackdrop() end + -- Update the dispelList at login and whenever spells change (talent or spec change) + self:RegisterEvent("SPELLS_CHANGED", UpdateDispelList, true) self:RegisterEvent("UNIT_AURA", Update) - self.RaidDebuffs.BlackList = self.RaidDebuffs.BlackList or { - [105171] = true, -- Deep Corruption - [108220] = true, -- Deep Corruption - [116095] = true, -- Disable, Slow - [137637] = true -- Warbringer, Slow - } + HideElement(element) return true end end local function Disable(self) - if self.RaidDebuffs then - if oUF.isRetail then - self:UnregisterEvent("PLAYER_TALENT_UPDATE", UpdateDispellFilter, true) - self:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED", UpdateDispellFilter, true) - end - - if oUF.isClassic then - self:UnregisterEvent("CHARACTER_POINTS_CHANGED", UpdateDispellFilter, true) - end + local element = self.RaidDebuffs + if element then + self:UnregisterEvent("SPELLS_CHANGED", UpdateDispelList, true) self:UnregisterEvent("UNIT_AURA", Update) - - self.RaidDebuffs:Hide() end end -if not oUF.isRetail then - oUF:AddElement("RaidDebuffs", Update, Enable, Disable) -end \ No newline at end of file +oUF:AddElement("RaidDebuffs", Update, Enable, Disable) \ No newline at end of file diff --git a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs_Retail.lua b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs_Retail.lua deleted file mode 100644 index 729c10af..00000000 --- a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs_Retail.lua +++ /dev/null @@ -1,208 +0,0 @@ ---[=[ - Shows Debuffs on Unit Frames - - Sub Widgets - .icon Icon/Texture of the debuff - .cd Cooldown frame - .count Number of Stacks ---]=] -local _, ns = ... -local oUF = ns.oUF or oUF - - -local IsPlayerSpell = _G.IsPlayerSpell -local UnitCanAssist = _G.UnitCanAssist -local playerClass = UnitClassBase("player") -local debuffColor = DebuffTypeColor -local debuffCache = {} - --- dispel priority? magic <- curse <- poison <- disease - - --- Holds which dispell types can currently be handled --- Initialized to false for all types -local dispellist = { - Magic = false, - Poison = false, - Disease = false, - Curse = false -} - - --- Class functions to update the dispell types which can be handled -local CanDispel = { - DRUID = function() - dispellist["Magic"] = IsPlayerSpell(88423) -- Nature's Cure - dispellist["Poison"] = IsPlayerSpell(392378) or IsPlayerSpell(2782) -- Improved Nature's Cure or Remove Corruption - dispellist["Disease"] = false - dispellist["Curse"] = IsPlayerSpell(392378) or IsPlayerSpell(2782) -- Improved Nature's Cure or Remove Corruption - end, - MAGE = function() - dispellist["Magic"] = false - dispellist["Poison"] = false - dispellist["Disease"] = false - dispellist["Curse"] = IsPlayerSpell(475) -- Remove Curse - end, - MONK = function() - dispellist["Magic"] = IsPlayerSpell(115450) -- Detox - dispellist["Poison"] = IsPlayerSpell(388874) or IsPlayerSpell(218164) -- Improved Detox or Detox - dispellist["Disease"] = IsPlayerSpell(388874) or IsPlayerSpell(218164) -- Improved Detox or Detox - dispellist["Curse"] = false - end, - PALADIN = function() - dispellist["Magic"] = IsPlayerSpell(4987) -- Cleanse - dispellist["Poison"] = IsPlayerSpell(393024) or IsPlayerSpell(213644) -- Improved Cleanse or Cleanse Toxins - dispellist["Disease"] = IsPlayerSpell(393024) or IsPlayerSpell(213644) -- Improved Cleanse or Cleanse Toxins - dispellist["Curse"] = false - end, - PRIEST = function() - dispellist["Magic"] = IsPlayerSpell(527) -- Purify - dispellist["Poison"] = false - dispellist["Disease"] = IsPlayerSpell(390632) or IsPlayerSpell(213634) -- Improved Purify or Purify Disease - dispellist["Curse"] = false - end, - SHAMAN = function() - dispellist["Magic"] = IsPlayerSpell(77130) -- Purify Spirit - dispellist["Poison"] = IsPlayerSpell(383013) -- Poison Cleansing Totem - dispellist["Disease"] = false - dispellist["Curse"] = IsPlayerSpell(383016) or IsPlayerSpell(51886) -- Improved Purify Spirit or Cleanse Spirit - end, - EVOKER = function() - dispellist["Magic"] = IsPlayerSpell(360823) -- Naturalize - dispellist["Poison"] = IsPlayerSpell(360823) or IsPlayerSpell(365585) or IsPlayerSpell(374251) -- Naturalize or Expunge or Cauterizing Flame - dispellist["Disease"] = IsPlayerSpell(374251) -- Cauterizing Flame - dispellist["Curse"] = IsPlayerSpell(374251) -- Cauterizing Flame - end -} - - --- Event handler for Player Login and Speels Changed -local function UpdateDispelList(self, event) - if event == "PLAYER_LOGIN" or event == "SPELLS_CHANGED" then - CanDispel[playerClass]() - end -end - - --- Show the debuff --- @self UnitFrame --- @AuraData AuraData object provided by UNIT_AURA event -local function Set(self, AuraData) - local element = self.RaidDebuffs - - local count = AuraData.applications - local duration = AuraData.duration - local color = debuffColor[AuraData.dispelName] - - element.icon:SetTexture(AuraData.icon) - element.Backdrop:SetBorderColor(color.r, color.g, color.b) - - if duration and duration > 0 then - element.cd:SetCooldown(AuraData.expirationTime - duration, duration) - end - - if count and count > 1 then - element.count:SetText(count) - end - - element:Show() -end - - --- Hide the debuff --- @self UnitFrame -local function Reset(self) - local element = self.RaidDebuffs - local color = debuffColor["none"] - - element.Backdrop:SetBorderColor(color.r, color.g, color.b) - element.cd:SetCooldown(0, 0) - element.count:SetText("") - - element:Hide() -end - - --- Event handler for Unit Aura --- @self UnitFrame --- @event UNIT_AURA --- @unit payload of event: unitTarget --- @updateInfo payload of event: UnitAuraUpdateInfo -local function Update(self, event, unit, updateInfo) - -- Exit when unit doesn't match or no updateInfo provided or target can't be assisted - if event ~= "UNIT_AURA" or self.unit ~= unit or not updateInfo or not UnitCanAssist("player", unit) then return end - local element = self.RaidDebuffs - - if updateInfo.removedAuraInstanceIDs then - for _, auraInstanceID in pairs(updateInfo.removedAuraInstanceIDs) do - if debuffCache[auraInstanceID] then - debuffCache[auraInstanceID] = nil - Reset(self) - end - end - end - - if updateInfo.addedAuras then - for _, AuraData in pairs(updateInfo.addedAuras) do - if AuraData.dispelName and dispellist[AuraData.dispelName] then - debuffCache[AuraData.auraInstanceID] = true - Set(self, AuraData) - end - end - end -end - - --- oUF Enable function -local function Enable(self) - local element = self.RaidDebuffs - - if oUF.isRetail and element and CanDispel[playerClass] then - element:CreateBackdrop() - - if not element.icon then - element.icon = element:CreateTexture(nil, "ARTWORK") - element.icon:SetTexCoord(.1, .9, .1, .9) - element.icon:SetInside(element) - end - - if not element.cd then - element.cd = CreateFrame("Cooldown", nil, element, "CooldownFrameTemplate") - element.cd:SetInside(element, 1, 0) - element.cd:SetReverse(true) - element.cd:SetHideCountdownNumbers(false) - element.cd:SetAlpha(.7) - end - - if not element.count then - element.count = element:CreateFontString(nil, "OVERLAY") - element.count:SetFont(C.Medias.Font, 12, "OUTLINE") - element.count:SetPoint("BOTTOMRIGHT", element, "BOTTOMRIGHT", 2, 0) - element.count:SetTextColor(1, .9, 0) - end - - -- Update the dispelList at login and whenever spells change (talent or spec change) - self:RegisterEvent("PLAYER_LOGIN", UpdateDispelList, true) - self:RegisterEvent("SPELLS_CHANGED", UpdateDispelList, true) - self:RegisterEvent("UNIT_AURA", Update) - - return true - end -end - - --- oUF Disable function -local function Disable(self) - local element = self.DebuffHighlight - - if element then - self:UnregisterEvent("PLAYER_LOGIN", UpdateDispelList, true) - self:UnregisterEvent("SPELLS_CHANGED", UpdateDispelList, true) - self:UnregisterEvent("UNIT_AURA", Update) - end -end - - -if oUF.isRetail then - oUF:AddElement("RaidDebuffs", Update, Enable, Disable) -end \ No newline at end of file diff --git a/Tukui/Libs/oUF_Retail/init.lua b/Tukui/Libs/oUF_Retail/init.lua index 3684275c..bcdbf00a 100644 --- a/Tukui/Libs/oUF_Retail/init.lua +++ b/Tukui/Libs/oUF_Retail/init.lua @@ -1,3 +1,6 @@ local _, ns = ... ns.oUF = {} ns.oUF.Private = {} + +ns.oUF.isRetail = (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) +ns.oUF.isClassic = (WOW_PROJECT_ID == WOW_PROJECT_CLASSIC) \ No newline at end of file diff --git a/Tukui/Modules/UnitFrames/Groups/Raid.lua b/Tukui/Modules/UnitFrames/Groups/Raid.lua index ff5958c7..28f37e79 100644 --- a/Tukui/Modules/UnitFrames/Groups/Raid.lua +++ b/Tukui/Modules/UnitFrames/Groups/Raid.lua @@ -132,29 +132,18 @@ function UnitFrames:Raid() RaidDebuffs:SetWidth(DebuffSize) RaidDebuffs:SetPoint("CENTER", Health) RaidDebuffs:SetFrameLevel(Health:GetFrameLevel() + 10) - RaidDebuffs:CreateBackdrop() - RaidDebuffs:CreateShadow() - RaidDebuffs.Shadow:SetFrameLevel(RaidDebuffs:GetFrameLevel() + 1) RaidDebuffs.icon = RaidDebuffs:CreateTexture(nil, "ARTWORK") RaidDebuffs.icon:SetTexCoord(.1, .9, .1, .9) RaidDebuffs.icon:SetInside(RaidDebuffs) RaidDebuffs.cd = CreateFrame("Cooldown", nil, RaidDebuffs, "CooldownFrameTemplate") RaidDebuffs.cd:SetInside(RaidDebuffs, 1, 0) RaidDebuffs.cd:SetReverse(true) - RaidDebuffs.cd.noOCC = true - RaidDebuffs.cd.noCooldownCount = true RaidDebuffs.cd:SetHideCountdownNumbers(true) RaidDebuffs.cd:SetAlpha(.7) - RaidDebuffs.onlyMatchSpellID = true - RaidDebuffs.showDispellableDebuff = true - RaidDebuffs.time = RaidDebuffs:CreateFontString(nil, "OVERLAY") - RaidDebuffs.time:SetFont(C.Medias.Font, 12, "OUTLINE") - RaidDebuffs.time:SetPoint("CENTER", RaidDebuffs, 1, 0) RaidDebuffs.count = RaidDebuffs:CreateFontString(nil, "OVERLAY") RaidDebuffs.count:SetFont(C.Medias.Font, 12, "OUTLINE") RaidDebuffs.count:SetPoint("BOTTOMRIGHT", RaidDebuffs, "BOTTOMRIGHT", 2, 0) RaidDebuffs.count:SetTextColor(1, .9, 0) - --RaidDebuffs.forceShow = true self.RaidDebuffs = RaidDebuffs end diff --git a/Tukui/Tukui-Mainline.toc b/Tukui/Tukui-Mainline.toc index 1b930762..1a859266 100644 --- a/Tukui/Tukui-Mainline.toc +++ b/Tukui/Tukui-Mainline.toc @@ -66,7 +66,6 @@ Libs\oUF_Retail\finalize.lua Libs\oUF_ComboPointsBar\oUF_ComboPointsBar.lua Libs\oUF_CombatFeedback\oUF_CombatFeedback.lua Libs\oUF_RaidDebuffs\oUF_RaidDebuffs.lua -Libs\oUF_RaidDebuffs\oUF_RaidDebuffs_Retail.lua Libs\oUF_FloatingCombatFeedback\oUF_FloatingCombatFeedback.lua Libs\oUF_AuraBars\oUF_AuraBars.lua Libs\oUF_ArcaneCharge\oUF_ArcaneCharge.lua From cce7f5946ba861c6e6095ec97fd6bc0b6a758da7 Mon Sep 17 00:00:00 2001 From: JerichoR Date: Sat, 14 Sep 2024 15:18:25 +0200 Subject: [PATCH 3/7] Added handling of priority and simultanous debuffs. Added duration text. --- .../Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua | 170 ++++++++++++++---- Tukui/Libs/oUF_Retail/init.lua | 8 +- Tukui/Modules/UnitFrames/Groups/Raid.lua | 3 + 3 files changed, 141 insertions(+), 40 deletions(-) diff --git a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua index b2f5a03b..23053058 100644 --- a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua +++ b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua @@ -3,27 +3,39 @@ Sub-Widgets will be created if not provided. + Member Variables + .font Font details used for timer and stacks + .fontheight | used if Sub-Widgets aren't provided + .fontFlags | not needed otherwise + Sub-Widgets .icon The Icon/Texture of the debuff - .cd A Cooldown frame showing the duration + .cd A Cooldown frame + .timer A Text showing the remaining duration .count A Text showing the number of stacks - .Backdrop Backdrop + .Backdrop Backdrops border is used to indicate the debuff type --]=] local _, ns = ... local oUF = ns.oUF or oUF local IsPlayerSpell = _G.IsPlayerSpell local UnitCanAssist = _G.UnitCanAssist -local playerClass = UnitClassBase("player") +local GetTime = _G.GetTime +local playerClass = _G.UnitClassBase("player") +local GetAuraDataByAuraInstanceID = _G.C_UnitAuras.GetAuraDataByAuraInstanceID +local NewTicker = _G.C_Timer.NewTicker local debuffColor = DebuffTypeColor local debuffCache = {} --- dispel priority? magic <- curse <- poison <- disease - ---[[ Holds which dispel types can currently be handled +--[[ Holds the dispel priority list ]]-- +local priorityList = { + Magic = 4, + Curse = 3, + Poison = 2, + Disease = 1, +} -Initialized to false for all types ---]] +--[[ Holds which dispel types can currently be handled. Initialized to false for all. ]]-- local dispelList = { Magic = false, Poison = false, @@ -31,7 +43,7 @@ local dispelList = { Curse = false, } ---[[ Class functions to update the dispel types which can be handled ]]-- +--[[ Class functions to update the dispel types which can be handled. ]]-- local canDispel = { DRUID = { retail = function() @@ -177,8 +189,8 @@ local canDispel = { --[[ Event handler for SPELLS_CHANGED -* self - Parent UnitFrame -* event - SPELLS_CHANGED +* self - oUF UnitFrame +* event - SPELLS_CHANGED --]] local function UpdateDispelList(self, event) if event == "SPELLS_CHANGED" then @@ -187,14 +199,32 @@ local function UpdateDispelList(self, event) end end ---[[ Show the debuff +--[[ Returns a format string for timers. -* element - RaidDebuff Frame -* AuraData - AuraData object provided by UNIT_AURA event +* time - Time in seconds --]] -local function ShowElement(element, AuraData) +local function timeFormat(time) + if time < 3 then + return "%.1f" + elseif time < 60 then + return "%d" + else + return "++" + end +end + +--[[ Show the debuff element. + +* self - oUF UnitFrame +* unit - Tracked unit +* auraInstanceID - auraInstanceID of the debuff to be displayed +--]] +local function ShowElement(self, unit, auraInstanceID) + local element = self.RaidDebuffs + local AuraData = debuffCache[auraInstanceID].AuraData local count = AuraData.applications local duration = AuraData.duration + local expirationTime = AuraData.expirationTime local color = debuffColor[AuraData.dispelName] element.icon:SetTexture(AuraData.icon) @@ -202,7 +232,14 @@ local function ShowElement(element, AuraData) element:Show() if duration and duration > 0 then - element.cd:SetCooldown(AuraData.expirationTime - duration, duration) + local start = expirationTime - duration + element.cd:SetCooldown(start, duration) + + if element.ticker then element.ticker:Cancel() end + element.ticker = NewTicker(.1, function() + local remaining = expirationTime - GetTime() + element.timer:SetFormattedText(timeFormat(remaining), remaining) + end) end if count and count > 1 then @@ -210,65 +247,114 @@ local function ShowElement(element, AuraData) end end ---[[ Hide the debuff +--[[ Hide the debuff element. -* element - RaidDebuff Frame +* self - oUF UnitFrame +* unit - Tracked unit --]] -local function HideElement(element) +local function HideElement(self, unit) + local element = self.RaidDebuffs local color = debuffColor["none"] + if element.ticker then element.ticker:Cancel() end + element.Backdrop:SetBorderColor(color.r, color.g, color.b) element.cd:SetCooldown(0, 0) + element.timer:SetText("") element.count:SetText("") element:Hide() end ---[[ Filter for dispellable debuffs +--[[ Select the Debuff with highest priority to display, hide element when none left. + +* self - oUF UnitFrame +* unit - Tracked unit +--]] +local function SelectPrioDebuff(self, unit) + local auraInstanceID = nil + local priority = 0 + + -- find debuff with highest priority + for id, debuff in pairs(debuffCache) do + if priority < debuff.priority then + auraInstanceID = id + priority = debuff.priority + end + end + + if auraInstanceID then + ShowElement(self, unit, auraInstanceID) + else + HideElement(self, unit) + end +end + +--[[ Filter for dispellable debuffs. -* element - RaidDebuff Frame -* AuraData - UNIT_AURA event payload +* self - oUF UnitFrame +* unit - Tracked unit +* auraInstanceID - auraInstanceID +* AuraData - (optional) UNIT_AURA event payload --]] -local function FilterAura(element, AuraData) - if AuraData.dispelName and dispelList[AuraData.dispelName] then - debuffCache[AuraData.auraInstanceID] = true - ShowElement(element, AuraData) +local function FilterAura(self, unit, auraInstanceID, AuraData) + AuraData = AuraData or GetAuraDataByAuraInstanceID(unit, auraInstanceID) + local dispelName = AuraData.dispelName + + if dispelName and dispelList[dispelName] then + debuffCache[auraInstanceID] = { + priority = priorityList[dispelName], + AuraData = AuraData + } + SelectPrioDebuff(self, unit) end end ---[[ Event handler for UNIT_AURA +--[[ Aura scan when isFullUpdate + +* self - oUF UnitFrame +* unit - Tracked unit +--]] +local function FullUpdate(self, unit) -* self - Parent UnitFrame +end + +--[[ Event handler for UNIT_AURA. + +* self - oUF UnitFrame * event - UNIT_AURA -* unit - payload of event: unitTarget -* updateInfo - payload of event: UnitAuraUpdateInfo +* unit - Payload of event: unitTarget +* updateInfo - Payload of event: UnitAuraUpdateInfo --]] local function Update(self, event, unit, updateInfo) -- Exit when unit doesn't match or no updateInfo provided or target can't be assisted if event ~= "UNIT_AURA" or self.unit ~= unit or not updateInfo or not UnitCanAssist("player", unit) then return end - local element = self.RaidDebuffs + + if updateInfo.isFullUpdate then + FullUpdate(self, unit) + return + end if updateInfo.removedAuraInstanceIDs then for _, auraInstanceID in pairs(updateInfo.removedAuraInstanceIDs) do if debuffCache[auraInstanceID] then debuffCache[auraInstanceID] = nil - HideElement(element) + SelectPrioDebuff(self, unit) end end end if updateInfo.updatedAuraInstanceIDs then for _, auraInstanceID in pairs(updateInfo.updatedAuraInstanceIDs) do - local AuraData = C_UnitAuras.GetAuraDataByAuraInstanceID(unit, auraInstanceID) - if AuraData then - FilterAura(element, AuraData) + if auraInstanceID then + FilterAura(self, unit, auraInstanceID) end end end if updateInfo.addedAuras then for _, AuraData in pairs(updateInfo.addedAuras) do - FilterAura(element, AuraData) + FilterAura(self, unit, AuraData.auraInstanceID, AuraData) end end end @@ -288,13 +374,19 @@ local function Enable(self) element.cd = CreateFrame("Cooldown", nil, element, "CooldownFrameTemplate") element.cd:SetInside(element, 1, 0) element.cd:SetReverse(true) - element.cd:SetHideCountdownNumbers(false) + element.cd:SetHideCountdownNumbers(true) element.cd:SetAlpha(.7) end + if not element.timer then + element.timer = element:CreateFontString(nil, "OVERLAY") + element.timer:SetFont(element.font, element.fontHeight, element.fontFlags) + element.timer:SetPoint("CENTER", element, 1, 0) + end + if not element.count then element.count = element:CreateFontString(nil, "OVERLAY") - element.count:SetFont(C.Medias.Font, 12, "OUTLINE") + element.count:SetFont(element.font, element.fontHeight, element.fontFlags) element.count:SetPoint("BOTTOMRIGHT", element, "BOTTOMRIGHT", 2, 0) element.count:SetTextColor(1, .9, 0) end @@ -307,7 +399,7 @@ local function Enable(self) self:RegisterEvent("SPELLS_CHANGED", UpdateDispelList, true) self:RegisterEvent("UNIT_AURA", Update) - HideElement(element) + HideElement(self, self.unit) return true end diff --git a/Tukui/Libs/oUF_Retail/init.lua b/Tukui/Libs/oUF_Retail/init.lua index bcdbf00a..a544d0c5 100644 --- a/Tukui/Libs/oUF_Retail/init.lua +++ b/Tukui/Libs/oUF_Retail/init.lua @@ -2,5 +2,11 @@ local _, ns = ... ns.oUF = {} ns.oUF.Private = {} +local Interface = select(4, GetBuildInfo()) + +ns.oUF.Interface = Interface ns.oUF.isRetail = (WOW_PROJECT_ID == WOW_PROJECT_MAINLINE) -ns.oUF.isClassic = (WOW_PROJECT_ID == WOW_PROJECT_CLASSIC) \ No newline at end of file +ns.oUF.isClassic = (WOW_PROJECT_ID == WOW_PROJECT_CLASSIC) +ns.oUF.isBCC = (WOW_PROJECT_ID == WOW_PROJECT_BURNING_CRUSADE_CLASSIC) or (Interface >= 20000 and Interface < 30000) -- unused +ns.oUF.isWotLK = (WOW_PROJECT_ID == WOW_PROJECT_WRATH_CLASSIC) or (Interface >= 30000 and Interface < 40000) -- used in runes element +ns.oUF.isDF = (Interface >= 100000 and Interface < 110000) -- unused \ No newline at end of file diff --git a/Tukui/Modules/UnitFrames/Groups/Raid.lua b/Tukui/Modules/UnitFrames/Groups/Raid.lua index 28f37e79..b02bdbd4 100644 --- a/Tukui/Modules/UnitFrames/Groups/Raid.lua +++ b/Tukui/Modules/UnitFrames/Groups/Raid.lua @@ -140,6 +140,9 @@ function UnitFrames:Raid() RaidDebuffs.cd:SetReverse(true) RaidDebuffs.cd:SetHideCountdownNumbers(true) RaidDebuffs.cd:SetAlpha(.7) + RaidDebuffs.time = RaidDebuffs:CreateFontString(nil, "OVERLAY") + RaidDebuffs.time:SetFont(C.Medias.Font, 12, "OUTLINE") + RaidDebuffs.time:SetPoint("CENTER", RaidDebuffs, 1, 0) RaidDebuffs.count = RaidDebuffs:CreateFontString(nil, "OVERLAY") RaidDebuffs.count:SetFont(C.Medias.Font, 12, "OUTLINE") RaidDebuffs.count:SetPoint("BOTTOMRIGHT", RaidDebuffs, "BOTTOMRIGHT", 2, 0) From 7893d87cd4d5b598193991e7b06d0c4e23a513af Mon Sep 17 00:00:00 2001 From: JerichoR Date: Sat, 14 Sep 2024 16:00:08 +0200 Subject: [PATCH 4/7] Added FullUpdate scan --- .../Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua index 23053058..cd15513f 100644 --- a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua +++ b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua @@ -18,13 +18,21 @@ local _, ns = ... local oUF = ns.oUF or oUF -local IsPlayerSpell = _G.IsPlayerSpell -local UnitCanAssist = _G.UnitCanAssist -local GetTime = _G.GetTime -local playerClass = _G.UnitClassBase("player") -local GetAuraDataByAuraInstanceID = _G.C_UnitAuras.GetAuraDataByAuraInstanceID -local NewTicker = _G.C_Timer.NewTicker -local debuffColor = DebuffTypeColor +local IsPlayerSpell = _G.IsPlayerSpell +local UnitCanAssist = _G.UnitCanAssist +local GetTime = _G.GetTime +local playerClass = _G.UnitClassBase("player") +local GetAuraDataByAuraInstanceID = _G.C_UnitAuras.GetAuraDataByAuraInstanceID +local GetAuraDataByIndex = _G.C_UnitAuras.GetAuraDataByIndex +local ForEachAura = _G.AuraUtil.ForEachAura +local NewTicker = _G.C_Timer.NewTicker +local debuffColor = _G.DebuffTypeColor + +--[[ Cache for active debuffs + + .priority - See priorityList + .AuraData - See UNIT_AURA event payload +--]] local debuffCache = {} --[[ Holds the dispel priority list ]]-- @@ -316,7 +324,25 @@ end * unit - Tracked unit --]] local function FullUpdate(self, unit) - + if ForEachAura then + -- Mainline iteration-style. + ForEachAura(unit, "HARMFUL", nil, + function(AuraData) + FilterAura(self, unit, AuraData.auraInstanceID, AuraData) + end, + true) + else + -- Classic iteration-style. + local AuraData + local i = 1 + repeat + AuraData = GetAuraDataByIndex(unit, i, "HARMFUL") + if AuraData then + FilterAura(self, unit, AuraData.auraInstanceID, AuraData) + end + i = i + 1 + until not AuraData + end end --[[ Event handler for UNIT_AURA. From 4ca4a8e9ee8504f0289dcc3382fa0ac63c6c3b95 Mon Sep 17 00:00:00 2001 From: JerichoR Date: Sat, 14 Sep 2024 21:15:07 +0200 Subject: [PATCH 5/7] fixed a missed rename --- Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua | 2 +- Tukui/Modules/UnitFrames/Groups/Raid.lua | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua index cd15513f..98c8ded9 100644 --- a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua +++ b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua @@ -388,7 +388,7 @@ end local function Enable(self) local element = self.RaidDebuffs - if element then + if element and canDispel[playerClass] then -- Create missing Sub-Widgets if not element.icon then element.icon = element:CreateTexture(nil, "ARTWORK") diff --git a/Tukui/Modules/UnitFrames/Groups/Raid.lua b/Tukui/Modules/UnitFrames/Groups/Raid.lua index b02bdbd4..8eefc820 100644 --- a/Tukui/Modules/UnitFrames/Groups/Raid.lua +++ b/Tukui/Modules/UnitFrames/Groups/Raid.lua @@ -140,9 +140,9 @@ function UnitFrames:Raid() RaidDebuffs.cd:SetReverse(true) RaidDebuffs.cd:SetHideCountdownNumbers(true) RaidDebuffs.cd:SetAlpha(.7) - RaidDebuffs.time = RaidDebuffs:CreateFontString(nil, "OVERLAY") - RaidDebuffs.time:SetFont(C.Medias.Font, 12, "OUTLINE") - RaidDebuffs.time:SetPoint("CENTER", RaidDebuffs, 1, 0) + RaidDebuffs.timer = RaidDebuffs:CreateFontString(nil, "OVERLAY") + RaidDebuffs.timer:SetFont(C.Medias.Font, 12, "OUTLINE") + RaidDebuffs.timer:SetPoint("CENTER", RaidDebuffs, 1, 0) RaidDebuffs.count = RaidDebuffs:CreateFontString(nil, "OVERLAY") RaidDebuffs.count:SetFont(C.Medias.Font, 12, "OUTLINE") RaidDebuffs.count:SetPoint("BOTTOMRIGHT", RaidDebuffs, "BOTTOMRIGHT", 2, 0) From c0f2f55691b2b32f18bf4e4eb904887b45feec4c Mon Sep 17 00:00:00 2001 From: JerichoR Date: Sun, 15 Sep 2024 12:00:30 +0200 Subject: [PATCH 6/7] Moved cache to individual element, not shared between multiple ones. --- .../Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua index 98c8ded9..072c329c 100644 --- a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua +++ b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua @@ -28,14 +28,7 @@ local ForEachAura = _G.AuraUtil.ForEachAura local NewTicker = _G.C_Timer.NewTicker local debuffColor = _G.DebuffTypeColor ---[[ Cache for active debuffs - - .priority - See priorityList - .AuraData - See UNIT_AURA event payload ---]] -local debuffCache = {} - ---[[ Holds the dispel priority list ]]-- +--[[ Holds the dispel priority list. ]] local priorityList = { Magic = 4, Curse = 3, @@ -43,7 +36,7 @@ local priorityList = { Disease = 1, } ---[[ Holds which dispel types can currently be handled. Initialized to false for all. ]]-- +--[[ Holds which dispel types can currently be handled. Initialized to false for all. ]] local dispelList = { Magic = false, Poison = false, @@ -51,7 +44,7 @@ local dispelList = { Curse = false, } ---[[ Class functions to update the dispel types which can be handled. ]]-- +--[[ Class functions to update the dispel types which can be handled. ]] local canDispel = { DRUID = { retail = function() @@ -195,11 +188,11 @@ local canDispel = { } } ---[[ Event handler for SPELLS_CHANGED +--[[ Event handler for SPELLS_CHANGED. * self - oUF UnitFrame * event - SPELLS_CHANGED ---]] +]] local function UpdateDispelList(self, event) if event == "SPELLS_CHANGED" then local project = (oUF.isRetail and "retail") or (oUF.isClassic and "classic") or "other" @@ -210,7 +203,7 @@ end --[[ Returns a format string for timers. * time - Time in seconds ---]] +]] local function timeFormat(time) if time < 3 then return "%.1f" @@ -226,10 +219,10 @@ end * self - oUF UnitFrame * unit - Tracked unit * auraInstanceID - auraInstanceID of the debuff to be displayed ---]] +]] local function ShowElement(self, unit, auraInstanceID) local element = self.RaidDebuffs - local AuraData = debuffCache[auraInstanceID].AuraData + local AuraData = element.debuffCache[auraInstanceID].AuraData local count = AuraData.applications local duration = AuraData.duration local expirationTime = AuraData.expirationTime @@ -259,7 +252,7 @@ end * self - oUF UnitFrame * unit - Tracked unit ---]] +]] local function HideElement(self, unit) local element = self.RaidDebuffs local color = debuffColor["none"] @@ -278,8 +271,9 @@ end * self - oUF UnitFrame * unit - Tracked unit ---]] +]] local function SelectPrioDebuff(self, unit) + local debuffCache = self.RaidDebuffs.debuffCache local auraInstanceID = nil local priority = 0 @@ -304,9 +298,10 @@ end * unit - Tracked unit * auraInstanceID - auraInstanceID * AuraData - (optional) UNIT_AURA event payload ---]] +]] local function FilterAura(self, unit, auraInstanceID, AuraData) AuraData = AuraData or GetAuraDataByAuraInstanceID(unit, auraInstanceID) + local debuffCache = self.RaidDebuffs.debuffCache local dispelName = AuraData.dispelName if dispelName and dispelList[dispelName] then @@ -318,11 +313,11 @@ local function FilterAura(self, unit, auraInstanceID, AuraData) end end ---[[ Aura scan when isFullUpdate +--[[ Aura scan when isFullUpdate. * self - oUF UnitFrame * unit - Tracked unit ---]] +]] local function FullUpdate(self, unit) if ForEachAura then -- Mainline iteration-style. @@ -351,7 +346,7 @@ end * event - UNIT_AURA * unit - Payload of event: unitTarget * updateInfo - Payload of event: UnitAuraUpdateInfo ---]] +]] local function Update(self, event, unit, updateInfo) -- Exit when unit doesn't match or no updateInfo provided or target can't be assisted if event ~= "UNIT_AURA" or self.unit ~= unit or not updateInfo or not UnitCanAssist("player", unit) then return end @@ -362,6 +357,7 @@ local function Update(self, event, unit, updateInfo) end if updateInfo.removedAuraInstanceIDs then + local debuffCache = self.RaidDebuffs.debuffCache for _, auraInstanceID in pairs(updateInfo.removedAuraInstanceIDs) do if debuffCache[auraInstanceID] then debuffCache[auraInstanceID] = nil @@ -389,6 +385,15 @@ local function Enable(self) local element = self.RaidDebuffs if element and canDispel[playerClass] then + --[[ Cache for active debuffs. + + table + aura = { + .priority - See priorityList + .AuraData - See UNIT_AURA event payload + }]] + element.debuffCache = {} + -- Create missing Sub-Widgets if not element.icon then element.icon = element:CreateTexture(nil, "ARTWORK") @@ -435,6 +440,7 @@ local function Disable(self) local element = self.RaidDebuffs if element then + element.debuffCache = nil self:UnregisterEvent("SPELLS_CHANGED", UpdateDispelList, true) self:UnregisterEvent("UNIT_AURA", Update) end From 34cbdf9e56ff2b0fbdcf5b302f192d25362cac01 Mon Sep 17 00:00:00 2001 From: JerichoR Date: Sun, 15 Sep 2024 20:45:59 +0200 Subject: [PATCH 7/7] Added a check if AuraData was populated --- .../Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua index 072c329c..ccec4fb5 100644 --- a/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua +++ b/Tukui/Libs/oUF_RaidDebuffs/oUF_RaidDebuffs.lua @@ -296,20 +296,20 @@ end * self - oUF UnitFrame * unit - Tracked unit -* auraInstanceID - auraInstanceID * AuraData - (optional) UNIT_AURA event payload ]] -local function FilterAura(self, unit, auraInstanceID, AuraData) - AuraData = AuraData or GetAuraDataByAuraInstanceID(unit, auraInstanceID) - local debuffCache = self.RaidDebuffs.debuffCache - local dispelName = AuraData.dispelName - - if dispelName and dispelList[dispelName] then - debuffCache[auraInstanceID] = { - priority = priorityList[dispelName], - AuraData = AuraData - } - SelectPrioDebuff(self, unit) +local function FilterAura(self, unit, AuraData) + if AuraData then + local debuffCache = self.RaidDebuffs.debuffCache + local dispelName = AuraData.dispelName + + if dispelName and dispelList[dispelName] then + debuffCache[AuraData.auraInstanceID] = { + priority = priorityList[dispelName], + AuraData = AuraData + } + SelectPrioDebuff(self, unit) + end end end @@ -323,7 +323,7 @@ local function FullUpdate(self, unit) -- Mainline iteration-style. ForEachAura(unit, "HARMFUL", nil, function(AuraData) - FilterAura(self, unit, AuraData.auraInstanceID, AuraData) + FilterAura(self, unit, AuraData) end, true) else @@ -333,7 +333,7 @@ local function FullUpdate(self, unit) repeat AuraData = GetAuraDataByIndex(unit, i, "HARMFUL") if AuraData then - FilterAura(self, unit, AuraData.auraInstanceID, AuraData) + FilterAura(self, unit, AuraData) end i = i + 1 until not AuraData @@ -369,14 +369,14 @@ local function Update(self, event, unit, updateInfo) if updateInfo.updatedAuraInstanceIDs then for _, auraInstanceID in pairs(updateInfo.updatedAuraInstanceIDs) do if auraInstanceID then - FilterAura(self, unit, auraInstanceID) + FilterAura(self, unit, GetAuraDataByAuraInstanceID(unit, auraInstanceID)) end end end if updateInfo.addedAuras then for _, AuraData in pairs(updateInfo.addedAuras) do - FilterAura(self, unit, AuraData.auraInstanceID, AuraData) + FilterAura(self, unit, AuraData) end end end