mirror of
https://github.com/brues-code/SuperCleveRoidMacros.git
synced 2026-09-16 03:38:00 +00:00
fix ! prefix with explicit conditionals and Judgement of Light debuff detection
This commit is contained in:
+32
-3
@@ -149,6 +149,33 @@ function CleveRoids.InvalidateSpellNameCache()
|
||||
_spellNameToIDsBuilt = false
|
||||
end
|
||||
|
||||
-- Check if a debuff is shared by spell ID or by name (for custom/Turtle WoW IDs).
|
||||
-- Falls back to checking if the debuff NAME matches any known shared debuff name
|
||||
-- in the spell name cache, even if the specific spell ID is unregistered.
|
||||
local function IsSharedDebuffByIdOrName(lib, spellID, debuffName)
|
||||
if not lib then return false end
|
||||
-- Direct ID check (fast path)
|
||||
if lib.IsPersonalDebuff and lib:IsPersonalDebuff(spellID) == false then
|
||||
return true
|
||||
end
|
||||
-- Name-based fallback: if ANY spell ID for this name is in sharedDebuffs, treat as shared.
|
||||
-- This handles custom server spell IDs (e.g., Turtle WoW Judgement variants) that have
|
||||
-- the same debuff name but different IDs from the hardcoded vanilla entries.
|
||||
if debuffName then
|
||||
local knownIDs = GetSpellIDsForName(debuffName)
|
||||
if knownIDs then
|
||||
for _, kid in ipairs(knownIDs) do
|
||||
if lib.sharedDebuffs and lib.sharedDebuffs[kid] then
|
||||
-- Also register this new spell ID so future checks are fast
|
||||
lib.sharedDebuffs[spellID] = lib.sharedDebuffs[kid]
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- PERFORMANCE: Equipment cache for HasGearEquipped (avoids 19-slot scan per call)
|
||||
-- Invalidated on UNIT_INVENTORY_CHANGED via CleveRoids.InvalidateEquipmentCache()
|
||||
-- Enhanced with Nampower v2.18+ GetEquippedItems when available
|
||||
@@ -3705,7 +3732,7 @@ function CleveRoids.ValidateUnitDebuff(unit, args)
|
||||
if gufResult ~= nil then
|
||||
-- GetUnitField was available and searched
|
||||
if gufResult then
|
||||
local isShared = lib and lib.IsPersonalDebuff and lib:IsPersonalDebuff(gufSpellId) == false
|
||||
local isShared = IsSharedDebuffByIdOrName(lib, gufSpellId, args.name)
|
||||
if isShared then
|
||||
found = true
|
||||
stacks = gufStacks or 0
|
||||
@@ -3739,7 +3766,8 @@ function CleveRoids.ValidateUnitDebuff(unit, args)
|
||||
if matched then
|
||||
-- IMPORTANT: Only use fallback for SHARED debuffs
|
||||
-- Personal debuffs must come from tracking table (caster check)
|
||||
local isShared = lib and lib.IsPersonalDebuff and lib:IsPersonalDebuff(debuffSpellID) == false
|
||||
-- Uses name-based fallback for custom spell IDs (e.g., Turtle WoW Judgements)
|
||||
local isShared = IsSharedDebuffByIdOrName(lib, debuffSpellID, args.name)
|
||||
if isShared then
|
||||
found = true
|
||||
texture = tex
|
||||
@@ -3769,7 +3797,8 @@ function CleveRoids.ValidateUnitDebuff(unit, args)
|
||||
end
|
||||
if matched then
|
||||
-- IMPORTANT: Only use fallback for SHARED debuffs
|
||||
local isShared = lib and lib.IsPersonalDebuff and lib:IsPersonalDebuff(buffSpellID) == false
|
||||
-- Uses name-based fallback for custom spell IDs (e.g., Turtle WoW Judgements)
|
||||
local isShared = IsSharedDebuffByIdOrName(lib, buffSpellID, args.name)
|
||||
if isShared then
|
||||
found = true
|
||||
texture = tex
|
||||
|
||||
@@ -1881,17 +1881,11 @@ function CleveRoids.ParseMsg(msg)
|
||||
|
||||
-- With a condition block present, build out the conditionals table
|
||||
|
||||
-- optional spam/cancel flags (apply only when we actually have a [] block)
|
||||
-- ! prefix with explicit conditionals: store as a flag for execution-time anti-toggle,
|
||||
-- rather than injecting an implicit conditional that gets AND'd with user conditions.
|
||||
-- The anti-toggle check happens in DoWithConditionals before CastSpellByName.
|
||||
if noSpam and noSpam ~= "" then
|
||||
local spamCond = CleveRoids.GetSpammableConditional(action)
|
||||
if spamCond then
|
||||
conditionals[spamCond] = { action }
|
||||
-- Also create _groups entry so Multi() finds it when combined with explicit conditionals
|
||||
if not conditionals._groups then
|
||||
conditionals._groups = {}
|
||||
end
|
||||
conditionals._groups[spamCond] = { { values = { action }, operator = "OR" } }
|
||||
end
|
||||
conditionals.noSpam = true
|
||||
end
|
||||
if cancelAura and cancelAura ~= "" then
|
||||
conditionals.cancelaura = action
|
||||
@@ -2481,8 +2475,30 @@ function CleveRoids.DoWithConditionals(msg, hook, fixEmptyTargetFunc, targetBefo
|
||||
end
|
||||
end
|
||||
if action == CastSpellByName then
|
||||
-- Special case: !Attack should use AttackTarget() which doesn't toggle
|
||||
-- This is more reliable than CastSpellByName("Attack") which toggles on/off
|
||||
-- ! prefix anti-toggle: prevent CastSpellByName from toggling off active spells.
|
||||
-- For Attack/AutoShot/Shoot, use the non-toggling AttackTarget() API.
|
||||
-- For self-buffs/shapeshifts, skip if already active on the player.
|
||||
if conditionals.noSpam then
|
||||
local spamType = CleveRoids.spamConditions[msg]
|
||||
if spamType == "checkchanneled" then
|
||||
-- Attack/AutoShot/Shoot: use non-toggling API
|
||||
if msg == CleveRoids.Localized.Attack then
|
||||
AttackTarget()
|
||||
if needRetarget then TargetLastTarget() end
|
||||
conditionals.target = origTarget
|
||||
return true
|
||||
end
|
||||
-- AutoShot/Shoot: checkchanneled prevents toggle (already handled below)
|
||||
else
|
||||
-- Self-buff/shapeshift: skip if already active on player
|
||||
if CleveRoids.ValidatePlayerBuff(msg) then
|
||||
if needRetarget then TargetLastTarget() end
|
||||
conditionals.target = origTarget
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Legacy path: !Attack without explicit conditionals (checkchanneled injected)
|
||||
if msg == CleveRoids.Localized.Attack and conditionals.checkchanneled then
|
||||
AttackTarget()
|
||||
elseif CleveRoids.hasSuperwow and conditionals.target then
|
||||
|
||||
@@ -163,6 +163,7 @@ CleveRoids.ignoreKeywords = {
|
||||
action = true,
|
||||
ignoretooltip = true,
|
||||
cancelaura = true,
|
||||
noSpam = true, -- ! prefix flag: prevent toggle-off at execution time
|
||||
_operators = true, -- Metadata for AND/OR operator tracking
|
||||
_groups = true, -- Grouped conditional values for AND/OR evaluation
|
||||
multiscan = true, -- Processed before Keywords loop (target resolution)
|
||||
|
||||
+14
-2
@@ -2996,10 +2996,16 @@ delayedTrackingFrame:SetScript("OnUpdate", function()
|
||||
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 list",
|
||||
_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
|
||||
@@ -4043,7 +4049,13 @@ ev:SetScript("OnEvent", function()
|
||||
})
|
||||
|
||||
-- If this is a Judgement spell cast by a Paladin, schedule a scan to find the actual debuff ID
|
||||
if CleveRoids.playerClass == "PALADIN" and lib.judgementSpells[spellID] then
|
||||
-- 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 = _SpellInfo(spellID)
|
||||
isJudgementCast = castName and _string_find(castName, "^Judgement")
|
||||
end
|
||||
if CleveRoids.playerClass == "PALADIN" and isJudgementCast then
|
||||
table.insert(lib.pendingJudgements, {
|
||||
timestamp = GetTime(),
|
||||
castSpellID = spellID,
|
||||
|
||||
Reference in New Issue
Block a user