From 31c95606d07dbd989ceef8f8d186e3f821030b18 Mon Sep 17 00:00:00 2001 From: Brues <5278969+brues-code@users.noreply.github.com> Date: Sun, 5 Jul 2026 23:47:39 -0500 Subject: [PATCH] Refactor turtle/Nampower checks and libdebuff cleanup Replace ad-hoc Turtle/Nampower detection with global TURTLE_WOW_VERSION and EventUtil startup flow. Remove legacy IsTurtleWoW and manual PLAYER_ENTERING_WORLD frame; use EventUtil.ContinueOnPlayerLogin. Clean up libdebuff by removing combo-point capture, GetEnhancedDebuffs API, and noisy startup messages; rely on Nampower/AURA_CAST and database fallback for durations. Fix tooltip compare shift handling (cache shift state and pass through). Update xpbar to use TURTLE_WOW_VERSION. Purpose: simplify startup, avoid duplicated logic, and rely on modern APIs for accurate durations. --- api/api.lua | 4 -- libs/libdebuff.lua | 121 +++-------------------------------------- modules/eqcompare.lua | 7 ++- modules/turtle-wow.lua | 60 +------------------- modules/xpbar.lua | 2 +- 5 files changed, 13 insertions(+), 181 deletions(-) diff --git a/api/api.lua b/api/api.lua index 1499a6d1..4f5e460f 100644 --- a/api/api.lua +++ b/api/api.lua @@ -28,10 +28,6 @@ function pfUI.api.HasNampower() return GetNampowerVersion and true or false end -function pfUI.api.IsTurtleWoW() - return C_Spell.GetSpellTexture(46050) == "Interface\\Icons\\Trade_Survival" -end - -- [ GetUnitDistance ] -- Returns distance to unit using best available method -- 'unit1' [string] first unit (default: "player") diff --git a/libs/libdebuff.lua b/libs/libdebuff.lua index 21c86eb8..7187f51a 100644 --- a/libs/libdebuff.lua +++ b/libs/libdebuff.lua @@ -14,7 +14,7 @@ setfenv(1, pfUI:GetEnvironment()) -- The public per-aura readers (UnitDebuff, UnitOwnDebuff) were retired in favor -- of ClassicAPI's C_UnitAuras (which now provides sourceUnit/sourceGUID and -- non-player expirationTime). What remains in libdebuff is the cast-event --- bookkeeping consumed by GetBestAuraCast / GetEnhancedDebuffs and the +-- bookkeeping consumed by GetBestAuraCast (libpredict HoT tracking) and the -- libdebuff_*_hooks broadcast surface (subscribers in actionbar / swingtimer -- / libtotem react to SPELL_GO and SPELL_FAILED). @@ -43,13 +43,7 @@ if GetNampowerVersion then end end --- Nampower startup check: show version info and ensure CVars are set. --- Runs the frame after PLAYER_ENTERING_WORLD so Nampower has finished initializing. -local nampowerCheckFrame = CreateFrame("Frame") -nampowerCheckFrame:RegisterEvent("PLAYER_ENTERING_WORLD") -nampowerCheckFrame:SetScript("OnEvent", function() - this:UnregisterAllEvents() - this:SetScript("OnEvent", nil) +EventUtil.ContinueOnPlayerLogin(function() RunNextFrame(function() if GetNampowerVersion then @@ -58,8 +52,6 @@ nampowerCheckFrame:SetScript("OnEvent", function() local versionString = major .. "." .. minor .. "." .. patch if major > 3 or (major == 3 and minor > 0) or (major == 3 and minor == 0 and patch >= 0) then - DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99[libdebuff]|r Nampower v" .. versionString .. " detected - GetUnitField mode enabled!") - if SetCVar and GetCVar then local cvarsToEnable = { "NP_EnableSpellStartEvents", @@ -89,8 +81,6 @@ nampowerCheckFrame:SetScript("OnEvent", function() if enabledCount > 0 then DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99[libdebuff]|r Enabled " .. enabledCount .. " Nampower CVars") - elseif alreadyEnabledCount == table.getn(cvarsToEnable) then - DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99[libdebuff]|r All required Nampower CVars already enabled") end if failedCount > 0 then DEFAULT_CHAT_FRAME:AddMessage("|cffffcc00[libdebuff]|r Warning: Could not check/set " .. failedCount .. " CVars") @@ -202,10 +192,6 @@ pfUI.libdebuff_spell_cast_hooks = pfUI.libdebuff_spell_cast_hooks or {} pfUI.libdebuff_downrank_blocked_hooks = pfUI.libdebuff_downrank_blocked_hooks or {} local AURA_CAST_DEDUPE_WINDOW = 0.1 -- Ignore duplicates within 100ms --- Captured combo points from SPELL_CAST_EVENT (before client consumes them) --- SPELL_CAST_EVENT fires BEFORE UnitAura updates, so GetComboPoints() still works -local capturedCP = nil - -- Pending cast info for libpredict (heal prediction target tracking) -- SPELL_CAST_EVENT fires with targetGuid BEFORE SPELLCAST_START, -- which allows libpredict to know the correct target for queued casts. @@ -278,40 +264,10 @@ local debuffOverwritePairs = { ["Demoralizing Roar"] = "Demoralizing Shout", } --- Combopoint-based abilities: Only show timers for OUR casts --- Format: [spellName] = { base = N, perCP = N } --- Duration formula: duration = base + combopoints * perCP -local combopointAbilities = { - -- Druid - ["Rip"] = { base = 8, perCP = 2 }, - - -- Rogue - ["Rupture"] = { base = 6, perCP = 2 }, - ["Kidney Shot"] = { base = 1, perCP = 1 }, - ["Slice and Dice"] = { base = 9, perCP = 3 }, - ["Expose Armor"] = { base = 30, perCP = 0 }, -- fixed 30s -} - -- ============================================================================ -- HELPER FUNCTIONS -- ============================================================================ --- Check if spell is a combo-point ability -local function IsComboPointAbility(spellName) - if not spellName then return false end - return combopointAbilities[spellName] ~= nil -end - --- Get combo-point spell data (base duration and per-CP bonus) -local function GetComboPointData(spellName) - if not spellName then return nil, nil end - local cpData = combopointAbilities[spellName] - if cpData then - return cpData.base, cpData.perCP - end - return nil, nil -end - -- Debug Stats pfUI.libdebuff_debugstats = pfUI.libdebuff_debugstats or { enabled = false, @@ -642,16 +598,7 @@ function libdebuff:GetDuration(effect, rank) local rank = L["debuffs"][effect][rank] and rank or libdebuff:GetMaxRank(effect) local duration = L["debuffs"][effect][rank] - if effect == L["dyndebuffs"]["Rupture"] then - local cp = GetComboPoints() or 0 - duration = duration + cp*2 - elseif effect == L["dyndebuffs"]["Kidney Shot"] then - local cp = GetComboPoints() or 0 - duration = duration + cp*1 - elseif effect == "Rip" or effect == L["dyndebuffs"]["Rip"] then - local cp = GetComboPoints() or 0 - duration = 8 + cp*2 - elseif effect == L["dyndebuffs"]["Demoralizing Shout"] then + if effect == L["dyndebuffs"]["Demoralizing Shout"] then local _,_,_,_,count = GetTalentInfo(2,1) if count and count > 0 then duration = duration + ( duration / 100 * (count*10)) end elseif effect == L["dyndebuffs"]["Shadow Word: Pain"] then @@ -815,33 +762,6 @@ function libdebuff:GetBestAuraCast(guid, spellName) return nil end --- ============================================================================ --- API: GetEnhancedDebuffs (for external modules) --- ============================================================================ - -function libdebuff:GetEnhancedDebuffs(targetGUID) - if not targetGUID then return nil end - local result = {} - - if ownDebuffs[targetGUID] then - local myGuid = GetPlayerGuid() - for spellName, data in pairs(ownDebuffs[targetGUID]) do - local timeleft = (data.startTime + data.duration) - GetTime() - if timeleft > 0 then - result[spellName] = result[spellName] or {} - result[spellName][myGuid] = { - startTime = data.startTime, - duration = data.duration, - texture = data.texture, - rank = data.rank - } - end - end - end - - return result -end - -- ============================================================================ -- NAMPOWER EVENT HANDLING -- ============================================================================ @@ -1165,11 +1085,6 @@ if hasNampower then pfUI.libpredict_pending_cast.time = nil end - -- Only capture CPs for combo-point abilities - if spellName and IsComboPointAbility(spellName) then - capturedCP = GetComboPoints() or 0 - end - -- Fire registered SPELL_CAST_EVENT hooks if pfUI.libdebuff_spell_cast_hooks then for _, fn in pairs(pfUI.libdebuff_spell_cast_hooks) do @@ -1224,30 +1139,10 @@ if hasNampower then debugStats.aura_cast = debugStats.aura_cast + 1 end - -- Combo-point abilities: Calculate duration based on CPs used - if IsComboPointAbility(spellName) then - if isOurs then - -- OWN casts: use captured CPs from SPELL_CAST_EVENT (if available) - local cp = capturedCP or 0 - local base, perCP = GetComboPointData(spellName) - if base and perCP then - duration = base + cp * perCP - else - -- Fallback to legacy database - duration = libdebuff:GetDuration(spellName, rankNum) - end - capturedCP = nil -- consumed - else - -- OTHER players: CP unknown, no timer (except Expose Armor = fixed 30s) - local base, perCP = GetComboPointData(spellName) - if perCP and perCP == 0 and base then - duration = base -- fixed duration (Expose Armor) - else - duration = 0 -- CP unknown for other players - end - end - elseif duration == 0 then - -- Non-CP managed spells: use database if AURA_CAST returned 0 + -- Duration comes from nampower's AURA_CAST event. ClassicAPI's + -- C_UnitAuras now resolves combo-scaled durations server-side, so + -- libdebuff only needs the database fallback when AURA_CAST reports 0. + if duration == 0 then duration = libdebuff:GetDuration(spellName, rankNum) or 0 end @@ -1789,5 +1684,3 @@ _G.SlashCmdList["MEMCHECK"] = function() DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00No ownSlots/allSlots (eliminated by GetUnitField approach!)|r") DEFAULT_CHAT_FRAME:AddMessage("|cff00ffff============================================================|r") end - -DEFAULT_CHAT_FRAME:AddMessage("|cff33ff99[libdebuff]|r GetUnitField Edition loaded!") \ No newline at end of file diff --git a/modules/eqcompare.lua b/modules/eqcompare.lua index d1e6cf13..27e9e980 100644 --- a/modules/eqcompare.lua +++ b/modules/eqcompare.lua @@ -3,8 +3,9 @@ pfUI:RegisterModule("eqcompare", function () local function ShowCompareItem(self, link, shift) self = self or GameTooltip + shift = shift or IsShiftKeyDown() - if not link or (not IsShiftKeyDown() and (C.tooltip.compare.showalways ~= "1" or C_Item.IsEquippedItem(link))) then + if not link or (not shift and (C.tooltip.compare.showalways ~= "1" or C_Item.IsEquippedItem(link))) then return end @@ -88,7 +89,7 @@ pfUI:RegisterModule("eqcompare", function () local prevMerchant = ShoppingTooltip1.SetMerchantCompareItem local function SetMerchantCompareItem(self, index, compareItem) if C.tooltip.compare.basestats == "1" and compareItem == 1 then - ShowCompareItem(nil, GetMerchantItemLink(index)) + ShowCompareItem(nil, GetMerchantItemLink(index), 1) return false end return prevMerchant and prevMerchant(self, index, compareItem) @@ -97,7 +98,7 @@ pfUI:RegisterModule("eqcompare", function () local prevAuction = ShoppingTooltip1.SetAuctionCompareItem local function SetAuctionCompareItem(self, type, index, compareItem) if C.tooltip.compare.basestats == "1" and compareItem == 1 then - ShowCompareItem(nil, GetAuctionItemLink(type, index)) + ShowCompareItem(nil, GetAuctionItemLink(type, index), 1) return false end return prevAuction and prevAuction(self, type, index, compareItem) diff --git a/modules/turtle-wow.lua b/modules/turtle-wow.lua index e123a5f2..54e709a3 100644 --- a/modules/turtle-wow.lua +++ b/modules/turtle-wow.lua @@ -1,5 +1,5 @@ -- skip module initialization on every other client than turtle-wow -if not TargetHPText or not TargetHPPercText then return end +if not TURTLE_WOW_VERSION then return end pfUI:RegisterModule("turtle-wow", function () -- Manage Turtle WoW's GroupUI (Turtle_GroupUI addon) vs pfUI frames. @@ -86,64 +86,6 @@ pfUI:RegisterModule("turtle-wow", function () L["debuffs"]['Moonfire'] = {[1]=9.0,[2]=18.0,[3]=18.0,[4]=18.0,[5]=18.0,[6]=18.0,[7]=18.0,[8]=18.0,[9]=18.0,[10]=18.0,[0]=18.0} L["debuffs"]['Deep Wound'] = {[0]=6.0} - -- add custom spell logic to libdebuff - HookScript(libdebuff, "OnEvent", function() - if event == "CHAT_MSG_SPELL_SELF_DAMAGE" then - -- refresh paladin judgements on holy strike - -- taken from: https://github.com/doorknob6/pfUI-turtle/blob/master/modules/debuffs.lua - local holystrike = string.find(string.sub(arg1,6,17), "Holy Strike") - --arg2 is spell dmg when it hits, nil when it misses - if holystrike and arg2 then - for seal in L["judgements"] do - local name = UnitName("target") - local level = UnitLevel("target") - if name and libdebuff.objects[name] then - if level and - libdebuff.objects[name][level] and - libdebuff.objects[name][level][seal] then - libdebuff:AddEffect(name, level, seal) - elseif libdebuff.objects[name][0] and - libdebuff.objects[name][0][seal] then - libdebuff:AddEffect(name, 0, seal) - end - end - end - end - - -- refresh rip and rake duration on ferocious bite (Turtle WoW feature) - -- Only refresh if Ferocious Bite actually hit (not missed/dodged/parried/etc.) - local match = string.find(arg1, "Ferocious Bite") - if match and arg2 and not libdebuff:DidSpellFail("Ferocious Bite") then - local name = UnitName("target") - local level = UnitLevel("target") - - -- Refresh Rip mit existierender Duration - if libdebuff.objects[name] and libdebuff.objects[name][level] and libdebuff.objects[name][level]["Rip"] then - local existingDuration = libdebuff.objects[name][level]["Rip"].duration - libdebuff:AddEffect(name, level, "Rip", existingDuration) - end - - -- Refresh Rake mit existierender Duration - if libdebuff.objects[name] and libdebuff.objects[name][level] and libdebuff.objects[name][level]["Rake"] then - local existingDuration = libdebuff.objects[name][level]["Rake"].duration - libdebuff:AddEffect(name, level, "Rake", existingDuration) - end - end - - -- refresh Immolate duration after cast Conflagrate - -- Only refresh if Conflagrate actually hit - local conflagrate = string.find(string.sub(arg1,6,17), "Conflagrate") - if conflagrate and arg2 and not libdebuff:DidSpellFail("Conflagrate") then - local name = UnitName("target") - local level = UnitLevel("target") - if libdebuff.objects[name] and libdebuff.objects[name][level] and libdebuff.objects[name][level]["Immolate"] then - local duration = libdebuff.objects[name][level]["Immolate"].duration - libdebuff:UpdateDuration(name, level, "Immolate", duration - 3) - end - end - end - end) - -- turtle wow totemic recall clear totem indicators local _, class = UnitClass("player") if libtotem and class == "SHAMAN" then diff --git a/modules/xpbar.lua b/modules/xpbar.lua index 97939f0d..bdcbbd3e 100644 --- a/modules/xpbar.lua +++ b/modules/xpbar.lua @@ -5,7 +5,7 @@ pfUI:RegisterModule("xpbar", function () local REST_WINDOW = 300 -- seconds of sliding-window samples for rate calc local REST_CAP_MUL = 1.5 -- target rested cap = UnitXPMax * 1.5 - if IsTurtleWoW() then + if TURTLE_WOW_VERSION then REST_CAP_MUL = 1.13 end