Commit Graph

37 Commits

Author SHA1 Message Date
Brues 7bbb8df010 remove pre pfUI 7.6 stuff 2026-09-11 00:27:05 -05:00
Brues 96dbe9aca8 Fail @focus clauses quietly when no focus is set
`[@focus,...] X` with no focus set printed "Invalid target" before falling
through to the next clause, which the new `[@mouseover][@focus][] X` idiom
turned into a message on every press. The noise came from a pre-ClassicAPI
name-based fallback in DoWithConditionals: with no native focus token,
TryTargetFocus resolved UnitName('focus') to nil and could never succeed,
so the branch only ever reached the error print. GetFocusUnitId's own
contract already says @focus should fall through silently.

Both evaluators now fail the clause quietly when GetFocusUnitId is nil,
the same way @mouseover does, so display and execution agree (TestAction
previously evaluated against "target" in that case). GetFocusName,
TryTargetFocus and pfUI's FocusNameHook were only reachable through that
path and are removed.
2026-09-10 17:35:49 -05:00
Brues d93d97a469 Delete the write-only buff tracking tables and the overflow fallback
Following the aura data source to ClassicAPI exposed a chain of machinery that
nothing consumed any more.

ValidateAura's non-player overflow fallback is gone. It existed because a buff
can occupy server slots 33-48 with no client slot, so it read presence and
duration out of AllCasterAuraTracking behind a UnitDebuff slot scan that stopped
[buff:Name] matching a debuff. ClassicAPI settles this at the source: its
HELPFUL/HARMFUL filters select on each aura's real polarity flag rather than the
slot range it happens to sit in, so per docs/API.md "a debuff parked in a buff
slot still reads harmful" -- and an overflowed buff still reads helpful. The
ClassicAPI resolution already covers the case, and classifies it more accurately
than the slot-range guard did.

That removed the last caller of FindAllCasterAuraByName (67 lines), and the
player-side allBuffAuras timing lookup went with it: for the player, C_Spell...
C_UnitAuras reads expirationTime out of the engine's own player-buff table, so it
is the more authoritative source rather than a fallback.

With no readers left, three tables turn out to be pure overhead -- populated on
every buff aura event, swept periodically, cleared on removal and death, and
never read for aura state:
  - lib.allBuffAuras   [guid][name][caster] = {startTime, duration, rank}
  - lib.ownBuffCasts   [guid][name]         = {startTime, duration, spellId, ...}
  - lib.pendingBuffCasts [guid][spellId]    = {casterGuid, duration, name, time}
pendingBuffCasts only existed to correlate AURA_CAST_ON_OTHER with
BUFF_ADDED_OTHER so the other two could be filled, so removing them emptied the
BUFF_ADDED_OTHER handler entirely. That event is no longer registered, and pfUI
compat no longer unregisters an event we never ask for.

Fixes a regression from the previous commit in this series: removing the
allBuffAuras/ownBuffCasts blocks from BUFF_REMOVED_SELF and BUFF_REMOVED_OTHER
also deleted their `local spellName = C_Spell.GetSpellName(spellId)`, leaving
later `if spellName` guards reading a nil global. The OverflowBuffsByName and
AllCasterAuraTracking prunes in those branches had silently stopped running.
Both declarations are restored.

AllCasterAuraTracking itself stays: OverflowBuffFrame and the aura-tracking
writers still use it.
2026-09-10 14:40:16 -05:00
Brues daaab2fd11 Retire the hasPfUI76 flag and the pfUI 7.6 branches it gated
Assume a modern pfUI, and drop the version-tiered branching entirely: 31 call
sites across five files, plus the flag and its detector.

Note which side was actually dead. HasPfUI76() required four things -- pfUI
version >= 7.6, Nampower >= 2.40, pfUI.libdebuff_objects_guid, and
pfUI.libdebuff_casts. The last one does not exist: pfUI exports 28 libdebuff_*
tables and libdebuff_casts is not among them (libdebuff_recent_casts is a
dedup table keyed [targetGuid][spellName][casterGuid], a different shape). So
the detector returned false at any version, and it was the hasPfUI76-TRUE
branches that never ran, not the fallbacks. Removing those is behaviour-
preserving; keeping SCRM as the owner of castTracking is what the code has
always actually done.

