From 9c05a6fc6a81c4b5aa35039a565803c82e30477f Mon Sep 17 00:00:00 2001 From: Jrc13245 Date: Tue, 3 Mar 2026 11:10:55 -0500 Subject: [PATCH] fix pfui loading objects without superwow --- Compatibility/pfUI.lua | 9 ++++++ Conditionals.lua | 63 ++++++++++++++++++++++++++++++------------ Core.lua | 10 +++++-- Utility.lua | 29 ++++++++++--------- 4 files changed, 79 insertions(+), 32 deletions(-) diff --git a/Compatibility/pfUI.lua b/Compatibility/pfUI.lua index a7caead..5db1750 100644 --- a/Compatibility/pfUI.lua +++ b/Compatibility/pfUI.lua @@ -671,6 +671,15 @@ function Extension.ADDON_LOADED() end function Extension.PLAYER_LOGIN() + -- If pfUI loaded before SCRM (alphabetical order), ADDON_LOADED for pfUI was missed. + -- Re-run InitPfUIIntegration here to ensure lib.objects is linked correctly. + if pfUI and not CleveRoids.hasPfUI76 then + local lib = CleveRoids.libdebuff + if lib and lib.InitPfUIIntegration then + lib:InitPfUIIntegration() + end + end + -- Final check after everything is loaded Extension.SetupCompatibility() diff --git a/Conditionals.lua b/Conditionals.lua index fb8d92d..46625cb 100644 --- a/Conditionals.lua +++ b/Conditionals.lua @@ -3420,25 +3420,29 @@ function CleveRoids.ValidateAura(unit, args, isbuff) local searchName = not searchID and args.name and _string_lower(args.name) or nil -- Fast path: Use GetUnitField to search all 48 aura slots in 2 C-to-Lua calls - -- Only for non-player units (player uses GetPlayerAura which provides duration) + -- Works for both player and non-player units (GetUnitField supports "player" token) local skipSlowSearch = false - if not isPlayer then - local API = CleveRoids.NampowerAPI - if API and API.FindUnitAuraInfo then - local gufResult, gufSpellId, gufStacks, gufSlot = API.FindUnitAuraInfo(unit, searchID, searchName) - if gufResult ~= nil then -- GetUnitField was available and searched - skipSlowSearch = true - if gufResult then - if isbuff then - -- For buff checks: only accept buff slots (1-32) - if gufSlot <= 32 then - found = true - stacks = gufStacks or 0 - end - else - -- For debuff checks: accept any slot (debuffs overflow to buff slots) + local API = CleveRoids.NampowerAPI + if API and API.FindUnitAuraInfo then + local gufResult, gufSpellId, gufStacks, gufSlot = API.FindUnitAuraInfo(unit, searchID, searchName) + if gufResult ~= nil then -- GetUnitField was available and searched + skipSlowSearch = true + if gufResult then + if isbuff then + -- For buff checks: only accept buff slots (1-32) + if gufSlot <= 32 then found = true stacks = gufStacks or 0 + if isPlayer then + remaining = GetPlayerBuffTimeLeft(gufSlot - 1) + end + end + else + -- For debuff checks: accept any slot (debuffs overflow to buff slots) + found = true + stacks = gufStacks or 0 + if isPlayer then + remaining = GetPlayerBuffTimeLeft(gufSlot - 1) end end end @@ -3787,7 +3791,7 @@ function CleveRoids.ValidateUnitDebuff(unit, args) end -- Check tracking table for ANY rank of this spell: Did player cast this? Is timer valid? - if matchingSpellIDs and table.getn(matchingSpellIDs) > 0 then + if not found and matchingSpellIDs and table.getn(matchingSpellIDs) > 0 then for _, spellID in ipairs(matchingSpellIDs) do local rec = lib.objects[guid] and lib.objects[guid][spellID] -- For shared debuffs (Sunder, Faerie Fire, etc.), accept any caster (including nil) @@ -3857,6 +3861,31 @@ function CleveRoids.ValidateUnitDebuff(unit, args) ) end + -- If spell not in personalDebuffs/sharedDebuffs cache, scan objectsByGuid by name + -- Safety net for Turtle WoW custom spells not in hardcoded lookup tables + if not found and (not matchingSpellIDs or table.getn(matchingSpellIDs) == 0) and lib.objects[guid] and not searchID then + local searchNameLower = _string_lower(args.name) + for spellID, rec in pairs(lib.objects[guid]) do + if rec and rec.caster == "player" then + local n = GetSpellRecField and GetSpellRecField(spellID, "name") + if n then + n = _string_gsub(n, "%s*%(%s*Rank%s+%d+%s*%)", "") + if _string_lower(n) == searchNameLower then + local timeRemaining = rec.duration + rec.start - GetTime() + if timeRemaining > 0 then + found = true + remaining = timeRemaining + stacks = rec.stacks or 0 + else + lib.objects[guid][spellID] = nil + end + break + end + end + end + end + end + -- FALLBACK: If not found in tracking table, scan actual debuffs on target -- This handles: -- 1. Shared debuffs from other players (we only track player's own casts) diff --git a/Core.lua b/Core.lua index 4fec944..dde57a6 100644 --- a/Core.lua +++ b/Core.lua @@ -108,11 +108,17 @@ requirementCheckFrame:SetScript("OnEvent", function() -- Check requirements immediately when our addon loads local hasNampower = (IsSpellInRange ~= nil) local hasUnitXP = pcall(UnitXP, "nop", "nop") + local hasNampower30 = hasNampower and CleveRoids.NampowerAPI + and CleveRoids.NampowerAPI.HasMinimumVersion(3, 0, 0) - if not hasNampower or not hasUnitXP then + if not hasNampower30 or not hasUnitXP then -- Show errors if not hasNampower then - CleveRoids.Print("|cFFFF0000SuperCleveRoidMacros|r requires |cFF00FFFFAvitasia's Nampower|r:") + CleveRoids.Print("|cFFFF0000SuperCleveRoidMacros|r requires |cFF00FFFFAvitasia's Nampower v3.0.0+|r:") + CleveRoids.Print("https://gitea.com/avitasia/nampower") + elseif not hasNampower30 then + local major, minor, patch = CleveRoids.NampowerAPI.GetVersion() + CleveRoids.Print(format("|cFFFF0000SuperCleveRoidMacros|r requires |cFF00FFFFNampower v3.0.0+|r (you have v%d.%d.%d):", major, minor, patch)) CleveRoids.Print("https://gitea.com/avitasia/nampower") end if not hasUnitXP then diff --git a/Utility.lua b/Utility.lua index 91a445d..005f2e4 100644 --- a/Utility.lua +++ b/Utility.lua @@ -51,14 +51,10 @@ function CleveRoids.NormalizeGUID(guid) return tostring(guid) end --- Get GUID for a unit token (prefers Nampower GetUnitGUID for extended token support) +-- Get GUID for a unit token via Nampower GetUnitGUID (v3.0+) -- Returns: normalized GUID string, or nil function CleveRoids.GetGUID(unit) - if _G.GetUnitGUID then - local guid = _G.GetUnitGUID(unit) - if guid then return tostring(guid) end - end - local _, guid = UnitExists(unit) + local guid = GetUnitGUID(unit) if guid then return tostring(guid) end return nil end @@ -3142,8 +3138,8 @@ delayedTrackingFrame:SetScript("OnUpdate", function() local function ResolveGUIDUnit(guid) if not guid then return nil end if hasSuperwow then return guid end - local _, ctGUID = _UnitExists("target") - if ctGUID and CleveRoids.NormalizeGUID(ctGUID) == guid then + local ctGUID = CleveRoids.GetGUID("target") + if ctGUID and ctGUID == guid then return "target" end return nil @@ -3163,8 +3159,7 @@ delayedTrackingFrame:SetScript("OnUpdate", function() -- Scan target after 0.5 seconds to find the actual judgement debuff if elapsed >= 0.5 then -- Check if this is still the current target - local _, currentTargetGUID = _UnitExists("target") - currentTargetGUID = CleveRoids.NormalizeGUID(currentTargetGUID) + local currentTargetGUID = CleveRoids.GetGUID("target") if currentTargetGUID == pending.targetGUID then -- Scan all debuffs on target to find judgement-type debuffs @@ -3592,8 +3587,8 @@ delayedTrackingFrame:SetScript("OnUpdate", function() resolvedTargetName = lib.guidToName[pending.targetGUID] -- Try to resolve from current target if not resolvedTargetName then - local _, currentTargetGUID = _UnitExists("target") - if currentTargetGUID and CleveRoids.NormalizeGUID(currentTargetGUID) == pending.targetGUID then + local currentTargetGUID = CleveRoids.GetGUID("target") + if currentTargetGUID and currentTargetGUID == pending.targetGUID then resolvedTargetName = _UnitName("target") lib.guidToName[pending.targetGUID] = resolvedTargetName end @@ -5830,7 +5825,15 @@ evCleanup:SetScript("OnEvent", function() if event == "PLAYER_ENTERING_WORLD" or event == "PLAYER_DEAD" then -- Keep only current target's data local currentGUID = CleveRoids.GetGUID("target") - if currentGUID then + if lib.hasPfUI76 then + -- pfUI76: lib.objects is pfUI.libdebuff_objects_guid - never replace the reference! + -- pfUI handles its own cleanup; just clear SCRM-side entries + for guid in pairs(lib.objects) do + if guid ~= currentGUID then + lib.objects[guid] = nil + end + end + elseif currentGUID then local temp = lib.objects[currentGUID] lib.objects = {} if temp then