From 1f406434e301a3dd94fc7cc0692f5dae3f118f75 Mon Sep 17 00:00:00 2001 From: Jrc13245 Date: Fri, 20 Feb 2026 22:15:07 -0500 Subject: [PATCH] update for nampower 2_40 --- NampowerAPI.lua | 77 ++++++++++++++++++++++++++++++++++++++++++++++++- Utility.lua | 26 ++++++++++++++--- 2 files changed, 98 insertions(+), 5 deletions(-) diff --git a/NampowerAPI.lua b/NampowerAPI.lua index cb655ff..38b2786 100644 --- a/NampowerAPI.lua +++ b/NampowerAPI.lua @@ -121,7 +121,29 @@ cast-time and channeling spells since there is no separate SPELL_CHANNEL_START packet for other players). - Current version: v2.38.0 + Unit GUID Events (v2.39+): + - New GUID-based unit events fire once per unit state change instead of once per + registered token. Each event carries GUID + flags for player/target/mouseover/pet/ + party/raid membership. Avoids event spam from per-token firing. + - Events: UNIT_HEALTH_GUID, UNIT_MANA_GUID, UNIT_RAGE_GUID, UNIT_ENERGY_GUID, + UNIT_PET_GUID, UNIT_FLAGS_GUID, UNIT_AURA_GUID, UNIT_DYNAMIC_FLAGS_GUID, + UNIT_NAME_UPDATE_GUID, UNIT_PORTRAIT_UPDATE_GUID, UNIT_MODEL_CHANGED_GUID, + UNIT_INVENTORY_CHANGED_GUID, PLAYER_GUILD_UPDATE_GUID + - UNIT_COMBAT_GUID: fires once per combat feedback event with full combat detail + (action, damage, school, hitInfo) instead of per token. + - Granular CVars to control which unit tokens fire standard UNIT_* events: + NP_EnableUnitEventsPet (default 1), NP_EnableUnitEventsParty (default 1), + NP_EnableUnitEventsRaid (default 1), NP_EnableUnitEventsMouseover (default 1), + NP_EnableUnitEventsGuid (default 1), NP_EnableUnitEventsGuidFiltering (default 1) + + Corpse Guid & Packed GUID Fix (v2.40+): + - SPELL_START_SELF/OTHER now include arg9 = corpseOwnerGuid (string or nil): + GUID of the player who owns the corpse target; nil if no corpse target. + - SPELL_GO_SELF/OTHER now include arg8 = corpseOwnerGuid (string or nil). + - Fixed packed GUID parsing bug that caused target to appear as "0x000000000" + for some player GUIDs. + + Current version: v2.40.0 ]] local _G = _G or getfenv(0) @@ -302,6 +324,16 @@ API.VERSION_REQUIREMENTS = { -- v2.38+ - GetSpellDuration and enhanced SPELL_START parameters ["GetSpellDuration"] = { 2, 38, 0, "GetSpellDuration" }, ["SpellStartSpellType"] = { 2, 38, 0 }, -- duration + spellType params added to SPELL_START events + + -- v2.39+ - Unit GUID events and granular unit event CVars + ["UnitGuidEvents"] = { 2, 39, 0 }, -- UNIT_HEALTH_GUID, UNIT_MANA_GUID, etc. + ["UnitCombatGuid"] = { 2, 39, 0 }, -- UNIT_COMBAT_GUID event + ["UnitEventGranularControl"]= { 2, 39, 0 }, -- NP_EnableUnitEvents* CVars + + -- v2.40+ - Corpse GUID param in spell events and packed GUID fix + ["SpellStartCorpseParam"] = { 2, 40, 0 }, -- arg9=corpseOwnerGuid added to SPELL_START events + ["SpellGoCorpseParam"] = { 2, 40, 0 }, -- arg8=corpseOwnerGuid added to SPELL_GO events + ["PackedGuidFix"] = { 2, 40, 0 }, -- Fix for packed GUID parsing (target showed as 0x000000000) } -- Check if a specific feature is available @@ -466,6 +498,16 @@ local function InitializeFeatures() f.hasGetSpellDuration = API.HasFeature("GetSpellDuration") f.hasSpellStartSpellType = API.HasFeature("SpellStartSpellType") + -- v2.39+ Unit GUID events and granular unit event CVars + f.hasUnitGuidEvents = API.HasFeature("UnitGuidEvents") + f.hasUnitCombatGuid = API.HasFeature("UnitCombatGuid") + f.hasUnitEventGranularControl = API.HasFeature("UnitEventGranularControl") + + -- v2.40+ Corpse GUID param in spell events and packed GUID fix + f.hasSpellStartCorpseParam = API.HasFeature("SpellStartCorpseParam") + f.hasSpellGoCorpseParam = API.HasFeature("SpellGoCorpseParam") + f.hasPackedGuidFix = API.HasFeature("PackedGuidFix") + -- Runtime detection for enhanced spell functions (verify by testing) if f.hasEnhancedSpellFunctions and GetSpellTexture then local success, result = pcall(function() @@ -531,6 +573,13 @@ API.defaultSettings = { -- v2.26+ CVars NP_EnableSpellHealEvents = "0", -- Enable SPELL_HEAL_BY_SELF/OTHER/ON_SELF events NP_EnableSpellEnergizeEvents = "0", -- Enable SPELL_ENERGIZE_BY_SELF/OTHER/ON_SELF events + -- v2.39+ CVars + NP_EnableUnitEventsPet = "1", -- Fire unit events for pet/partypet1-4 tokens + NP_EnableUnitEventsParty = "1", -- Fire unit events for party1-4 tokens + NP_EnableUnitEventsRaid = "1", -- Fire unit events for raid1-40 tokens + NP_EnableUnitEventsMouseover = "1", -- Fire unit events for mouseover token + NP_EnableUnitEventsGuid = "1", -- Fire UNIT_* events using raw GUID as unit token (mimics SuperWoW) + NP_EnableUnitEventsGuidFiltering = "1", -- Suppress high-freq raw GUID events that have _GUID variants } -- Get a Nampower setting value @@ -2189,10 +2238,36 @@ API.VICTIMSTATE = { DEFLECTS = 8, } +-- Unit GUID events (v2.39+) +-- Fire once per unit state change, identified by GUID rather than unit token. +-- Unlike standard UNIT_HEALTH etc. (one event per registered token), each GUID event +-- fires exactly once and carries flags for player/target/mouseover/pet/party/raid. +-- Parameters: guid, isPlayer, isTarget, isMouseover, isPet, partyIndex, raidIndex +API.UNIT_GUID_EVENTS = { + "UNIT_HEALTH_GUID", + "UNIT_MANA_GUID", + "UNIT_RAGE_GUID", + "UNIT_ENERGY_GUID", + "UNIT_PET_GUID", + "UNIT_FLAGS_GUID", + "UNIT_AURA_GUID", + "UNIT_DYNAMIC_FLAGS_GUID", + "UNIT_NAME_UPDATE_GUID", + "UNIT_PORTRAIT_UPDATE_GUID", + "UNIT_MODEL_CHANGED_GUID", + "UNIT_INVENTORY_CHANGED_GUID", + "PLAYER_GUILD_UPDATE_GUID", + -- UNIT_COMBAT_GUID: guid, action, damage, school, hitInfo, isPet, partyIndex, raidIndex + "UNIT_COMBAT_GUID", +} + -- Spell start/go event names (v2.25+) -- These provide improved granularity over UNIT_CASTEVENT for spell cast tracking -- SPELL_START: Server notifies a spell with cast time has begun -- SPELL_GO: Server notifies a spell has completed casting (projectile launched, instant landed) +-- v2.38+: SPELL_START includes arg7=durationMs, arg8=spellType +-- v2.40+: SPELL_START includes arg9=corpseOwnerGuid (string or nil) +-- v2.40+: SPELL_GO includes arg8=corpseOwnerGuid (string or nil) API.SPELL_START_EVENTS = { "SPELL_START_SELF", -- Player starts casting (requires NP_EnableSpellStartEvents=1) "SPELL_START_OTHER", -- Other unit starts casting diff --git a/Utility.lua b/Utility.lua index b396fdb..65a03a6 100644 --- a/Utility.lua +++ b/Utility.lua @@ -732,12 +732,14 @@ function lib:HasPfUI76() 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.38.0+ (pfUI 7.6+ hard requirement, bumped from 2.37 in pfUI update 2026-02-18) + -- Verify Nampower v2.40.0+ (pfUI 7.6+ hard requirement, bumped from 2.38 on 2026-02-21; + -- v2.40.0 fixes packed GUID parsing that caused target GUIDs to appear as 0x000000000 + -- for some players, which directly affects cast tracking reliability) 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 < 38 then return false end + if npMajor == 2 and npMinor < 40 then return false end -- Verify the new tables exist if not pfUI.libdebuff_casts then return false end @@ -4468,6 +4470,9 @@ ev:SetScript("OnEvent", function() startTime = now, duration = durationSec, endTime = durationSec > 0 and (now + durationSec) or nil, + -- v2.40+: arg4 is now correct for friendly player targets (packed GUID bug fixed). + -- Nil/zero target means no explicit target (e.g. self-cast buffs, AoE spells). + targetGuid = (arg4 and arg4 ~= "0x0000000000000000") and CleveRoids.NormalizeGUID(arg4) or nil, } if CleveRoids.debug then @@ -4502,14 +4507,24 @@ 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) + -- Clear cast tracking entry - cast completed/fired (standalone mode only). + -- v2.40+: Save the SPELL_START targetGuid before clearing so we can fall back + -- to it below when SPELL_GO arg4 is empty (e.g. AoE spells with no single target). + local startTargetGuid if not lib.hasPfUI76 and arg3 and CleveRoids.castTracking[arg3] then + startTargetGuid = CleveRoids.castTracking[arg3].targetGuid CleveRoids.castTracking[arg3] = nil end local spellId = arg2 local casterGuid = arg3 + -- v2.40+: SPELL_GO targetGuid is now correct for friendly player GUIDs. + -- Fall back to the SPELL_START-cached targetGuid for spells with no explicit + -- single target in SPELL_GO (AoE, self-cast with no target arg, etc.). local targetGuid = arg4 + if not targetGuid or targetGuid == "0x0000000000000000" then + targetGuid = startTargetGuid + end local numHit = arg6 or 0 local numMissed = arg7 or 0 @@ -8933,7 +8948,10 @@ reactiveFrame:SetScript("OnEvent", function() -- can distinguish "dodged" from other avoidance types. We only update LastSwing here -- as a generic miss indicator (combat log overwrites with specific type if dodge). if numMissed >= 1 and numHit == 0 then - -- Use current target GUID if SPELL_GO targetGuid is empty + -- Resolve the target GUID. v2.40+ fixes packed GUID parsing so player GUIDs + -- are no longer returned as 0x0000000000000000 in SPELL_GO. The fallback + -- chain here is still needed for spells that genuinely have no single target + -- in SPELL_GO (AoE, on-swing abilities, etc.). local procTarget = targetGuid if not procTarget or procTarget == "0x0000000000000000" then procTarget = pending.targetGuid