Removed accordingly:
- lib:HasPfUI76(), both flag declarations, and the block that would have aliased
  castTracking to pfUI.libdebuff_casts and re-pointed lib.objects/iconCache.
- HookPfUILibdebuff's "7.6 handles durations internally" early return, so the
  GetDuration/AddEffect hooks below it are visibly the live path again.
- The SPELL_START_OTHER / SPELL_FAILED_OTHER unregister arm, the pfUI branch of
  GetAuraTrackingData, the pfUI76 arm of the libdebuff zone/death cleanup, the
  pfUI backing table in the /cleveroid aura dump, and two status-string suffixes.
- SyncComboDurationToPfUI (77 lines) with its two call sites: it returned
  immediately whenever hasPfUI76, and is inert once the tier split is gone.

Unconditionalised the paths that were gated on `not hasPfUI76`: the castTracking
populate/clear/sweep, InitPfUIIntegration on login, and ten libdebuff duration
lookups.

Verified no hasPfUI76 reference remains, and that per-file block balance is
unchanged from HEAD.
2026-09-10 14:40:16 -05:00
Brues f296425c94 Cut per-call allocations in the event and publish paths; merge SPELL_CAST_EVENT
Chasing high memory churn (~188 kb/s with pfUI). Four allocation sources and one
correctness bug found along the way.

The recurring cause: in 1.12's Lua 5.0 a function declared `function(...)` builds
a fresh `arg` table on every call. Three handlers were declared that way and none
of them read the vararg.

- Compatibility/pfUI.lua: the registered action handler. This was the dominant
  one. UpdateAllManagedCooldowns fans ACTIONBAR_UPDATE_COOLDOWN across every
  managed slot (up to 120) on each SPELL_UPDATE_COOLDOWN, so every GCD and
  cooldown tick allocated ~120 tables that the handler then discarded, because
  its whole body only ever applied to ACTIONBAR_SLOT_CHANGED. Dropped the vararg
  and added an early return before any work. Bongos' and UltimaMacros' handlers
  were already vararg-free.

- Core.lua SendEventForAction: dropped the vararg (every caller passes exactly
  one extra value) and replaced the inline "arg" .. i concatenations -- 30 per
  call across three loops -- with a prebuilt name table. The eight-branch arg.n
  fan-out collapses to one loop.

- Core.lua Frame OnEvent dispatcher: dropped the vararg. It fires for all ~48
  registered events, including the UNIT_HEALTH / UNIT_AURA / UNIT_*_GUID streams.

PublishDisplay now skips no-op publishes. Publishing is not free: the client
repaints holders of the macro through its own notifier, which returns as
ACTIONBAR_SLOT_CHANGED -> ClearAction + IndexActionSlot -> TestForActiveAction ->
publish. Publishing an unchanged value therefore tore down and re-resolved slots
for nothing and fed itself, since GetAction and IndexActionSlot both publish on
paths that fire constantly. This was the C_Macro.SetMacroDisplay regression.

Also merges the two same-named SPELL_CAST_EVENT handlers. Lua assigns in file
order, so the later definition silently replaced the earlier one and its half
never ran: channel-start detection, spell_tracking cleanup, and cast-sequence
advancement. AdvanceSequence has only two callers and the other is inside
UNIT_CASTEVENT, which is registered only under SuperWoW -- so /castsequence had
no way to advance on a successful cast for Nampower-only users.
2026-09-10 14:40:16 -05:00
Brues 2ce4d11698 Use ClassicAPI EventUtil for addon-load/login extension wiring
Replace hand-rolled ADDON_LOADED/PLAYER_LOGIN handlers with
EventUtil.ContinueOnAddOnLoaded / ContinueOnPlayerLogin, which fire
immediately if the event already happened -- removing the "we loaded before
the target addon and missed its ADDON_LOADED" workarounds.

