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>
This commit is contained in:
Jrc13245
2025-11-17 20:28:22 -05:00
co-authored by Claude
parent 2f90199a26
commit c5a57af024
6 changed files with 222 additions and 11 deletions
+52 -10
View File
@@ -9,8 +9,7 @@ local CleveRoids = _G.CleveRoids or {}
-- Initialize combo point tracking table
CleveRoids.ComboPointTracking = CleveRoids.ComboPointTracking or {}
CleveRoids.spell_tracking = CleveRoids.spell_tracking or {}
CleveRoids.lastComboPoints = CleveRoids.lastComboPoints or 0 -- Track last known CP count
-- Note: CleveRoids.lastComboPoints and CleveRoids.lastComboPointsTime are initialized in Init.lua
-- Initialize SavedVariable for learned combo durations
-- Structure: CleveRoids_ComboDurations[spellID][comboPoints] = duration
@@ -61,6 +60,7 @@ function CleveRoids.UpdateComboPoints()
local current = CleveRoids.GetComboPoints()
if current > 0 then
CleveRoids.lastComboPoints = current
CleveRoids.lastComboPointsTime = GetTime()
end
end
@@ -264,10 +264,16 @@ function CleveRoids.TrackComboPointCastByID(spellID, targetGUID)
-- If combo points are 0, try multiple fallback sources
if comboPoints == 0 then
-- First, try lastComboPoints
-- First, try lastComboPoints (don't reset immediately - let it persist)
if CleveRoids.lastComboPoints > 0 then
comboPoints = CleveRoids.lastComboPoints
CleveRoids.lastComboPoints = 0 -- Reset after using
-- Don't reset here - let it persist for multiple events
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff9900[TrackComboByID]|r Using lastComboPoints: %d for spell ID %d",
comboPoints, spellID)
)
end
else
-- Second, check if name-based tracking has recent data for this spell
local spellName = SpellInfo(spellID)
@@ -316,6 +322,16 @@ function CleveRoids.TrackComboPointCastByID(spellID, targetGUID)
)
end
-- Reset lastComboPoints after successfully using it
if comboPoints > 0 and comboPoints == CleveRoids.lastComboPoints then
CleveRoids.lastComboPoints = 0
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff888888[TrackComboByID]|r Reset lastComboPoints after use")
)
end
end
return duration
end
@@ -409,13 +425,39 @@ function Extension.OnLoad()
CleveRoids.UpdateComboPoints()
end)
-- Hook the spell cast functions if they exist
if CleveRoids.CastSpell then
Extension.Hook("CleveRoids.CastSpell", "CastSpell_Hook")
end
-- Hook CastSpellByName to capture combo points BEFORE the cast
if CastSpellByName then
Extension.Hook("CastSpellByName", "CastSpellByName_Hook")
local originalCastSpellByName = CastSpellByName
CastSpellByName = function(spellName, onSelf)
if spellName and CleveRoids.IsComboScalingSpell(spellName) then
-- Capture current combo points BEFORE the spell cast
local currentCP = CleveRoids.GetComboPoints()
if currentCP and currentCP > 0 then
CleveRoids.lastComboPoints = currentCP
CleveRoids.lastComboPointsTime = GetTime()
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffaaff00[CastSpellByName Hook]|r Captured %d CP before casting %s",
currentCP, spellName)
)
end
end
CleveRoids.TrackComboPointCast(spellName)
-- Confirm the tracking immediately - this only fires on actual casts
if CleveRoids.ComboPointTracking[spellName] then
CleveRoids.ComboPointTracking[spellName].confirmed = true
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff00ff00[Confirmed]|r %s tracking confirmed (CastSpellByName)",
spellName)
)
end
end
end
return originalCastSpellByName(spellName, onSelf)
end
end
-- Hook global CastSpell - minimal hook to avoid breaking action bars
+12
View File
@@ -150,6 +150,13 @@ function Extension.HookPfUILibdebuff()
pflib.AddEffect = function(self, unit, unitlevel, effect, duration, caster)
-- effect is a spell name, not ID
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffcccccc[pfUI AddEffect]|r Called for '%s' on %s, duration=%s",
effect, unit or "unknown", tostring(duration))
)
end
-- Check if this is a combo scaling spell by name
if CleveRoids.IsComboScalingSpell and CleveRoids.IsComboScalingSpell(effect) then
-- Use name-based tracking which is populated BEFORE pfUI's AddEffect
@@ -172,6 +179,11 @@ function Extension.HookPfUILibdebuff()
effect)
)
end
elseif CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff9900[pfUI AddEffect]|r No tracking found for '%s'",
effect)
)
end
end
+73 -1
View File
@@ -43,7 +43,7 @@ SlashCmdList.EQUIP = CleveRoids.DoUse
-- take back supermacro and pfUI /equip and /use
SlashCmdList.SMEQUIP = CleveRoids.DoUse
SlashCmdList.PFEQUIP = CleveRoids.DoUse
SlashCmdList.PFUSE = CleveRoids.DoUse
SlashCmdList.PFUSE = CleveRoids.DoUse
SLASH_EQUIPMH1 = "/equipmh"
SlashCmdList.EQUIPMH = CleveRoids.DoEquipMainhand
@@ -160,6 +160,78 @@ SlashCmdList.CAST = function(msg)
if msg and string.find(msg, "[%[%?!~{]") then
CleveRoids.DoCast(msg)
else
-- Use lastComboPoints which is updated on every OnUpdate tick
-- This is critical for instant-cast finishers where GetComboPoints() returns 0 immediately
local currentCP = CleveRoids.lastComboPoints or 0
-- Also try GetComboPoints as a fallback
if currentCP == 0 and GetComboPoints then
currentCP = GetComboPoints()
end
if currentCP > 0 then
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffaaff00[/cast Hook]|r Using %d CP for %s",
currentCP, msg)
)
end
-- Pre-inject combo duration into pfUI for instant-cast combo finishers
-- Get the spell data to find the proper spell name (handles case-insensitive input)
local spellData = CleveRoids.GetSpell and CleveRoids.GetSpell(msg)
local spellName = spellData and spellData.name or msg
-- If GetSpell didn't find it, capitalize first letter as fallback
if not spellData and spellName then
spellName = string.upper(string.sub(spellName, 1, 1)) .. string.sub(spellName, 2)
end
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffcccccc[/cast Debug]|r input='%s', spellName='%s', GetSpell=%s, IsComboScalingSpell=%s",
msg, spellName or "nil", tostring(spellData ~= nil), tostring(CleveRoids.IsComboScalingSpell ~= nil))
)
end
if CleveRoids.IsComboScalingSpell and CleveRoids.IsComboScalingSpell(spellName) then
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[/cast Debug]|r IS combo scaling spell")
end
local duration = CleveRoids.CalculateComboScaledDuration and
CleveRoids.CalculateComboScaledDuration(spellName, currentCP)
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffcccccc[/cast Debug]|r duration=%s, pfUI=%s, pfUI.api=%s, pfUI.api.libdebuff=%s, debuffs=%s",
tostring(duration), tostring(pfUI ~= nil),
tostring(pfUI and pfUI.api ~= nil),
tostring(pfUI and pfUI.api and pfUI.api.libdebuff ~= nil),
tostring(pfUI and pfUI.api and pfUI.api.libdebuff and pfUI.api.libdebuff.debuffs ~= nil))
)
end
if duration and CleveRoids.ComboPointTracking then
-- Remove rank from spell name for pfUI compatibility
local baseName = string.gsub(spellName, "%s*%(Rank %d+%)", "")
-- Populate name-based tracking BEFORE the spell is cast
-- This allows pfUI's AddEffect hook to find it
CleveRoids.ComboPointTracking[baseName] = {
combo_points = currentCP,
duration = duration,
cast_time = GetTime(),
target = UnitName("target") or "Unknown",
confirmed = true
}
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff00ff[/cast Pre-Tracking]|r Set tracking['%s'] = %ds (%d CP)",
baseName, duration, currentCP)
)
end
end
elseif CleveRoids.debug and currentCP > 0 then
DEFAULT_CHAT_FRAME:AddMessage("|cffff9900[/cast Debug]|r NOT a combo scaling spell")
end
end
CleveRoids.Hooks.CAST_SlashCmd(msg)
end
end
+25
View File
@@ -2415,6 +2415,31 @@ function IsCurrentAction(slot)
if actionToCheck.spell then
local rank = actionToCheck.spell.rank or actionToCheck.spell.highest.rank
name = actionToCheck.spell.name..(rank and ("("..rank..")"))
-- Check if this spell is currently queued or being cast via Nampower
if GetCurrentCastingInfo then
local castId, visId, autoId, casting, channeling, onswing, autoattack = GetCurrentCastingInfo()
-- Get spell ID for comparison
local spellId = actionToCheck.spell.id
if not spellId and GetSpellIdForName then
spellId = GetSpellIdForName(name)
end
-- Only show glow if spell is actively casting, channeling, or queued
-- castId matches when spell is queued or being cast
-- visId matches during channeling
if spellId then
-- Show glow if actively casting/channeling this spell
if (casting == 1 and castId == spellId) or (channeling == 1 and visId == spellId) then
return true
end
-- Show glow if this spell is queued (castId set but not yet casting)
if casting == 0 and channeling == 0 and castId == spellId then
return true
end
end
end
elseif actionToCheck.item then
name = actionToCheck.item.name
end
+4
View File
@@ -38,6 +38,10 @@ CleveRoids.unknownTexture = "Interface\\Icons\\INV_Misc_QuestionMark"
CleveRoids.spell_tracking = {}
-- Combo point tracking (initialized early for /cast hook)
CleveRoids.lastComboPoints = 0
CleveRoids.lastComboPointsTime = 0
-- Holds information about the currently cast spell
CleveRoids.CurrentSpell = {
-- "channeled" or "cast"
+56
View File
@@ -1086,6 +1086,27 @@ ev:SetScript("OnEvent", function()
local eventType = arg3
local spellID = arg4
-- Capture combo points when cast STARTS (before they're consumed)
if (eventType == "START" or eventType == "CHANNEL") and spellID then
local _, playerGUID = UnitExists("player")
if casterGUID == playerGUID and targetGUID then
-- If this is a combo scaling spell, capture combo points NOW (before consumption)
if CleveRoids.IsComboScalingSpellID and CleveRoids.IsComboScalingSpellID(spellID) then
local currentCP = CleveRoids.GetComboPoints()
if currentCP and currentCP > 0 then
CleveRoids.lastComboPoints = currentCP
if CleveRoids.debug then
local spellName = SpellInfo(spellID) or "Unknown"
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffaaaaff[UNIT_CASTEVENT START]|r Captured %d CP before casting %s (ID:%d)",
currentCP, spellName, spellID)
)
end
end
end
end
end
if eventType == "CAST" and spellID then
local _, playerGUID = UnitExists("player")
if casterGUID == playerGUID and targetGUID then
@@ -1127,6 +1148,41 @@ ev:SetScript("OnEvent", function()
targetName = "Unknown"
end
end
-- For combo spells, populate name-based tracking for pfUI compatibility
if comboPoints and comboPoints > 0 then
local spellName = SpellInfo(spellID)
if spellName and CleveRoids.ComboPointTracking then
-- Remove rank from spell name to match pfUI's format
local baseName = string.gsub(spellName, "%s*%(Rank %d+%)", "")
CleveRoids.ComboPointTracking[baseName] = {
combo_points = comboPoints,
duration = duration,
cast_time = GetTime(),
target = targetName,
confirmed = true -- This is from actual UNIT_CASTEVENT, always confirmed
}
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cff00ffff[Name-based tracking]|r Set %s: %d CP, %ds duration (for pfUI)",
baseName, comboPoints, duration)
)
end
-- CRITICAL: Update pfUI's duration database directly
if pfUI and pfUI.api and pfUI.api.libdebuff and pfUI.api.libdebuff.debuffs then
-- pfUI stores durations by spell name in its debuffs table
pfUI.api.libdebuff.debuffs[baseName] = duration
if CleveRoids.debug then
DEFAULT_CHAT_FRAME:AddMessage(
string.format("|cffff00ff[pfUI Duration Inject]|r Set pfUI.api.libdebuff.debuffs['%s'] = %ds",
baseName, duration)
)
end
end
end
end
lib:AddEffect(targetGUID, targetName, spellID, duration, 0, "player")
-- Sync combo duration to pfUI if it's loaded