update nampower support to 2_27_2 and pfUI 7_6+

This commit is contained in:
Jrc13245
2026-02-04 16:23:34 -05:00
parent d29b180bd4
commit ee2de33001
6 changed files with 200 additions and 56 deletions
+6 -1
View File
@@ -616,7 +616,12 @@ function Extension.PLAYER_LOGIN()
-- Print startup status only if pfUI global exists and compatibility was set up
if Extension.pfUILoaded and pfUI then
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[SCRM]|r pfUI compatibility loaded. Use /pfuicd for debug.")
local statusMsg = "|cff00ff00[SCRM]|r pfUI compatibility loaded"
if CleveRoids.hasPfUI76 then
statusMsg = statusMsg .. " (7.6+ GUID cast tracking)"
end
-- statusMsg = statusMsg .. ". Use /pfuicd for debug."
DEFAULT_CHAT_FRAME:AddMessage(statusMsg)
if not Extension.actionHandlerRegistered then
DEFAULT_CHAT_FRAME:AddMessage("|cffff0000[SCRM]|r WARNING: pfUI action handler NOT registered!")
end
+22 -9
View File
@@ -3940,31 +3940,44 @@ function CleveRoids.CheckSpellCast(unit, spell)
local _,guid = UnitExists(unit)
if not guid then return false end
-- BUGFIX: Special handling for player unit - check CurrentSpell.type
-- This is event-driven and more reliable than spell_tracking for the player
-- Player: check CurrentSpell (event-driven, most reliable for self)
if unit == "player" then
-- Check if player is casting or channeling
if CleveRoids.CurrentSpell and CleveRoids.CurrentSpell.type ~= "" then
-- If checking for any spell, return true
if spell == "" then
return true
end
-- If checking for specific spell, compare spell names
-- Note: CurrentSpell.spellName may not be set, so also check spell_tracking as fallback
if CleveRoids.CurrentSpell.spellName and CleveRoids.CurrentSpell.spellName == spell then
return true
end
end
-- Fallback to spell_tracking for player if CurrentSpell doesn't have the info
-- Fallback to GUID-based tracking and spell_tracking below
end
-- For non-player units or as fallback, use spell_tracking
-- GUID-based cast tracking (pfUI 7.6 or standalone SPELL_START events)
local ct = CleveRoids.castTracking
if ct then
local normalizedGuid = CleveRoids.NormalizeGUID(guid)
local castEntry = normalizedGuid and ct[normalizedGuid]
if castEntry and castEntry.endTime and GetTime() < castEntry.endTime then
if spell == "" then
return true
end
if castEntry.spellName then
-- Strip rank suffix for comparison: "Heal(Rank 4)" -> "Heal"
local baseName = string.gsub(castEntry.spellName, "%s*%(Rank %d+%)", "")
if baseName == spell or castEntry.spellName == spell then
return true
end
end
end
end
-- Legacy fallback: UNIT_CASTEVENT-based spell_tracking (requires SuperWoW)
if not CleveRoids.hasSuperwow then return false end
if not CleveRoids.spell_tracking[guid] then
return false
else
-- are we casting a specific spell, or any spell
if spell == SpellInfo(CleveRoids.spell_tracking[guid].spell_id) or (spell == "") then
return true
end
+14
View File
@@ -3901,6 +3901,20 @@ function CleveRoids.OnUpdate(self)
guid, cast = nextGuid, nextGuid and spell_tracking[nextGuid]
end
-- Clean stale castTracking entries (standalone mode only, pfUI 7.6 manages its own)
if not CleveRoids.hasPfUI76 then
local ct = CleveRoids.castTracking
local ctGuid, ctEntry = next(ct)
while ctGuid do
local nextCtGuid = next(ct, ctGuid)
if ctEntry.endTime and time > ctEntry.endTime + 0.5 then
ct[ctGuid] = nil
end
ctGuid = nextCtGuid
ctEntry = nextCtGuid and ct[nextCtGuid]
end
end
-- PERFORMANCE OPTIMIZATION: Run memory cleanup less frequently (every 5 seconds instead of every frame)
-- This reduces CPU usage while maintaining effective memory management
if (time - CleveRoids.lastCleanupTime) >= CleveRoids.CLEANUP_INTERVAL then
+7
View File
@@ -38,6 +38,13 @@ CleveRoids.unknownTexture = "Interface\\Icons\\INV_Misc_QuestionMark"
CleveRoids.spell_tracking = {}
-- GUID-based cast tracking (populated by pfUI 7.6 or standalone SPELL_START events)
-- Format: [casterGuid] = {spellID, spellName, icon, startTime, duration, endTime}
CleveRoids.castTracking = {}
-- pfUI 7.6+ with Nampower 2.27.2+ detected (GUID-based cast tracking available)
CleveRoids.hasPfUI76 = false
-- Combo point tracking (initialized early for /cast hook)
CleveRoids.lastComboPoints = 0
CleveRoids.lastComboPointsTime = 0
+1 -1
View File
@@ -2,7 +2,7 @@
## Author: DWG, _brain, Torio, yani9o, Avitasia
## Title: [Super]CleveRoidMacros
## Notes: /cleveroid for settings
## Version: 1.9.1
## Version: 1.9.2
## OptionalDeps: ClassicFocus, FocusFrame, pfUI, SuperMacro, Bongos_ActionBar, Cursive, XPerl, LunaUnitFrames, DragonflightReloaded, -Dragonflight3
## SavedVariables: CleveRoidMacros, CleveRoids_LearnedDurations, CleveRoids_AuraTextures, CleveRoids_ImmunityData, CleveRoids_ComboDurations, CleveRoids_SpellSchools
Localization.lua
+150 -45
View File
@@ -651,9 +651,7 @@ local lib = CleveRoids.libdebuff
lib.objects = lib.objects or {}
lib.guidToName = lib.guidToName or {}
-- ============================================================================
-- PFUI v7.4.3+ NAMPOWER-BASED DEBUFF TRACKING INTEGRATION
-- ============================================================================
-- When pfUI v7.4.3+ with Nampower v2.26+ is available, we leverage pfUI's
-- comprehensive debuff tracking tables instead of duplicating the event handlers.
-- This provides accurate caster GUID tracking, rank checking, combo point
@@ -666,10 +664,12 @@ lib.allSlots = lib.allSlots or {} -- [targetGUID][slot] = {spellName,
lib.allAuraCasts = lib.allAuraCasts or {} -- [targetGUID][spellName][casterGuid] = {startTime, duration, rank}
lib.pendingCasts = lib.pendingCasts or {} -- [targetGUID][spellName] = {casterGuid, rank, time, comboPoints}
lib.recentMisses = lib.recentMisses or {} -- [targetGUID][spellName] = {time, spellId, targetName, reason} for miss/dodge/parry detection
lib.iconCache = lib.iconCache or {} -- [spellId] = texture (shared with pfUI 7.6 or standalone)
-- Flag indicating whether enhanced pfUI tracking is available
lib.hasPfUIEnhanced = false
lib.hasStandaloneNampower = false
lib.hasPfUI76 = false
-- Check if pfUI v7.4.3+ with enhanced libdebuff is available
function lib:HasEnhancedPfUILibdebuff()
@@ -713,6 +713,63 @@ function lib:HasEnhancedPfUILibdebuff()
return true
end
-- Check if pfUI v7.6+ with enhanced cast tracking is available
-- pfUI 7.6 requires Nampower v2.27.2+ and exposes additional tables
function lib:HasPfUI76()
if not pfUI then return false end
local v = pfUI.version
if not v or not v.major then return false end
-- Version comparison: 7.6+
if v.major < 7 then return false end
if v.major == 7 and (v.minor or 0) < 6 then return false end
-- Verify Nampower v2.27.2+ (pfUI 7.6 hard requirement)
if not GetNampowerVersion then return false end
local npMajor, npMinor, npPatch = GetNampowerVersion()
npPatch = npPatch or 0
if npMajor < 2 then return false end
if npMajor == 2 and npMinor < 27 then return false end
if npMajor == 2 and npMinor == 27 and npPatch < 2 then return false end
-- Verify the new tables exist
if not pfUI.libdebuff_casts then return false end
if not pfUI.libdebuff_objects_guid then return false end
return true
end
-- Icon caching helper: DBC lookup (fast) → SpellInfo fallback (slow)
function lib:GetCachedIcon(spellId)
if not spellId then return nil end
if lib.iconCache[spellId] then return lib.iconCache[spellId] end
local texture = nil
-- Try Nampower DBC lookup first (fast)
if GetSpellRecField and GetSpellIconTexture then
local iconId = GetSpellRecField(spellId, "spellIconID")
if iconId and type(iconId) == "number" and iconId > 0 then
texture = GetSpellIconTexture(iconId)
end
end
-- Fallback to SpellInfo (slower but works without Nampower v2.27)
if not texture and SpellInfo then
local _, _, spellTex = SpellInfo(spellId)
texture = spellTex
end
-- Final fallback
if not texture then
texture = "Interface\\Icons\\INV_Misc_QuestionMark"
end
lib.iconCache[spellId] = texture
return texture
end
-- Initialize pfUI integration (call after ADDON_LOADED for pfUI)
function lib:InitPfUIIntegration()
if lib:HasEnhancedPfUILibdebuff() then
@@ -726,6 +783,19 @@ function lib:InitPfUIIntegration()
lib.hasPfUIEnhanced = true
lib.hasStandaloneNampower = false
-- Check for pfUI 7.6+ additional tables (cast tracking, GUID objects, icon cache)
if lib:HasPfUI76() then
CleveRoids.hasPfUI76 = true
lib.hasPfUI76 = true
CleveRoids.castTracking = pfUI.libdebuff_casts
lib.iconCache = pfUI.libdebuff_icon_cache or lib.iconCache
-- lib.objects is already set by pfUI's CleveRoids.libdebuff = libdebuff override
-- but explicitly sync if pfUI.libdebuff_objects_guid is available
if pfUI.libdebuff_objects_guid then
lib.objects = pfUI.libdebuff_objects_guid
end
end
-- Unregister chat log events since SPELL_GO provides miss detection
if CleveRoidsLibDebuffLearnFrame then
CleveRoidsLibDebuffLearnFrame:UnregisterEvent("CHAT_MSG_SPELL_SELF_DAMAGE")
@@ -733,9 +803,10 @@ function lib:InitPfUIIntegration()
if CleveRoids.debug then
local v = pfUI.version
local tierMsg = lib.hasPfUI76 and " (7.6+ cast tracking)" or ""
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff33ff99[libdebuff]|r pfUI v%d.%d.%d enhanced tracking enabled",
v.major, v.minor, v.fix or 0)
string.format("|cff33ff99[libdebuff]|r pfUI v%d.%d.%d enhanced tracking enabled%s",
v.major, v.minor, v.fix or 0, tierMsg)
)
end
@@ -2386,12 +2457,10 @@ end
-- When Carnage procs, combo points don't drop to 0 after Ferocious Bite (they stay at 1)
-- The ApplyCarnageRefresh function below is called from ComboPointTracker when a proc is detected
-- =============================================================================
-- WARLOCK DARK HARVEST: Duration Acceleration System (TWoW Custom)
-- Credits: Avitasia / Cursive addon
-- Dark Harvest is a channeled spell that accelerates DoT tick rate by 30%
-- While channeling, DoTs on the target expire 30% faster
-- =============================================================================
-- Calculate Dark Harvest reduction for a debuff record
-- Returns the amount of time to subtract from remaining duration
@@ -3517,6 +3586,19 @@ if CleveRoids.hasNampower then
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nampower]|r Registered UNIT_DIED for instant cleanup (v2.26+)")
end
end
-- Register SPELL_START/SPELL_FAILED events for cast tracking (v2.25+)
-- These events let us know when ANY unit starts or fails a cast-time spell
-- pfUI 7.6 handles these itself, but we register anyway for standalone mode
if npMajor > 2 or (npMajor == 2 and npMinor >= 25) then
ev:RegisterEvent("SPELL_START_SELF")
ev:RegisterEvent("SPELL_START_OTHER")
ev:RegisterEvent("SPELL_FAILED_OTHER")
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[Nampower]|r Registered SPELL_START/SPELL_FAILED for cast tracking (v2.25+)")
end
end
end
-- Track if UNIT_DIED is available for cleanup optimization
@@ -4179,9 +4261,59 @@ ev:SetScript("OnEvent", function()
end
end
-- ============================================================================
-- NAMPOWER v2.25+ CAST TRACKING HANDLERS (Standalone or pfUI < 7.6)
-- Populates CleveRoids.castTracking for [casting] conditional support.
-- When pfUI 7.6+ is active, castTracking points to pfUI.libdebuff_casts
-- and these handlers return early (pfUI handles it).
elseif event == "SPELL_START_SELF" or event == "SPELL_START_OTHER" then
-- pfUI 7.6 manages castTracking via its own SPELL_START handler
if lib.hasPfUI76 then return end
local spellId = arg2
local casterGuid = arg3
local castTime = arg6 -- milliseconds
if not casterGuid or not spellId then return end
local spellName = SpellInfo and SpellInfo(spellId)
local icon = lib:GetCachedIcon(spellId)
local now = GetTime()
local durationSec = castTime and (castTime / 1000) or 0
CleveRoids.castTracking[casterGuid] = {
spellID = spellId,
spellName = spellName,
icon = icon,
startTime = now,
duration = durationSec,
endTime = durationSec > 0 and (now + durationSec) or nil,
}
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff00ccff[SPELL_START]|r %s (ID:%d) cast by %s - %.1fs",
spellName or "Unknown", spellId, casterGuid, durationSec)
)
end
elseif event == "SPELL_FAILED_OTHER" then
-- pfUI 7.6 manages castTracking cleanup itself
if lib.hasPfUI76 then return end
local casterGuid = arg1
if casterGuid and CleveRoids.castTracking[casterGuid] then
if CleveRoids.debug then
local entry = CleveRoids.castTracking[casterGuid]
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff6600[SPELL_FAILED]|r %s cast by %s interrupted/failed",
entry.spellName or "Unknown", casterGuid)
)
end
CleveRoids.castTracking[casterGuid] = nil
end
-- NAMPOWER v2.26+ SPELL EVENT HANDLERS (Standalone Mode)
-- ============================================================================
-- These handlers are only used when pfUI v7.4.3+ is NOT available.
-- When pfUI is available, we use its tables directly instead.
@@ -4189,6 +4321,11 @@ ev:SetScript("OnEvent", function()
-- Skip if pfUI enhanced tracking is active (it handles this)
if lib.hasPfUIEnhanced then return end
-- Clear cast tracking entry - cast completed/fired (standalone mode only)
if not lib.hasPfUI76 and arg3 and CleveRoids.castTracking[arg3] then
CleveRoids.castTracking[arg3] = nil
end
local spellId = arg2
local casterGuid = arg3
local targetGuid = arg4
@@ -4291,9 +4428,7 @@ ev:SetScript("OnEvent", function()
lib.recentMisses[targetGuid][spellName] = nil
end
-- ========================================================================
-- COMBO POINT INTEGRATION: Capture combo points on SPELL_GO hit
-- ========================================================================
-- SPELL_GO fires immediately when the spell lands - this is the best time
-- to capture combo points because they might already be consumed by the
-- time AURA_CAST fires. Store in pendingCasts for AURA_CAST to use.
@@ -4541,9 +4676,7 @@ ev:SetScript("OnEvent", function()
end
end
-- ============================================================================
-- NAMPOWER v2.26+ UNIT_DIED - Instant cleanup on target death
-- ============================================================================
elseif event == "UNIT_DIED" then
local guid = arg1
if not guid then return end
@@ -4572,6 +4705,11 @@ ev:SetScript("OnEvent", function()
lib.recentMisses[guid] = nil
end
-- Clean up cast tracking for this unit (they can't be casting if dead)
if not lib.hasPfUI76 and CleveRoids.castTracking[guid] then
CleveRoids.castTracking[guid] = nil
end
-- Clean up GUID to name mapping (after 5 seconds to allow final lookups)
-- Actually, keep it for a bit in case we need it for immunity detection
-- lib.guidToName[guid] = nil
@@ -5102,9 +5240,7 @@ evJudgement:SetScript("OnEvent", function()
end
end)
-- ============================================================================
-- TALENT MODIFIER SYSTEM
-- ============================================================================
-- Database of talent modifiers for debuff durations
-- Structure: [spellID] = {
@@ -5380,9 +5516,7 @@ function CleveRoids.DiagnoseTalentModifier(spellID, baseDuration)
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00=== End Diagnostic ===|r")
end
-- ============================================================================
-- EQUIPMENT MODIFIER SYSTEM
-- ============================================================================
-- Database of equipment modifiers for debuff durations
-- Structure: [spellID] = { slot = invSlotID, items = { [itemID] = modifierFunction } }
@@ -5476,9 +5610,7 @@ function CleveRoids.RegisterEquipmentModifier(spellID, slotID, modifierFunc)
return true
end
-- ============================================================================
-- NAMPOWER SPELL MODIFIERS INTEGRATION (v2.18+)
-- ============================================================================
-- Try to get duration modifiers from Nampower's GetSpellModifiers
-- This function supplements (not replaces) the talent/equipment modifier system
@@ -5562,9 +5694,7 @@ function CleveRoids.ApplyAllDurationModifiers(spellID, baseDuration)
return duration
end
-- ============================================================================
-- SET BONUS MODIFIER SYSTEM
-- ============================================================================
-- Database of set bonus modifiers for debuff durations
-- Structure: [spellID] = { items = {itemID1, itemID2, ...}, threshold = X, modifier = function(baseDuration) }
@@ -5683,10 +5813,7 @@ CleveRoids.setbonusModifiers[778] = { items = haruspexItems, threshold = 3, modi
CleveRoids.setbonusModifiers[9749] = { items = haruspexItems, threshold = 3, modifier = haruspexFaerieFireModifier } -- Faerie Fire Rank 3
CleveRoids.setbonusModifiers[9907] = { items = haruspexItems, threshold = 3, modifier = haruspexFaerieFireModifier } -- Faerie Fire Rank 4
-- ============================================================================
-- IMMUNITY TRACKING SYSTEM
-- ============================================================================
-- Initialize SavedVariables for immunity tracking
CleveRoids_ImmunityData = CleveRoids_ImmunityData or {}
@@ -6245,9 +6372,7 @@ local function HasImmunityGrantingBuff(unit)
return nil
end
-- ============================================================================
-- CC IMMUNITY TRACKING
-- ============================================================================
-- Get CC type from a spell ID using the CCSpellMechanics table from Conditionals.lua
-- Returns: CC type name (e.g., "stun", "fear") or nil if not a CC spell
@@ -6400,9 +6525,7 @@ end
-- Expose publicly
CleveRoids.CheckCCImmunity = CheckCCImmunity
-- ============================================================================
-- DAMAGE SCHOOL IMMUNITY RECORDING
-- ============================================================================
-- Record an immunity (permanent or buff-based)
-- Parameters:
@@ -6661,9 +6784,7 @@ local function ParseImmunityCombatLog()
local targetName = nil
local school = nil
-- ============================================================================
-- IMMUNE PATTERNS
-- ============================================================================
if hasImmune then
-- Pattern 1: "Your [Spell] fails. Y is immune."
local _, _, extractedSpell, extractedTarget = string.find(message, "Your%s+(.-)%s+fails%.%s+(.-)%s+is immune")
@@ -6698,9 +6819,7 @@ local function ParseImmunityCombatLog()
end
end
-- ============================================================================
-- REFLECT PATTERNS
-- ============================================================================
if hasReflect and not targetName then
-- Pattern 1: "Your [Spell] is reflected back by Y."
local _, _, extractedSpell, extractedTarget = string.find(message, "Your%s+(.-)%s+is reflected back by%s+(.-)%.")
@@ -6737,9 +6856,7 @@ local function ParseImmunityCombatLog()
end
end
-- ============================================================================
-- EVADE PATTERNS
-- ============================================================================
if hasEvade and not targetName then
-- Pattern 1: "Your [Spell] fails. Y evades."
local _, _, extractedSpell, extractedTarget = string.find(message, "Your%s+(.-)%s+fails%.%s+(.-)%s+evades")
@@ -6775,9 +6892,7 @@ local function ParseImmunityCombatLog()
end
end
-- ============================================================================
-- STORE REASON FOR SPELL_GO CORRELATION
-- ============================================================================
-- Store the reason for ProcessMissReason to correlate with SPELL_GO events
if targetName and lib and lib.recentCombatLogReasons then
lib.recentCombatLogReasons[targetName] = lib.recentCombatLogReasons[targetName] or {}
@@ -7425,9 +7540,7 @@ function CleveRoids.RemoveImmunity(npcName, school)
end
end
-- ============================================================================
-- CC IMMUNITY MANAGEMENT COMMANDS
-- ============================================================================
-- List CC immunities
function CleveRoids.ListCCImmunities(ccType)
@@ -7573,9 +7686,7 @@ immunityFrame:SetScript("OnEvent", function()
end
end)
-- ============================================================================
-- REACTIVE ABILITY PROC TRACKING SYSTEM
-- ============================================================================
-- Tracks reactive ability procs independently of stance/usability
-- Allows detection of Overpower/Revenge/Riposte procs even when not in correct stance
@@ -7797,9 +7908,7 @@ if originalUnitCastEvent then
end
end
-- ============================================================================
-- NAMPOWER v2.24+ AUTO_ATTACK EVENT HANDLER FOR REACTIVE ABILITIES
-- ============================================================================
-- Uses native events for dodge/parry/block detection when available.
-- Falls back to combat log parsing for older Nampower versions.
@@ -7971,10 +8080,8 @@ reactiveFrame:SetScript("OnEvent", function()
end
end)
-- ============================================================================
-- RESIST TRACKING SYSTEM
-- Tracks full and partial spell resists for [resisted] and [noresisted] conditionals
-- ============================================================================
-- Set resist state with target GUID matching
function CleveRoids.SetResistState(resistType, targetGUID)
@@ -8070,9 +8177,7 @@ local function ParseResistCombatLog()
end
end
-- ============================================================================
-- UNIFIED COMBAT LOG DISPATCHER
-- ============================================================================
-- Consolidates all RAW_COMBATLOG handling into a single frame for performance.
-- Previously, 4 separate frames were each parsing the same combat log events.
-- This single dispatcher calls all parsing functions once per event.