- pfUI compat: ContinueOnAddOnLoaded("pfUI") + ContinueOnPlayerLogin; drops
  the missed-event fallback (login path still re-runs SetupCompatibility).
- MacroErrorUI / MacroLengthWarn: ContinueOnAddOnLoaded("Blizzard_MacroUI"),
  folding their manual "already loaded" checks.
- 9 Mouseover extensions (ag_UnitFrames, CT_RaidAssist, CT_UnitFrames,
  DiscordUnitFrames, Grid, NotGrid, Cursive, sRaidFrames, PerfectRaid):
  ContinueOnAddOnLoaded("<AddonName>", OnLoad). Since immediate-fire passes no
  event args, the old `arg1 == "X"` checks are replaced by the addon-name gate
  (global guards kept where present); also removes the buggy
  UnregisterEvent("ADDON_LOADED", "Onload") no-ops that never fired.

Addon names match file names; drops support for renamed folders (e.g. -master).
2026-07-26 14:53:34 -05:00
Brues 22633aa16c Replace GetSpellRecField name/rank reads with C_Spell equivalents
Swap 166 call sites from GetSpellRecField(id, "name") to
C_Spell.GetSpellName(id) and GetSpellRecField(id, "rank") to
C_Spell.GetSpellSubtext(id) across Core, Conditionals, Utility,
ComboPointTracker, CursiveCustomSpells, pfUI, OverflowBuffFrame, and
Generic. Guard forms and the _GetSpellRecField alias calls collapse to the
direct C_Spell call.

GetSpellRecField stays for fields with no C_Spell equivalent (school,
spellIconID, mechanic, effectMechanic, effectApplyAuraName, stackAmount,
rangeIndex) and inside the NampowerAPI wrapper layer.
2026-07-26 14:07:31 -05:00
Brues f926ac5521 Replace custom/UnitXP timers with ClassicAPI C_Timer
- ScheduleTimer now wraps C_Timer.After, removing the dedicated timer
  frame + per-frame OnUpdate loop + timers queue.
- Aura-tracking cleanup -> C_Timer.NewTicker(5) (_auraCleanupTicker);
  drop the UnitXP arm, the named global CleveRoids_AuraTrackingCleanupTimer,
  and the inline "not hasUnitXP" fallback in OnAuraCastOther.
- Libdebuff cleanup -> C_Timer.NewTicker(30) (_cleanupTicker); drop the
  UnitXP arm and CleveRoids_LibDebuffCleanupTimer.
- Shutdown cancels the tickers instead of UnitXP timer disarm.

Cleanup now always runs (was gated on hasUnitXP) and no longer depends
on UnitXP threaded timers or named global callbacks. Tickers self-guard
on isShuttingDown and are cancelled on shutdown.
2026-06-21 01:59:54 -05:00
Brues 73e8938d76 Use ClassicAPI for action-bar mapping, spell IDs, and dynamic pfUI icons
GetActionInfo:
- Add ClassicAPI.GetActionInfo wrapper; rewrite GetActionButtonInfo
  (Generic.lua) to use it and resolve names via GetSpellRecField /
  GetItem / GetMacroInfo, replacing the per-slot GameTooltip scan +
  texture heuristic. Powers reactive-ability slot detection.
- Delete the dead SuperWoW-GetActionText copy of GetActionButtonInfo.

Spell IDs in the index:
- IndexSpells now uses ClassicAPI GetSpellInfo(slot, bookType), whose
  10th return is the spellID, so every Spells entry carries .id (one
  call also replaces GetSpellName + GetSpellTexture).

Dynamic pfUI action-button icons (pairs with the pfUI fork change):
- GameTooltip.SetAction hook renders spells via ClassicAPI
  SetSpellByID(spell.id) instead of SetSpell(spellSlot, bookType) +
  manual rank text. Items stay location-based (instance data).
- Drop the redundant GetActionSpellSlot -> GetSpellCooldown cooldown
  shim in the pfUI handler; pfUI now routes through the hooked
  GetActionCooldown when it defers macro scanning to us.
