Add [locked]/[nolocked] school-interrupt conditional via C_LossOfControl

Detects a spell-school interrupt lockout (Counterspell/Kick/Pummel/Earth
Shock) on the player -- the server-side lockout that no debuff scan can see,
since it's a SMSG_SPELL_COOLDOWN packet, not an aura. ClassicAPI's
C_LossOfControl aggregates it as SCHOOL_INTERRUPT with a lockoutSchool mask.

ClassicAPI.GetSchoolLockout() returns the locked school mask; ValidateSchoolLocked
tests a school name against it (bitmask check without the 5.1-only % operator).
[locked] = any school kicked, [locked:frost] = that school, [locked:fire/frost]
= either; [nolocked:...] negates with AND (neither). Registered in
BOOLEAN_CONDITIONALS for the bare form; LOSS_OF_CONTROL_ADDED/UPDATE wired to
refresh the icon. Full silences remain [mycc:silence].
This commit is contained in:
Brues
2026-07-28 08:57:37 -05:00
parent 2e8ed33a6a
commit dd61767eb9
3 changed files with 99 additions and 30 deletions
+25
View File
@@ -208,6 +208,31 @@ function API.GetEnchantName(enchantID)
return info and info.name or nil
end
--------------------------------------------------------------------------------
-- Loss Of Control
--------------------------------------------------------------------------------
-- Locked spell-school mask from an active SCHOOL_INTERRUPT (Counterspell / Kick /
-- Pummel / Earth Shock lockout) on the player, or 0 when not kicked. Read from
-- C_LossOfControl, which synthesizes the lockout from the server's own
-- SMSG_SPELL_COOLDOWN packet -- a state no debuff scan can see. Also returns the
-- seconds remaining (nil if ClassicAPI didn't observe the applying cast). Returns
-- 0 for a client without C_LossOfControl. Player-only (vanilla LoC is local-only).
function API.GetSchoolLockout()
if type(C_LossOfControl) ~= "table"
or type(C_LossOfControl.GetActiveLossOfControlDataCount) ~= "function" then
return 0, nil
end
local n = C_LossOfControl.GetActiveLossOfControlDataCount() or 0
for i = 1, n do
local d = C_LossOfControl.GetActiveLossOfControlData(i)
if d and d.locType == "SCHOOL_INTERRUPT" then
return d.lockoutSchool or 0, d.timeRemaining
end
end
return 0, nil
end
--------------------------------------------------------------------------------
-- Spell
--------------------------------------------------------------------------------