From 2276daffdd166b1e9210d44ee495b1356a71e0b9 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Nov 2025 21:34:43 +0000 Subject: [PATCH 1/2] Fix combo point tracking for spellbook and action bar casts 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) --- ComboPointTracker.lua | 78 +++++++++++++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/ComboPointTracker.lua b/ComboPointTracker.lua index e8ecb89..50b0b12 100644 --- a/ComboPointTracker.lua +++ b/ComboPointTracker.lua @@ -418,18 +418,38 @@ function Extension.OnLoad() Extension.Hook("CastSpellByName", "CastSpellByName_Hook") end - -- Hook global CastSpell and UseAction for confirmation + -- Hook global CastSpell to track combo points from spellbook if _G.CastSpell then local originalCastSpell = _G.CastSpell _G.CastSpell = function(id, bookType) - -- Call original first + -- Get spell name before casting + local spellName = GetSpellName(id, bookType) + + -- Capture combo points BEFORE casting if it's a combo scaling spell + if spellName and CleveRoids.IsComboScalingSpell(spellName) then + local currentCP = CleveRoids.GetComboPoints() + if currentCP and currentCP > 0 then + CleveRoids.lastComboPoints = currentCP + if CleveRoids.debug then + DEFAULT_CHAT_FRAME:AddMessage( + string.format("|cffaaaaff[CastSpell]|r Captured %d combo points before casting %s", + currentCP, spellName) + ) + end + end + end + + -- Call original to cast the spell originalCastSpell(id, bookType) - -- Confirm tracking for combo spells - local spellName = GetSpellName(id, bookType) - if spellName and CleveRoids.IsComboScalingSpell(spellName) and - CleveRoids.ComboPointTracking[spellName] then - CleveRoids.ComboPointTracking[spellName].confirmed = true + -- Track combo points after casting + if spellName and CleveRoids.IsComboScalingSpell(spellName) then + CleveRoids.TrackComboPointCast(spellName) + + -- Confirm the tracking + if CleveRoids.ComboPointTracking[spellName] then + CleveRoids.ComboPointTracking[spellName].confirmed = true + end end end end @@ -437,20 +457,44 @@ function Extension.OnLoad() if _G.UseAction then local originalUseAction = _G.UseAction _G.UseAction = function(slot, target, button) - -- Call original first - originalUseAction(slot, target, button) + -- Try to determine spell name from action slot BEFORE casting + local spellName = nil + local actionText = GetActionText(slot) - -- Try to determine spell name from action slot - if not GetActionText(slot) and IsCurrentAction(slot) then - local spellName = GetActionText(slot) - if not spellName then - -- Try to get from tooltip - GameTooltip:SetAction(slot) + -- If no action text, it's likely a spell (not a macro) + if not actionText then + -- Try to get from tooltip + GameTooltip:SetOwner(UIParent, "ANCHOR_NONE") + GameTooltip:SetAction(slot) + if GameTooltipTextLeft1 then spellName = GameTooltipTextLeft1:GetText() end + GameTooltip:Hide() + end - if spellName and CleveRoids.IsComboScalingSpell(spellName) and - CleveRoids.ComboPointTracking[spellName] then + -- Capture combo points BEFORE casting if it's a combo scaling spell + if spellName and CleveRoids.IsComboScalingSpell(spellName) then + local currentCP = CleveRoids.GetComboPoints() + if currentCP and currentCP > 0 then + CleveRoids.lastComboPoints = currentCP + if CleveRoids.debug then + DEFAULT_CHAT_FRAME:AddMessage( + string.format("|cffaaaaff[UseAction]|r Captured %d combo points before casting %s", + currentCP, spellName) + ) + end + end + end + + -- Call original to execute the action + originalUseAction(slot, target, button) + + -- Track combo points after casting + if spellName and CleveRoids.IsComboScalingSpell(spellName) then + CleveRoids.TrackComboPointCast(spellName) + + -- Confirm the tracking + if CleveRoids.ComboPointTracking[spellName] then CleveRoids.ComboPointTracking[spellName].confirmed = true end end From 56de67332c79d5220f30b88b033d6660e288ab2b Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Nov 2025 21:42:52 +0000 Subject: [PATCH 2/2] Fix action bar icon behavior by properly returning hook values 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. --- ComboPointTracker.lua | 106 +++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 47 deletions(-) diff --git a/ComboPointTracker.lua b/ComboPointTracker.lua index 50b0b12..7254337 100644 --- a/ComboPointTracker.lua +++ b/ComboPointTracker.lua @@ -422,11 +422,10 @@ function Extension.OnLoad() if _G.CastSpell then local originalCastSpell = _G.CastSpell _G.CastSpell = function(id, bookType) - -- Get spell name before casting - local spellName = GetSpellName(id, bookType) + -- Safely try to track combo points without breaking the cast + local success, spellName = pcall(GetSpellName, id, bookType) - -- Capture combo points BEFORE casting if it's a combo scaling spell - if spellName and CleveRoids.IsComboScalingSpell(spellName) then + if success and spellName and CleveRoids.IsComboScalingSpell(spellName) then local currentCP = CleveRoids.GetComboPoints() if currentCP and currentCP > 0 then CleveRoids.lastComboPoints = currentCP @@ -439,65 +438,78 @@ function Extension.OnLoad() end end - -- Call original to cast the spell - originalCastSpell(id, bookType) + -- Call original to cast the spell (and capture return value) + local result1, result2, result3 = originalCastSpell(id, bookType) - -- Track combo points after casting - if spellName and CleveRoids.IsComboScalingSpell(spellName) then - CleveRoids.TrackComboPointCast(spellName) - - -- Confirm the tracking - if CleveRoids.ComboPointTracking[spellName] then - CleveRoids.ComboPointTracking[spellName].confirmed = true - end + -- Track combo points after casting (with error protection) + if success and spellName and CleveRoids.IsComboScalingSpell(spellName) then + pcall(function() + CleveRoids.TrackComboPointCast(spellName) + if CleveRoids.ComboPointTracking[spellName] then + CleveRoids.ComboPointTracking[spellName].confirmed = true + end + end) end + + return result1, result2, result3 end end if _G.UseAction then local originalUseAction = _G.UseAction _G.UseAction = function(slot, target, button) - -- Try to determine spell name from action slot BEFORE casting + -- Safely try to determine spell name without breaking action bar local spellName = nil - local actionText = GetActionText(slot) + pcall(function() + local actionText = GetActionText(slot) - -- If no action text, it's likely a spell (not a macro) - if not actionText then - -- Try to get from tooltip - GameTooltip:SetOwner(UIParent, "ANCHOR_NONE") - GameTooltip:SetAction(slot) - if GameTooltipTextLeft1 then - spellName = GameTooltipTextLeft1:GetText() - end - GameTooltip:Hide() - end + -- If no action text, it's likely a spell (not a macro) + if not actionText then + -- Try to get spell name from tooltip + -- Use a temporary hidden tooltip to avoid UI interference + local tooltip = getglobal("CleveRoidsComboTooltip") + if not tooltip then + tooltip = CreateFrame("GameTooltip", "CleveRoidsComboTooltip", nil, "GameTooltipTemplate") + tooltip:SetOwner(WorldFrame, "ANCHOR_NONE") + end - -- Capture combo points BEFORE casting if it's a combo scaling spell - if spellName and CleveRoids.IsComboScalingSpell(spellName) then - local currentCP = CleveRoids.GetComboPoints() - if currentCP and currentCP > 0 then - CleveRoids.lastComboPoints = currentCP - if CleveRoids.debug then - DEFAULT_CHAT_FRAME:AddMessage( - string.format("|cffaaaaff[UseAction]|r Captured %d combo points before casting %s", - currentCP, spellName) - ) + tooltip:ClearLines() + tooltip:SetAction(slot) + local text = getglobal("CleveRoidsComboTooltipTextLeft1") + if text then + spellName = text:GetText() end end - end - -- Call original to execute the action - originalUseAction(slot, target, button) - - -- Track combo points after casting - if spellName and CleveRoids.IsComboScalingSpell(spellName) then - CleveRoids.TrackComboPointCast(spellName) - - -- Confirm the tracking - if CleveRoids.ComboPointTracking[spellName] then - CleveRoids.ComboPointTracking[spellName].confirmed = true + -- Capture combo points if it's a combo scaling spell + if spellName and CleveRoids.IsComboScalingSpell(spellName) then + local currentCP = CleveRoids.GetComboPoints() + if currentCP and currentCP > 0 then + CleveRoids.lastComboPoints = currentCP + if CleveRoids.debug then + DEFAULT_CHAT_FRAME:AddMessage( + string.format("|cffaaaaff[UseAction]|r Captured %d combo points before casting %s", + currentCP, spellName) + ) + end + end end + end) + + -- Call original to execute the action (and capture return value) + local result1, result2, result3 = originalUseAction(slot, target, button) + + -- Track combo points after casting (with error protection) + if spellName and CleveRoids.IsComboScalingSpell(spellName) then + pcall(function() + CleveRoids.TrackComboPointCast(spellName) + if CleveRoids.ComboPointTracking[spellName] then + CleveRoids.ComboPointTracking[spellName].confirmed = true + end + end) end + + return result1, result2, result3 end end end