2026-06-21 00:11:46 -05:00
Jrc13245 e51c4f7136 fix pfui libdebuff and extra overflowframe tracking 2026-04-02 15:02:50 -04:00
Jrc13245 6ab3f7a157 fix debuff bug, reformat pfui hooks, add rangedclip and norangedclip conditionals 2026-03-13 08:25:23 -04:00
Jrc13245 efdcde3eca performance updates, meleerange conditional checks if unit is alive 2026-03-11 19:57:33 -04:00
Jrc13245 9c05a6fc6a fix pfui loading objects without superwow 2026-03-03 11:10:55 -05:00
Jrc13245 b56beef4b2 remove more superwow only functions 2026-03-02 09:01:34 -05:00
Jrc13245 2f0f000733 no superwow required, update for nampower 3 2026-03-01 09:33:41 -05:00
Jrc13245 37afbd047c update pfui compatibility 2026-02-16 21:32:37 -05:00
Jrc13245 c2c8af7d2d pfui 7_6 update compatibility and reformat readme 2026-02-08 17:42:16 -05:00
Jrc13245 fcd68c6efb update for pfui 7_6 updates 2026-02-04 17:36:17 -05:00
Jrc13245 ee2de33001 update nampower support to 2_27_2 and pfUI 7_6+ 2026-02-04 16:23:34 -05:00
Jrc13245 ede836f1b8 fix castsequence and fix possible 132 logout error caused by dlls 2026-01-30 19:19:54 -05:00
Jrc13245 8f1e2166b1 fix false immunities 2026-01-16 09:35:29 -05:00
Jrc13245 c230b1decb fix stopmacro and fix mouseover in other addons 2026-01-15 11:48:01 -05:00
Jrc13245 b942cdb07e update for pfui compatibility 2026-01-10 11:59:46 -05:00
Jrc13245 8d39ae75c2 add error catcher and fix libdebuff accesses 2025-12-26 16:42:58 -05:00
Jrc13245 ce017f5832 fix lower rank spells showing as refreshing higher ranks in pfui. further improve debuff duration handling. 2025-11-30 19:25:19 -05:00
Jrc13245 ff6ec25c06 bleed immunity, fix icons and their tooltips with no available actions, reformat readme 2025-11-27 09:21:41 -05:00
Jrc13245 6a4f7a417c fix revenge reactive and majorly improve pfui compatibility for icons and actionbars 2025-11-26 07:48:12 -05:00
Jrc13245 f6df0b2b5a fix icon issue and fix carnage talent duration refreshers updating visually for pfui 2025-11-19 17:50:30 -05:00
Jrc13245 c5a57af024 Fix combo point tracking and queue glow for instant finishers
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 20:28:22 -05:00
Claude ce8f1dcf7d Fix pfUI AddEffect handling multiple calls
Don't clear the confirmed flag after first use since pfUI may call
AddEffect multiple times for the same spell. Instead, rely on the
time-based expiry (0.5s timeout) to prevent stale tracking data.

This fixes the issue where the second AddEffect call would see
unconfirmed tracking and ignore the correct duration.
2025-11-16 22:46:17 +00:00
Claude aedb2684b5 Add confirmation system to prevent pfUI from using evaluation-only tracking
Problem: Macro conditional evaluations create tracking entries, but
pfUI's AddEffect can fire during these evaluations (before actual cast),
causing it to use incorrect combo point data.

Flow before fix:
1. Macro evaluates [combo:>0] → TrackComboPointCast(0 CP, confirmed=false)
2. Macro evaluates again → TrackComboPointCast(1 CP, confirmed=false)
3. pfUI AddEffect fires → uses tracking (wrong timing!) ✗
4. SPELLCAST_START fires (actual cast)

Flow after fix:
1. Macro evaluates [combo:>0] → TrackComboPointCast(0 CP, confirmed=false)
2. Macro evaluates again → TrackComboPointCast(1 CP, confirmed=false)
3. SPELLCAST_START fires → sets confirmed=true ✓
4. pfUI AddEffect fires → only uses tracking if confirmed=true ✓

