4 Commits

Author SHA1 Message Date
Brues 5e27e6fe58 Name the macro slot count
Three loops walked 1..36 by hand, two of them re-arguing in comments why 36
is the right number. It is: the client addresses 18 account-wide macros at
1-18 and 18 character-specific ones at 19-36, and that range is what
GetMacroInfo and C_Macro.SetMacroDisplay index. Nothing in the API hands it
back -- GetNumMacros() returns how many of each tab are used, which cannot be
summed into a range, because the character block still starts at 19 when the
account block is empty. Blizzard's MAX_MACROS is no better: it lives in the
load-on-demand Blizzard_MacroUI and is nil until the macro window is opened.

So CleveRoids.MAX_MACRO_SLOTS in Init.lua, carrying that reasoning once.
ValidateAllMacros also dropped a numAccountMacros it computed and never read.

ReleaseDisplays keeps sweeping the full range rather than the macros it knows
it published: PublishAllDisplays clears that record on each re-parse, so a
macro claimed before one and gone after it would keep our last published value
forever. Releasing a slot we never claimed costs nothing, and it runs once.
2026-09-11 13:57:11 -05:00
Brues 6edd37a76f Require ClassicAPI v1.15.0
An out-of-date ClassicAPI did not degrade the addon, it decapitated it.
Utility.lua calls ev:RegisterUnitEvent at file scope (v1.15.0), so on an
older build that call raises and Lua abandons the rest of the chunk --
every definition below line 4118 of a 10040-line file, some 6000 lines,
silently never happens. What the user sees is the first one a common path
reaches: PLAYER_TARGET_CHANGED calling a nil ClearResistState, once per
target swap, forever.

The requirement check still said v1.12.1 (the positional
C_UnitAuras.UnitAura), so the affected client sailed through it and the
warning it did print promised only that "dispel-type conditionals will be
unavailable" -- describing a graceful degradation that was not happening.
The gate is now v1.15.0 and says the addon cannot finish loading, with the
installed version in the message the way the Nampower branch does it.
ClassicAPI.lua gains GetVersion() to decode CLASSIC_API_VERSION, keeping
the X*10000 + Y*100 + Z encoding inside that module, and its header notes
that the minimum has to rise with any ClassicAPI call adopted at file
scope -- that is the property that turns a version mismatch into a silent
half-load rather than a missing feature.

C_Macro.SetMacroDisplay also ships in v1.15.0, which retires the last
pre-ClassicAPI display path:

  useClassicAPIDisplay folds into ClassicAPIMacroDisplay. The two were
  always equal -- set together at load, cleared together in
  ReleaseDisplays -- and one of them is a handshake ClassicAPI reads, so
  a second name for the same state could only ever drift.

  TestForAllActiveActions loses the per-slot ACTIONBAR_SLOT_CHANGED
  fan-out. Publishing repaints every slot holding the macro through the
  client's own notifier; the fan-out was what ran when SetMacroDisplay
  was unavailable, and its one remaining reachable state was after
  DisableAddon, where ReleaseDisplays has already handed all 36 macros
  back and ClassicAPI repaints them itself.

The load-time feature detect stays, with a new reason: below the minimum
the addon is already broken, so a nil SetMacroDisplay now means ClassicAPI
is absent outright -- the case the requirement check warns about and then
keeps running.
2026-09-11 13:44:09 -05:00
Brues c8bc4c134d Filter UNIT_AURA by unit token and drop the unit streams in realtime mode
Two handlers opened by testing arg1 against a fixed set of unit tokens, so
every other unit's copy of UNIT_AURA reached Lua only to be compared away
-- in a raid that is the bulk of them. ClassicAPI's RegisterUnitEvent
pushes that filter into the client, so the handler only runs for the units
named. Filtering is per (frame, event), so the other events sharing the
libdebuff frame are unaffected.

  Utility.lua      UNIT_AURA -> "target"            (libdebuff seeding)
  ComboPointTracker UNIT_AURA -> "target", "player"

