mirror of
https://github.com/brues-code/SuperCleveRoidMacros.git
synced 2026-09-16 03:38:00 +00:00
Delete the Lua paladin judgement refresh
A paladin's white swing refreshes their own judgement debuff on the victim, and the server's edit is packet-silent, so pfUI#45 was the visible symptom: the timer ran to zero while the debuff stayed up. This addon worked around it three ways at once -- a UNIT_CASTEVENT MAINHAND/OFFHAND handler in Core.lua, an AUTO_ATTACK_OTHER fallback in Conditionals.lua, and a CHAT_MSG_COMBAT_SELF_HITS parser in Utility.lua that string-matched "hit"/"crit" and guessed at melee vs spell by looking for a parenthesis -- each rewriting rec.start and pushing the result into pfUI by hand. ClassicAPI mirrors the server rule in the DLL (src/aura/JudgementRefresh.cpp), keyed off SMSG_ATTACKERSTATEUPDATE, which is the visible trigger for the invisible edit. It matches judgements by their DBC marker -- SPELLFAMILY_PALADIN with SPELL_ATTR_EX3_ALWAYS_HIT -- for any paladin's judgements, not only ours. That last detail retires the auto-detection too. The hardcoded judgementSpells list could not cover Turtle's custom judgement ranks, so a cast queued a pending scan that read the target's debuffs 0.5s later, matched names against "^Judgement", and grew the list at runtime. Matching on the DBC attribute needs no list to grow. Gone with it: judgementSpells, pendingJudgements, detectedJudgementDebuffIDs, the pending-scan pass and its queue buffer, and both cast-site hooks. The scan also registered each ID it discovered into lib.sharedDebuffs so [debuff] fallback matching worked for custom IDs. That mattered when detection went through the tracking store; the read path resolves auras through C_UnitAuras now, which returns a debuff whether or not we have a row for it.
This commit is contained in:
+1
-219
@@ -1772,43 +1772,6 @@ lib.sharedDebuffs = lib.sharedDebuffs or {
|
||||
[5209] = 6, -- Challenging Roar
|
||||
}
|
||||
|
||||
-- JUDGEMENT SPELLS: These are refreshed by the paladin's melee attacks
|
||||
-- Track them by spell ID for refresh detection
|
||||
lib.judgementSpells = lib.judgementSpells or {
|
||||
-- Vanilla IDs
|
||||
[20184] = true, -- Judgement of Justice
|
||||
[20185] = true, -- Judgement of Light (Rank 1)
|
||||
[20267] = true, -- Judgement of Light (Rank 2)
|
||||
[20268] = true, -- Judgement of Light (Rank 3)
|
||||
[20271] = true, -- Judgement of Light (Rank 4)
|
||||
[20186] = true, -- Judgement of Wisdom (Rank 1)
|
||||
[20354] = true, -- Judgement of Wisdom (Rank 2)
|
||||
[20355] = true, -- Judgement of Wisdom (Rank 3)
|
||||
[21183] = true, -- Judgement of the Crusader (Rank 1)
|
||||
[20183] = true, -- Judgement of the Crusader (Rank 2)
|
||||
[20300] = true, -- Judgement of the Crusader (Rank 3)
|
||||
[20301] = true, -- Judgement of the Crusader (Rank 4)
|
||||
[20302] = true, -- Judgement of the Crusader (Rank 5)
|
||||
[20303] = true, -- Judgement of the Crusader (Rank 6)
|
||||
|
||||
-- Turtle WoW custom judgement IDs (debuff IDs only, not cast spells)
|
||||
[51751] = true, -- Judgement of Wisdom (Rank 4) - Turtle WoW
|
||||
[51752] = true, -- Judgement of Wisdom (Rank 5) - Turtle WoW
|
||||
-- Auto-detection will discover other Turtle WoW judgement debuffs at runtime
|
||||
}
|
||||
|
||||
-- Pending judgement casts: Map cast spell ID to target for debuff ID detection
|
||||
-- When paladin casts Judgement, we need to find what debuff actually appears
|
||||
lib.pendingJudgements = lib.pendingJudgements or {}
|
||||
|
||||
-- Detected judgement debuff IDs: Maps debuff name patterns to spell IDs
|
||||
-- This gets populated as we discover what debuffs actually appear after casting
|
||||
lib.detectedJudgementDebuffIDs = lib.detectedJudgementDebuffIDs or {}
|
||||
|
||||
-- NOTE: Judgement refresh on melee hits is handled by evJudgement (below)
|
||||
-- It only uses chat-based detection when SuperWoW is unavailable;
|
||||
-- otherwise Core.lua handles it via UNIT_CASTEVENT (MAINHAND/OFFHAND)
|
||||
|
||||
-- Combined table for backwards compatibility (will be deprecated)
|
||||
lib.durations = lib.durations or {}
|
||||
for k, v in pairs(lib.personalDebuffs) do
|
||||
@@ -2413,7 +2376,6 @@ local _table_insert = table.insert -- Lua 5.0 compatible
|
||||
|
||||
-- PERFORMANCE: Static buffers for removal tracking - reused every frame
|
||||
-- Using mark-and-sweep pattern instead of table.remove() for O(1) removal
|
||||
local _pendingJudgementsBuffer = {}
|
||||
local _pendingPersonalBuffer = {}
|
||||
local _pendingCCBuffer = {}
|
||||
local _pendingSharedBuffer = {}
|
||||
@@ -2539,7 +2501,6 @@ delayedTrackingFrame:SetScript("OnUpdate", function()
|
||||
-- PERFORMANCE: Early exit if all queues are empty
|
||||
-- NOTE: Use next() instead of [1] to handle array holes from table.remove()
|
||||
-- Array holes can occur when combat log handlers remove entries mid-iteration
|
||||
local hasJudgements = lib.pendingJudgements and _next(lib.pendingJudgements)
|
||||
local hasPersonal = lib.pendingPersonalDebuffs and _next(lib.pendingPersonalDebuffs)
|
||||
local hasCC = lib.pendingCCDebuffs and _next(lib.pendingCCDebuffs)
|
||||
local hasShared = lib.pendingSharedDebuffs and _next(lib.pendingSharedDebuffs)
|
||||
@@ -2565,7 +2526,7 @@ delayedTrackingFrame:SetScript("OnUpdate", function()
|
||||
end
|
||||
end
|
||||
|
||||
if not (hasJudgements or hasPersonal or hasCC or hasShared or hasOverrides) then
|
||||
if not (hasPersonal or hasCC or hasShared or hasOverrides) then
|
||||
return
|
||||
end
|
||||
|
||||
@@ -2590,69 +2551,6 @@ delayedTrackingFrame:SetScript("OnUpdate", function()
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Process pending judgement scans to detect actual debuff IDs
|
||||
if hasJudgements then
|
||||
local writeIdx = 0
|
||||
local pendingList = lib.pendingJudgements
|
||||
|
||||
for i = 1, _getn(pendingList) do
|
||||
local pending = pendingList[i]
|
||||
-- Guard against nil entries (can occur if combat log events remove items during iteration)
|
||||
if pending then
|
||||
local elapsed = currentTime - pending.timestamp
|
||||
|
||||
-- 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 = CleveRoids.GetGUID("target")
|
||||
|
||||
if currentTargetGUID == pending.targetGUID then
|
||||
-- Scan all debuffs on target to find judgement-type debuffs
|
||||
for slot = 1, 16 do
|
||||
local _, _, _, debuffSpellID = _UnitDebuff("target", slot)
|
||||
if not debuffSpellID then break end
|
||||
|
||||
local debuffName = C_Spell.GetSpellName(debuffSpellID)
|
||||
-- Check if this is a judgement debuff (name starts with "Judgement")
|
||||
if debuffName and _string_find(debuffName, "^Judgement") then
|
||||
-- Found a judgement debuff! Store it for refresh tracking
|
||||
if not lib.detectedJudgementDebuffIDs[debuffSpellID] then
|
||||
lib.detectedJudgementDebuffIDs[debuffSpellID] = true
|
||||
lib.judgementSpells[debuffSpellID] = true -- Add to refresh list
|
||||
-- Also register as shared debuff so [debuff]/[nodebuff] fallback detection works
|
||||
-- for custom Turtle WoW spell IDs not in the hardcoded sharedDebuffs table
|
||||
if not lib.sharedDebuffs[debuffSpellID] then
|
||||
lib.sharedDebuffs[debuffSpellID] = 10 -- Standard judgement duration
|
||||
CleveRoids.InvalidateSpellNameCache()
|
||||
end
|
||||
|
||||
if debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
_string_format("|cff00ffff[Judgement Detect]|r Found debuff %s (ID:%d) from cast (ID:%d) - added to refresh + shared list",
|
||||
debuffName, debuffSpellID, pending.castSpellID)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Item processed, don't copy to output
|
||||
else
|
||||
-- Item not ready, keep it
|
||||
writeIdx = writeIdx + 1
|
||||
if writeIdx ~= i then
|
||||
pendingList[writeIdx] = pending
|
||||
end
|
||||
end
|
||||
end -- if pending
|
||||
end
|
||||
|
||||
-- PERFORMANCE: Clear remaining slots and update length
|
||||
for i = writeIdx + 1, _getn(pendingList) do
|
||||
pendingList[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Process pending personal debuffs
|
||||
if hasPersonal then
|
||||
-- Count entries properly using pairs (handles array holes)
|
||||
@@ -3864,22 +3762,6 @@ ev:SetScript("OnEvent", function()
|
||||
comboPoints = comboPoints
|
||||
})
|
||||
|
||||
-- If this is a Judgement spell cast by a Paladin, schedule a scan to find the actual debuff ID
|
||||
-- Check by ID (known judgement debuffs) OR by name (Turtle WoW custom cast spell IDs)
|
||||
local isJudgementCast = lib.judgementSpells[spellID]
|
||||
if not isJudgementCast and CleveRoids.playerClass == "PALADIN" then
|
||||
local castName = C_Spell.GetSpellName(spellID)
|
||||
isJudgementCast = castName and _string_find(castName, "^Judgement")
|
||||
end
|
||||
if CleveRoids.playerClass == "PALADIN" and isJudgementCast then
|
||||
table.insert(lib.pendingJudgements, {
|
||||
timestamp = GetTime(),
|
||||
castSpellID = spellID,
|
||||
targetGUID = targetGUID,
|
||||
targetName = targetName
|
||||
})
|
||||
end
|
||||
|
||||
if CleveRoids.debug then
|
||||
local spellName = C_Spell.GetSpellName(trackingSpellID) or "Unknown"
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
@@ -4577,21 +4459,6 @@ ev:SetScript("OnEvent", function()
|
||||
spellGoHit = true, -- Already confirmed hit from SPELL_GO
|
||||
})
|
||||
|
||||
-- Judgement scan for Paladins
|
||||
local isJudgementCast = lib.judgementSpells[spellId]
|
||||
if not isJudgementCast and CleveRoids.playerClass == "PALADIN" then
|
||||
local castName = C_Spell.GetSpellName(spellId)
|
||||
isJudgementCast = castName and string.find(castName, "^Judgement")
|
||||
end
|
||||
if CleveRoids.playerClass == "PALADIN" and isJudgementCast then
|
||||
table.insert(lib.pendingJudgements, {
|
||||
timestamp = GetTime(),
|
||||
castSpellID = spellId,
|
||||
targetGUID = targetGuid,
|
||||
targetName = targetName
|
||||
})
|
||||
end
|
||||
|
||||
if CleveRoids.debug then
|
||||
local trackingName = C_Spell.GetSpellName(trackingSpellID) or "Unknown"
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
@@ -5441,91 +5308,6 @@ evCleanup:SetScript("OnEvent", function()
|
||||
end
|
||||
end)
|
||||
|
||||
-- Judgement refresh on melee hits
|
||||
-- Priority: SuperWoW UNIT_CASTEVENT > Nampower AUTO_ATTACK_OTHER > Chat log fallback
|
||||
-- This chat-based fallback is only used if neither SuperWoW nor Nampower v2.24+ is available
|
||||
local evJudgement = CreateFrame("Frame", "CleveRoidsLibDebuffJudgementRefreshFrame", UIParent)
|
||||
|
||||
-- Only use chat-based detection if SuperWoW and Nampower auto-attack events are not available
|
||||
local hasAutoAttackEvents = CleveRoids.NampowerAPI and CleveRoids.NampowerAPI.features
|
||||
and CleveRoids.NampowerAPI.features.hasAutoAttackEvents
|
||||
if not CleveRoids.hasSuperwow and not hasAutoAttackEvents then
|
||||
evJudgement:RegisterEvent("CHAT_MSG_COMBAT_SELF_HITS")
|
||||
evJudgement:RegisterEvent("CHAT_MSG_COMBAT_SELF_MISSES")
|
||||
end
|
||||
|
||||
evJudgement:SetScript("OnEvent", function()
|
||||
-- Skip if SuperWoW or Nampower auto-attack events handle this
|
||||
if CleveRoids.hasSuperwow then return end
|
||||
if hasAutoAttackEvents then return end
|
||||
-- Only process for paladins
|
||||
if CleveRoids.playerClass ~= "PALADIN" then return end
|
||||
|
||||
if not arg1 then return end
|
||||
|
||||
-- Debug: Show all combat hit events if debug is enabled
|
||||
if CleveRoids.debug and event == "CHAT_MSG_COMBAT_SELF_HITS" then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffaaaaaa[Combat Hit Event]|r " .. arg1)
|
||||
end
|
||||
|
||||
-- Check if this is a melee hit (not a spell hit)
|
||||
-- CHAT_MSG_COMBAT_SELF_HITS contains both melee and spell hits
|
||||
-- Filter out spell hits by checking for spell names in parentheses or common patterns
|
||||
-- Melee hits look like: "You hit Target for X." or "You crit Target for X."
|
||||
local isSpellHit = string.find(arg1, "%(") -- Spell hits often have parentheses
|
||||
if isSpellHit then return end
|
||||
|
||||
-- Must contain "hit" or "crit" to be a valid melee attack
|
||||
local lowerMsg = string.lower(arg1)
|
||||
local hasHit = string.find(lowerMsg, "hit") or string.find(lowerMsg, "crit")
|
||||
if not hasHit then return end
|
||||
|
||||
-- Get current target
|
||||
local targetGUID = CleveRoids.GetGUID("target")
|
||||
if not targetGUID then return end
|
||||
|
||||
if not lib.objects[targetGUID] then return end
|
||||
|
||||
-- Refresh all active Judgements on the target
|
||||
for spellID, rec in pairs(lib.objects[targetGUID]) do
|
||||
if lib.judgementSpells[spellID] and rec.start and rec.duration then
|
||||
-- Only refresh if the Judgement is still active and was cast by player
|
||||
local remaining = rec.duration + rec.start - GetTime()
|
||||
if remaining > 0 and rec.caster == "player" then
|
||||
-- Refresh the Judgement by updating the start time
|
||||
rec.start = GetTime()
|
||||
|
||||
if CleveRoids.debug then
|
||||
local spellName = C_Spell.GetSpellName(spellID) or "Unknown"
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ffaa[Judgement Refresh]|r Refreshed %s (ID:%d) on melee hit - new duration: %ds",
|
||||
spellName, spellID, rec.duration)
|
||||
)
|
||||
end
|
||||
|
||||
-- Also sync to pfUI if it's loaded (pre-7.6 only)
|
||||
if pfUI and pfUI.api and pfUI.api.libdebuff then
|
||||
local targetName = lib.guidToName[targetGUID] or UnitName("target")
|
||||
local targetLevel = UnitLevel("target") or 0
|
||||
local spellName = C_Spell.GetSpellName(spellID)
|
||||
|
||||
if spellName and targetName then
|
||||
local effectName = CleveRoids.StripRank(spellName)
|
||||
pfUI.api.libdebuff:AddEffect(targetName, targetLevel, effectName, rec.duration, "player")
|
||||
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ffaa[pfUI Judgement Refresh]|r Synced %s refresh to pfUI",
|
||||
effectName)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- TALENT MODIFIER SYSTEM
|
||||
|
||||
-- Database of talent modifiers for debuff durations
|
||||
|
||||
Reference in New Issue
Block a user