Changes:
- Added 'confirmed' field to tracking (default: false)
- SPELLCAST_START sets confirmed=true when spell actually casts
- pfUI AddEffect hook only uses tracking if confirmed=true
- Clear confirmed flag after use to prevent reuse
- Clear on failed/interrupted casts

Debug shows: "Ignoring X tracking (not confirmed - evaluation only)"
when preventing use of evaluation-only data.
2025-11-16 18:51:57 +00:00
Claude c9bd224c2b Fix pfUI AddEffect timing - use name-based tracking instead of ID
CRITICAL TIMING FIX: pfUI's AddEffect fires BEFORE UNIT_CASTEVENT!

Event sequence:
1. CastSpell → Extension hooks → name-based tracking stores 5 CP, 18s ✓
2. pfUI AddPending → GetDuration (base 10s)
3. SPELLCAST_STOP → pfUI AddEffect fires
4. Our AddEffect hook fires (ID tracking doesn't exist yet!) ✗
5. UNIT_CASTEVENT → ID-based tracking created ✓

Solution: Use name-based tracking (available at step 4) instead of
ID-based tracking (not created until step 5).

Changed pfUI AddEffect hook to:
- Use CleveRoids.ComboPointTracking[effect] (name-based)
- Check cast_time < 0.5s to ensure freshness
- This data exists when pfUI calls AddEffect

Now shows: "[pfUI AddEffect Hook] Overriding Rip duration to 18s"
Instead of: "[pfUI AddEffect Hook] Overriding Rip duration to 10s"
2025-11-16 18:41:39 +00:00
Claude 3e669a7b7a Fix pfUI integration - use unit names and spell names, not GUIDs/IDs
CRITICAL FIX: pfUI's libdebuff uses completely different data structures:
- Uses unit NAME (not GUID)
- Uses unit LEVEL as a key
- Uses spell NAME (effect, not ID)
- Storage: pflib.objects[unitName][unitLevel][effectName]

Fixed SyncComboDurationToPfUI:
- Convert GUID to unit name (check target, fallback to guidToName map)
- Get unit level from target or default to 0
- Convert spell ID to spell name using SpellInfo()
- Remove rank from spell name to match pfUI's format
- Search both specific level and level 0 (pfUI's fallback)

Fixed AddEffect hook:
- Updated parameters to match pfUI signature: (unit, unitlevel, effect, duration, caster)
- Check spell by name instead of ID
- Map spell name back to ID to find tracking data

This ensures pfUI's cooldown displays show correct combo durations.
2025-11-16 18:20:51 +00:00
Claude d6b4ae3d97 Add direct pfUI duration synchronization for combo spells
After analyzing pfUI's cooldown module, we need to directly sync
combo durations to pfUI's libdebuff.objects storage:

- Added SyncComboDurationToPfUI function to force-update pfUI's
  stored debuff duration after tracking combo spells
- Called from UNIT_CASTEVENT handler after AddEffect
- This ensures pfUI's cooldown display shows the correct combo
  duration (e.g., 28s for 5 CP Rip) instead of base 12s

pfUI's cooldown module is just a display layer - it shows durations
from pfUI.api.libdebuff.objects. By directly updating this storage,
we ensure the correct duration is displayed regardless of timing.
2025-11-16 18:18:41 +00:00
Claude 60bf1741ed Add pfUI cooldown integration for combo-aware durations
Hook into pfUI.api.libdebuff to inject combo-based durations:
- Hook GetDuration: Returns learned combo durations for combo spells
- Hook AddEffect: Injects tracked combo durations when debuffs are applied

This ensures pfUI's cooldown module displays the correct duration
(e.g., 28s for 5 CP Rip instead of base 12s).

Debug messages show when pfUI hooks are triggered in debug mode.
2025-11-16 18:15:33 +00:00
Jrc13245 c65642a129 fix compatibility with pfui macrotweak 2025-11-12 16:33:54 -05:00
Jrc13245 fb359993b2 Initial Commit 2025-08-18 16:15:25 -04:00