Extensions register through CleveRoids.RegisterEvent, so ExtensionsManager
gains a RegisterUnitEvent alongside it.

Separately, the main frame's unit state streams (UNIT_AURA / UNIT_HEALTH /
UNIT_POWER, or the _GUID variants under Nampower v2.39+) are now registered
only in event-driven mode. Their handlers are wholly wrapped in
`realtime == 0`, so with realtime on every one of them crossed into Lua and
returned immediately while the OnUpdate did the refreshing. Registration is
applied at load, again at VARIABLES_LOADED once the saved setting is
readable, and whenever /cleveroid realtime flips it.

Those three stay plain RegisterEvent calls: their handlers ignore the unit
and refresh every macro, and a conditional may name any unit
([@party3,hp:<50], @focus, @mouseover), so narrowing the token set would
leave those icons stale. The _GUID variants could not be filtered anyway --
their first argument is a GUID, not a unit token.
2026-09-11 00:42:42 -05:00
Brues 5213bd5474 Migrate to ClassicAPI for macro display, auras and timing
Squash of the classicapi_next branch (10 commits). ClassicAPI is now a hard
requirement, and the Lua-side reimplementations it supersedes are gone:
net -1087 lines across 12 files.

Macro display: resolved macro actions are published through
C_Macro.SetMacroDisplay, so the client draws macro buttons and the
action-bar function overrides this addon used to install are removed.
Ownership is per macro -- ClassicAPI keeps the macros we never claim.

Auras and timing: ClassicAPI is the source of truth for non-player aura
timing via the positional C_UnitAuras.UnitAura, replacing the write-only
buff tracking tables and the overflow-slot fallback.

Cleanup: the hasPfUI76 flag and the pfUI 7.6 branches it gated, two
silently-shadowed code paths, and per-call allocations in the event and
publish paths (SPELL_CAST_EVENT merged). Packaging moves to
brues-code/packager@vCAPI.

