The CastSpell and UseAction hooks were doing too much work (tooltip
manipulation, spell name detection, combo point tracking) which was
interfering with WoW's action bar icon updates.
Solution:
Made both hooks minimal pass-throughs that just call and return the
original function. Combo point tracking is now handled entirely by:
1. UpdateComboPoints() - runs continuously via OnUpdate, captures
combo points as they're generated and stores in lastComboPoints
2. SPELLCAST_START event - fires for ALL spell casts regardless of
source (spellbook, action bar, macro, keybind) and calls
TrackComboPointCast()
3. TrackComboPointCast() - uses GetComboPoints() first, falls back
to lastComboPoints if points are already consumed
This approach works for all casting methods:
- Spellbook clicks
- Action bar clicks
- Keybinds
- Macros with /cast
- Macros with conditionals
And doesn't interfere with action bar icon updates (GCD, range
coloring, queue glowing, etc).
Previously, action button state functions (IsCurrentAction, IsActionInRange,
IsUsableAction, ActionHasRange, GetActionCount, IsConsumableAction) only
checked the active action, not the tooltip action. This caused issues when
using #showtooltip without conditionals, or when no conditionals matched:
- No glow on buttons even when the ability was queued/active
- Incorrect range/usability indicators
- Missing item counts for consumables
Now all these functions use the same priority as GetActionTexture and
GetActionCooldown: check the active action first, then fall back to the
tooltip action. This ensures button states match the displayed icon.
Fixes issues with abilities like Cleave and Heroic Strike not showing glow
when queued, and ensures all action button visuals are consistent.
When #showtooltip had an argument with conditionals (e.g., #showtooltip [stance:1] Fireball),
the code was trying to find a spell named "[stance:1] Fireball" which doesn't exist.
This resulted in no texture being found for the tooltip action, causing incorrect icons.
Now the code parses the argument first using GetParsedMsg() to extract just the spell name
before creating the tooltip action info. This allows it to properly find the spell in the
spellbook and retrieve its correct texture/icon.
The CastSpell and UseAction hooks were breaking action bar icon
updates (GCD display, range coloring, queue glowing) because they
weren't returning the values from the original functions.
Issues fixed:
1. Return values: Both hooks now capture and return all return values
from the original functions, ensuring the game receives the expected
data for action bar updates
2. Error protection: Wrapped all tracking code in pcall() to prevent
any errors from breaking the normal spell cast flow
3. Tooltip interference: UseAction now uses a separate hidden tooltip
(CleveRoidsComboTooltip) instead of manipulating GameTooltip,
avoiding interference with the main UI tooltip
Changes to CastSpell hook:
- Use pcall for GetSpellName to safely handle errors
- Capture return values: result1, result2, result3
- Wrap tracking code in pcall for error protection
- Return all captured values
Changes to UseAction hook:
- Wrap entire spell name detection in pcall
- Create separate hidden tooltip for combo point spells
- Capture return values from original UseAction
- Wrap tracking code in pcall for error protection
- Return all captured values
This ensures action bar icons work correctly while still tracking
combo points for finisher spells.
The CastSpell and UseAction hooks were only confirming existing
tracking, not actually creating it. They also called the original
functions before capturing combo points, so the points were already
consumed.
Changes to CastSpell hook (spellbook casts):
- Get spell name BEFORE calling original CastSpell
- Capture combo points to lastComboPoints if spell is combo scaling
- Call original to cast the spell
- Call TrackComboPointCast to track the combo points used
- Confirm the tracking
Changes to UseAction hook (action bar casts):
- Get spell name from action slot BEFORE calling original UseAction
- Fixed tooltip logic (was checking "not GetActionText" incorrectly)
- Capture combo points to lastComboPoints if spell is combo scaling
- Call original to execute the action
- Call TrackComboPointCast to track the combo points used
- Confirm the tracking
Both hooks now capture combo points at the exact moment before the
spell is cast, ensuring they're available in lastComboPoints for
TrackComboPointCast to use as a fallback.
This fixes tracking for:
- Clicking spells from spellbook (CastSpell)
- Clicking spells on action bars (UseAction)
- Keybinding spells on action bars (UseAction)
Previously, combo point tracking attempted to capture combo points at
cast time in the hooks, but this approach failed because hooks run
after the spell has already consumed the combo points.
The solution is to rely entirely on the existing UpdateComboPoints()
system, which runs continuously via OnUpdate and PLAYER_COMBO_POINTS
events. This system tracks combo points AS THEY ARE GENERATED on the
target, storing them in lastComboPoints before any spell can consume
them.
Changes:
- Removed manual combo point capture logic from all hooks
(CastSpellByName_Hook, CastSpell_Hook, DoCast, OnSpellcastStart)
- TrackComboPointCast() now relies solely on the continuous tracking
system, falling back to lastComboPoints when GetComboPoints()
returns 0 (because points were already consumed)
- UpdateComboPoints() continues to run on every frame, capturing
combo points as they appear on the target
This ensures that all casts of combo point finisher spells (Rip,
Rupture, Kidney Shot) are tracked correctly with the actual number
of combo points used, regardless of whether they're cast through
conditionals (e.g., /cast [combo:>0]Rip) or directly (e.g., /cast Rip).
Previously, combo point tracking only worked reliably when spells were
cast with conditionals (e.g., /cast [combo:>0]Rip) but not for direct
casts (e.g., /cast Rip). This was because combo points are consumed
immediately when a spell is cast, so by the time the tracking code ran,
GetComboPoints() would return 0.
Changes:
- Updated TrackComboPointCast() to fall back to lastComboPoints when
GetComboPoints() returns 0, ensuring the correct combo point count
is used even if the points have already been consumed
- Modified all spell cast hooks (CastSpellByName_Hook, CastSpell_Hook,
DoCast integration, OnSpellcastStart) to capture the current combo
points into lastComboPoints BEFORE the spell is cast
- Added debug messages to track when combo points are captured and
when fallback values are used
This ensures that all casts of combo point finisher spells (Rip,
Rupture, Kidney Shot) are tracked correctly with the actual number
of combo points used, regardless of whether they're cast through
conditionals or directly.
The GetComboPoints() function was using TBC/WotLK syntax with two
parameters ("player", "target"), which is incorrect for Vanilla WoW 1.12.
In Vanilla WoW, GetComboPoints() takes no parameters and returns the
combo points on the current target.
This fixes the issue where macros were not tracking combo points correctly,
especially for users without pfui or other addon dependencies.
Fixes combo point tracking for Rupture, Rip, and Kidney Shot spells.
- Added lib:UnitBuff(unit, index, filterCaster) to query buff data by slot
- Added lib:FindPlayerBuff(unit, spellID) to find player-cast buffs by spell ID
- Both functions return duration, timeleft, and caster information
- Mirrors the debuff tracking API (UnitDebuff/FindPlayerDebuff)
- Enables tracking buff ownership and timeleft for future projects
Updated GetActionTexture to fall back to the macro's icon in all code paths:
- When no action is active and no explicit tooltip (line 2444)
- When inventory slot is empty (line 2469)
- Final fallback for all other cases (line 2494)
This ensures the macro icon is always shown instead of the question mark
when no action/spell texture is available. The question mark should only
appear as an absolute last resort if GetMacroInfo fails.
Changes:
- Split lib.durations into lib.personalDebuffs and lib.sharedDebuffs
- Removed combo-scaling spells (Rupture, Rip, Kidney Shot) from static tables
since they are handled dynamically by ComboPointTracker
- Added lib:IsPersonalDebuff() helper to distinguish debuff types
- Updated ValidateUnitDebuff to auto-detect personal vs shared debuffs
- Personal debuffs (DoTs, poisons, most CC) now auto-filter to player by default
- Shared debuffs (Sunder, Faerie Fire, Hunter's Mark) remain unfiltered
- Maintained lib.durations for backwards compatibility
This prevents false positives when checking personal debuffs like Rupture
in multi-player scenarios while allowing shared debuffs like Sunder Armor
to work correctly.
- ValidateUnitDebuff now supports args.mine to filter player-cast debuffs
- Fixes issue where personal debuffs (Rupture, Rip) from other players
were incorrectly matched when checking timeleft
- Shared stacking debuffs (Sunder Armor) continue to work as expected
- Uses new lib:UnitDebuff filterCaster parameter internally
- Modified lib:UnitDebuff() to accept optional filterCaster parameter
- Added lib:FindPlayerDebuff() to search for player debuffs by spell ID
- Ensures debuffs in buff slots can be properly identified by owner
- Prevents false positives from other players' debuffs with same spell ID