Macro syntax: a clause may carry a leading run of [group] blocks sharing
one action, Blizzard-style -- groups are OR'd, first pass wins, and []
always passes. The ;-separated form is unchanged and mixes freely. @focus
clauses with no focus set now fail quietly instead of printing
"Invalid target" on the way past.
2026-09-11 00:30:36 -05:00
9 changed files with 119 additions and 63 deletions
+19 -6
View File
@@ -3,11 +3,16 @@
ClassicAPI is a client mod (sibling to Nampower/SuperWoW) that backports the
modern C_* API into the 1.12.1 Lua environment. It is a HARD REQUIREMENT of
this addon (ClassicAPI v1.12.1+, which added the positional
C_UnitAuras.UnitAura), so the wrappers below call the API directly — no
fallbacks. The load-time requirement check (Core.lua) uses IsAvailable() to
warn when the DLL is missing and HasMinimumVersion() when it's too old; users
who don't want ClassicAPI should run the upstream addon.
this addon (ClassicAPI v1.15.0+, which added frame:RegisterUnitEvent), so the
wrappers below call the API directly — no fallbacks. The load-time requirement
check (Core.lua) uses IsAvailable() to warn when the DLL is missing and
HasMinimumVersion() when it's too old; users who don't want ClassicAPI should
run the upstream addon.
The minimum is not advisory: Utility.lua calls frame:RegisterUnitEvent at file
scope, so an older ClassicAPI aborts that chunk and leaves most of the addon
undefined. Raise the Core.lua minimum in step with any new API adopted at file
scope.
Detection: the global CLASSIC_API_VERSION is defined once the client has
booted, encoded as X*10000 + Y*100 + Z for a vX.Y.Z tag (untagged dev builds
@@ -37,6 +42,14 @@ function API.GetVersionNumber()
return CLASSIC_API_VERSION or 0
end
-- Returns the loaded version as major, minor, patch (0, 0, 0 if absent).
function API.GetVersion()
local v = CLASSIC_API_VERSION or 0
local major = math.floor(v / 10000)
local minor = math.floor(v / 100) - major * 100
return major, minor, v - math.floor(v / 100) * 100
end
-- True if the ClassicAPI client mod is loaded at all.
function API.IsAvailable()
return CLASSIC_API_VERSION ~= nil
@@ -56,7 +69,7 @@ end
-- Scan one aura range of `unit` (filter = "HELPFUL" or "HARMFUL") for an aura
-- matching the dispel type. Uses the positional C_UnitAuras.UnitAura (added in
-- ClassicAPI v1.12.1, this addon's minimum) -- no table allocated per slot, with
-- ClassicAPI v1.12.1, below this addon's minimum) -- no table allocated per slot, with
-- dispelName as the 4th return. The filtered index self-terminates at the end of
-- the range (nil name); 48 is a backstop over vanilla's 32 helpful / 16 harmful slots.
local function scanDispel(unit, filter, dispelType, wantAny)
+4 -4
View File
@@ -745,7 +745,7 @@ function Extension.OnLoad()
Extension.RegisterEvent("SPELLCAST_FAILED", "OnSpellcastFailed")
Extension.RegisterEvent("SPELLCAST_INTERRUPTED", "OnSpellcastInterrupted")
Extension.RegisterEvent("PLAYER_TARGET_CHANGED", "OnTargetChanged")
Extension.RegisterEvent("UNIT_AURA", "OnUnitAura")
Extension.RegisterUnitEvent("UNIT_AURA", "OnUnitAura", "target", "player")
Extension.RegisterEvent("PLAYER_COMBO_POINTS", "OnComboPointsChanged")
-- PERFORMANCE OPTIMIZATION: Removed OnUpdate polling for combo points
@@ -765,10 +765,10 @@ function Extension.OnTargetChanged()
CleveRoids.UpdateComboPoints()
end
-- Registered as a unit event for target and player, so arg1 is always one of
-- those two -- no token check needed.
function Extension.OnUnitAura()
if arg1 == "target" or arg1 == "player" then
CleveRoids.UpdateComboPoints()
end
CleveRoids.UpdateComboPoints()
end
function Extension.OnComboPointsChanged()
+54 -31
View File
@@ -198,10 +198,12 @@ requirementCheckFrame:SetScript("OnEvent", function()
local hasNampower30 = hasNampower and CleveRoids.NampowerAPI
and CleveRoids.NampowerAPI.HasMinimumVersion(3, 0, 0)
local hasClassicAPI = CleveRoids.ClassicAPI and CleveRoids.ClassicAPI.IsAvailable()
-- v1.12.1 added the positional C_UnitAuras.UnitAura the dispel conditionals use.
local hasClassicAPI1121 = hasClassicAPI and CleveRoids.ClassicAPI.HasMinimumVersion(1, 12, 1)
-- v1.15.0 added frame:RegisterUnitEvent, which Utility.lua calls at file scope.
-- On an older build that call raises, aborting the rest of the chunk -- so this
-- is not a degraded-features warning, it's "the addon did not finish loading".
local hasClassicAPI1150 = hasClassicAPI and CleveRoids.ClassicAPI.HasMinimumVersion(1, 15, 0)
if not hasNampower30 or not hasUnitXP or not hasClassicAPI or not hasClassicAPI1121 then
if not hasNampower30 or not hasUnitXP or not hasClassicAPI or not hasClassicAPI1150 then
-- Show warnings (don't disable — tearing down a partially-initialized addon causes hangs)
if not hasNampower then
CleveRoids.Print("|cFFFF9900WARNING:|r |cFF00FFFFAvitasia's Nampower v3.0.0+|r is required:")
@@ -221,10 +223,11 @@ requirementCheckFrame:SetScript("OnEvent", function()
CleveRoids.Print("|cFFFF9900WARNING:|r |cFF00FFFFClassicAPI|r is required:")
CleveRoids.Print("https://github.com/brues-code/ClassicAPI")
CleveRoids.Print("Dispel-type and movement conditionals will be unavailable without it.")
elseif not hasClassicAPI1121 then
CleveRoids.Print("|cFFFF9900WARNING:|r |cFF00FFFFClassicAPI v1.12.1+|r is required:")
elseif not hasClassicAPI1150 then
local major, minor, patch = CleveRoids.ClassicAPI.GetVersion()
CleveRoids.Print(format("|cFFFF9900WARNING:|r |cFF00FFFFClassicAPI v1.15.0+|r is required (you have v%d.%d.%d):", major, minor, patch))
CleveRoids.Print("https://github.com/brues-code/ClassicAPI")
CleveRoids.Print("Dispel-type conditionals will be unavailable with this older version.")
CleveRoids.Print("The addon cannot finish loading on this version -- update ClassicAPI.")
end
end
@@ -591,6 +594,10 @@ frame:SetScript("OnEvent", function()
if type(CleveRoidMacros.macrocheck) ~= "number" then
CleveRoidMacros.macrocheck = 1 -- enabled by default
end
-- The saved realtime setting is only readable now; the unit streams were
-- registered at load assuming event-driven mode.
CleveRoids.ApplyUnitStreamEvents()
end)
-- Queues a full update of all action bars.
@@ -1135,7 +1142,7 @@ local publishedDisplay = {}
-- nothing matched" and shows the question mark. Skipping the call instead would hand
-- the macro back to ClassicAPI's own #showtooltip parser.
function CleveRoids.PublishDisplay(actions)
if not CleveRoids.useClassicAPIDisplay then return end
if not CleveRoids.ClassicAPIMacroDisplay then return end
local macroID = actions and actions.macroID
if not macroID then return end -- SuperMacro macros have no Blizzard index
@@ -1150,7 +1157,7 @@ end
-- ClassicAPI re-evaluates nothing for us. Covers macros that aren't on a bar too,
-- which is what keeps the macro window grid's icons correct.
function CleveRoids.PublishAllDisplays()
if not CleveRoids.useClassicAPIDisplay then return end
if not CleveRoids.ClassicAPIMacroDisplay then return end
-- Forget what we published so every macro republishes once. Callers reach here
-- after login and after a re-parse, where a cached value could otherwise
-- suppress the publish a freshly rebuilt macro still needs.
@@ -1165,13 +1172,16 @@ end
-- Hand every macro back to ClassicAPI's own parser and stop claiming ownership.
function CleveRoids.ReleaseDisplays()
if not CleveRoids.useClassicAPIDisplay then return end
for i = 1, 36 do
if not CleveRoids.ClassicAPIMacroDisplay then return end
-- Sweep the whole index space rather than the macros we know we published:
-- PublishAllDisplays clears that record on every re-parse, so a macro claimed
-- before one and gone after it would keep our last value forever. Releasing a
-- slot we never claimed costs nothing, and this runs once.
for i = 1, CleveRoids.MAX_MACRO_SLOTS do
C_Macro.SetMacroDisplay(i, nil)
end
publishedDisplay = {}
CleveRoids.ClassicAPIMacroDisplay = false
CleveRoids.useClassicAPIDisplay = false
end
-- PERFORMANCE: Static buffer references for hot path
@@ -1217,17 +1227,10 @@ function CleveRoids.TestForAllActiveActions()
local slots = actionsToSlots[actions]
local stateChanged = CleveRoids.TestForActiveAction(actions)
if stateChanged then
if CleveRoids.useClassicAPIDisplay then
-- Publishing repaints every slot holding this macro through the
-- client's own notifier, so the per-slot fan-out below is redundant.
CleveRoids.PublishDisplay(actions)
else
-- Send event to ALL slots that use this macro
local count = slots._count
for j = 1, count do
CleveRoids.SendEventForAction(slots[j], "ACTIONBAR_SLOT_CHANGED", slots[j])
end
end
-- Publishing repaints every slot holding this macro through the client's
-- own notifier, so there is no per-slot fan-out to do here. It no-ops once
-- ReleaseDisplays has handed the macros back.
CleveRoids.PublishDisplay(actions)
end
-- Clear for reuse (reset count and clear buffer reference)
for j = 1, slots._count do
@@ -4464,18 +4467,36 @@ if type(C_LossOfControl) == "table" then
CleveRoids.Frame:RegisterEvent("LOSS_OF_CONTROL_ADDED")
CleveRoids.Frame:RegisterEvent("LOSS_OF_CONTROL_UPDATE")
end
-- Use GUID events when available (v2.39+), fall back to standard per-token events
-- The unit state streams that drive icon refresh: GUID events when Nampower
-- provides them (v2.39+, one event per unit change rather than one per token),
-- else the stock per-token events. These cannot become RegisterUnitEvent calls
-- -- the handlers ignore the unit and refresh every macro, because a conditional
-- may name any unit ([@party3,hp:<50], @focus, @mouseover), so narrowing the
-- token set would leave those icons stale.
local unitStreamEvents
if CleveRoids.NampowerAPI.features.hasUnitGuidEvents then
CleveRoids.Frame:RegisterEvent("UNIT_AURA_GUID")
CleveRoids.Frame:RegisterEvent("UNIT_HEALTH_GUID")
CleveRoids.Frame:RegisterEvent("UNIT_MANA_GUID")
CleveRoids.Frame:RegisterEvent("UNIT_RAGE_GUID")
CleveRoids.Frame:RegisterEvent("UNIT_ENERGY_GUID")
unitStreamEvents = { "UNIT_AURA_GUID", "UNIT_HEALTH_GUID", "UNIT_MANA_GUID", "UNIT_RAGE_GUID", "UNIT_ENERGY_GUID" }
else
CleveRoids.Frame:RegisterEvent("UNIT_AURA")
CleveRoids.Frame:RegisterEvent("UNIT_HEALTH")
CleveRoids.Frame:RegisterEvent("UNIT_POWER")
unitStreamEvents = { "UNIT_AURA", "UNIT_HEALTH", "UNIT_POWER" }
end
-- They do fire continuously for every unit in range, and in realtime mode their
-- handlers do nothing at all: the OnUpdate refreshes on every throttled tick and
-- QueueActionUpdate no-ops. Rather than pay a Lua dispatch per event to return
-- early, drop the registrations entirely while realtime is on. Re-applied at
-- VARIABLES_LOADED (when the saved value is first known) and whenever
-- `/cleveroid realtime` flips it.
function CleveRoids.ApplyUnitStreamEvents()
local eventDriven = not CleveRoidMacros or CleveRoidMacros.realtime == 0
for i = 1, table.getn(unitStreamEvents) do
if eventDriven then
CleveRoids.Frame:RegisterEvent(unitStreamEvents[i])
else
CleveRoids.Frame:UnregisterEvent(unitStreamEvents[i])
end
end
end
CleveRoids.ApplyUnitStreamEvents()
if CleveRoids.hasSuperwow then
CleveRoids.Frame:RegisterEvent("UNIT_CASTEVENT")
end
@@ -5808,6 +5829,8 @@ SlashCmdList["CLEVEROID"] = function(msg)
local num = tonumber(val)
if num == 0 or num == 1 then
CleveRoidMacros.realtime = num
-- The unit streams are only worth receiving in event-driven mode.
CleveRoids.ApplyUnitStreamEvents()
CleveRoids.Print("realtime set to " .. num)
else
CleveRoids.Print("Usage: /cleveroid realtime 0 or 1 - Force realtime updates rather than event based updates (Default: 0. 1 = on, increases CPU load.)")
+1 -1
View File
@@ -1180,7 +1180,7 @@ local function ReportAllMacroErrors()
-- Collect body (syntax) errors per macro. Macro names are no longer
-- restricted (slot/index-based identification), so no name checks here.
for i = 1, 36 do
for i = 1, CleveRoids.MAX_MACRO_SLOTS do
local nameOk, name = pcall(GetMacroInfo, i)
if nameOk and name and name ~= "" then
local errors = {}
+18
View File
@@ -66,6 +66,10 @@ function CleveRoids.RegisterExtension(name)
CleveRoids.RegisterEvent(name, eventName, callbackName)
end
extension.RegisterUnitEvent = function(eventName, callbackName, ...)
CleveRoids.RegisterUnitEvent(name, eventName, callbackName, unpack(arg))
end
extension.Hook = function(functionName, callbackName, dontCallOriginal)
CleveRoids.RegisterHook(name, functionName, callbackName, dontCallOriginal)
end
@@ -146,6 +150,20 @@ function CleveRoids.RegisterEvent(extensionName, eventName, callbackName)
extension.internal.frame:RegisterEvent(eventName)
end
-- Registers a callback for a UNIT_* event, filtered to the given unit tokens.
-- The callback then only runs for those units: the client drops every other
-- unit's copy, instead of all of them reaching Lua to be compared away. Use
-- this over RegisterEvent whenever the handler starts by testing arg1.
-- extensionName: The name of the extension trying to register the callback
-- eventName: The UNIT_* event to register
-- callbackName: The name of the callback that gets called when the event fires
-- ...: the unit tokens to accept (e.g. "player", "target")
function CleveRoids.RegisterUnitEvent(extensionName, eventName, callbackName, ...)
local extension = CleveRoids.Extensions[extensionName]
extension.internal.eventHandlers[eventName] = callbackName
extension.internal.frame:RegisterUnitEvent(eventName, unpack(arg))
end
-- Hooks the given function by it's name
-- extensionName: The name of the extension trying to register the callback
-- functionName: The name of the function that'll be hooked
+19 -7
View File
@@ -19,6 +19,15 @@ CleveRoids.mouseOverResolvers = {}
CleveRoids.mouseoverUnit = CleveRoids.mouseoverUnit or nil
CleveRoids.mouseOverUnit = nil
-- Every macro slot the client can hold: 18 account-wide (1-18) followed by 18
-- character-specific (19-36). This is the index space GetMacroInfo and
-- C_Macro.SetMacroDisplay address, and it is fixed -- GetNumMacros() returns how
-- many of each tab are *used*, which cannot be summed into a range, because the
-- character block starts at 19 no matter how few account macros exist. Blizzard's
-- own MAX_MACROS is no help either: it lives in the load-on-demand Blizzard_MacroUI
-- and is nil until the player opens the macro window.
CleveRoids.MAX_MACRO_SLOTS = 36
-- Environment flags
CleveRoids.hasSuperwow = SetAutoloot and true or false
CleveRoids.hasTurtle = (type(_G.TURTLE_WOW_VERSION) ~= "nil")
@@ -29,14 +38,17 @@ CleveRoids.supported = CleveRoids.hasTurtle
-- tooltip, cooldown sweep, range and usable state all come from the client -- including
-- the drag cursor and the macro window grid, which Lua cannot reach.
--
-- Feature-detect rather than version-check: the API is unreleased, so
-- CLASSIC_API_VERSION reports the dev sentinel. ClassicAPI stands down from macro
-- display entirely when it sees this addon loaded; ClassicAPIMacroDisplay is what
-- tells it we drive it instead. A fork that leaves the flag unset keeps the old
-- behavior -- both must never drive the same buttons.
CleveRoids.useClassicAPIDisplay =
-- ClassicAPI stands down from macro display entirely when it sees this addon loaded;
-- ClassicAPIMacroDisplay is what tells it we drive it instead, and ReleaseDisplays
-- clears it to hand every macro back. A fork that leaves the flag unset keeps the old
-- behavior -- both must never drive the same buttons. It doubles as the internal
-- "may we call C_Macro.SetMacroDisplay" guard, so the two can never disagree.
--
-- Feature-detect rather than version-check: SetMacroDisplay ships in ClassicAPI
-- v1.15.0, this addon's minimum, so a nil here means the client mod is missing
-- outright -- the case Core.lua's requirement check warns about but keeps running.
CleveRoids.ClassicAPIMacroDisplay =
(type(C_Macro) == "table" and C_Macro.SetMacroDisplay ~= nil) and true or false
CleveRoids.ClassicAPIMacroDisplay = CleveRoids.useClassicAPIDisplay
CleveRoids.ParsedMsg = {}
CleveRoids.ExpandedGroups = {}
+1 -11
View File
@@ -1096,17 +1096,7 @@ function CleveRoids.ValidateAllMacros()
local results = {}
local totalErrors = 0
-- Account-wide macros are indexed from 1 up to GetNumMacros().
-- Character-specific macros occupy the slots immediately following the account-wide ones.
-- In Classic clients, the macro UI has 18 General (Account) slots and 18 Character-Specific slots.
local numAccountMacros = GetNumMacros()
-- The WoW API GetMacroInfo(index) supports indexing up to 36 (1-18 for General, 19-36 for Character)
-- in Classic clients, even though the total is GetNumMacros() + GetNumCharacterMacros() in Retail.
-- To ensure we check all 36 possible slots:
local totalSlots = 36
for i = 1, totalSlots do
for i = 1, CleveRoids.MAX_MACRO_SLOTS do
local nameSuccess, name = pcall(GetMacroInfo, i)
-- Check if GetMacroInfo returned a name (i.e., the slot is used)
+1 -1
View File
@@ -10,7 +10,7 @@ Enhanced macro addon for World of Warcraft 1.12.1 (Vanilla/Turtle WoW) with dyna
|-----|:--------:|---------|
| [Nampower](https://github.com/brues-code/nampower/releases) (v3.0.0+) | ✅ | Spell queueing, DBC data, auto-attack events |
| [UnitXP_SP3](https://codeberg.org/konaka/UnitXP_SP3/releases) | ✅ | Distance checks, `[multiscan]` enemy scanning |
| [ClassicAPI](https://github.com/brues-code/ClassicAPI/releases) | ✅ | Modern `C_*` API: dispel-type conditionals (`[magic]`, `[curse]`, …), `[moving]` speed |
| [ClassicAPI](https://github.com/brues-code/ClassicAPI/releases) (v1.15.0+) | ✅ | Modern `C_*` API: dispel-type conditionals (`[magic]`, `[curse]`, …), `[moving]` speed, unit-filtered events |
## Installation
+2 -2
View File
@@ -4115,7 +4115,7 @@ end)
local ev = CreateFrame("Frame", "CleveRoidsLibDebuffFrame", UIParent)
ev:RegisterEvent("PLAYER_TARGET_CHANGED")
ev:RegisterEvent("UNIT_AURA")
ev:RegisterUnitEvent("UNIT_AURA", "target")
ev:RegisterEvent("ADDON_LOADED") -- For pfUI integration initialization
ev:RegisterEvent("ZONE_CHANGED_NEW_AREA") -- Clear known enemy GUIDs on zone change
@@ -4214,7 +4214,7 @@ ev:SetScript("OnEvent", function()
end
SeedUnit("target")
elseif event == "UNIT_AURA" and arg1 == "target" then
elseif event == "UNIT_AURA" then
SeedUnit("target")
elseif event == "UNIT_CASTEVENT" then