From 6db708f40b63db3fd27e5c68d27f366afa8a5fac Mon Sep 17 00:00:00 2001 From: Jrc13245 Date: Sat, 25 Oct 2025 11:34:36 -0400 Subject: [PATCH] fix castsequence reset functionality --- Core.lua | 52 +++++++++++++++++++++++++++++---- Utility.lua | 83 +++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 108 insertions(+), 27 deletions(-) diff --git a/Core.lua b/Core.lua index 8d6c744..7c15d20 100644 --- a/Core.lua +++ b/Core.lua @@ -1051,9 +1051,32 @@ end function CleveRoids.AdvanceSequence(sequence) if sequence.index < table.getn(sequence.list) then + -- Not at the end yet, just advance normally sequence.index = sequence.index + 1 else - CleveRoids.ResetSequence(sequence) + -- At the end of sequence - check if we should auto-reset or stay at last step + local hasNonModifierReset = false + + if sequence.reset then + -- Check if there are any reset conditions besides modifier keys + for k, _ in pairs(sequence.reset) do + -- target, combat, secs are non-modifier resets + if k ~= "alt" and k ~= "ctrl" and k ~= "shift" then + hasNonModifierReset = true + break + end + end + end + + -- Only auto-reset if: + -- 1. No reset table exists at all, OR + -- 2. Reset table only contains modifier keys (alt/ctrl/shift) + -- Otherwise, stay on the last step and keep casting it until reset fires + if not hasNonModifierReset then + CleveRoids.ResetSequence(sequence) + end + -- If hasNonModifierReset is true, sequence.index stays at max, + -- so GetCurrentSequenceAction will keep returning the last spell end end @@ -1710,7 +1733,6 @@ end return handled end --- Keep THIS version function CleveRoids.DoCastSequence(sequence) if not CleveRoids.hasSuperwow then CleveRoids.Print("|cFFFF0000/castsequence|r requires |cFF00FFFFSuperWoW|r.") @@ -1727,6 +1749,11 @@ function CleveRoids.DoCastSequence(sequence) return end + -- If sequence is complete, don't execute - let macro continue to next line + if sequence.complete then + return + end + if sequence.index > 1 and sequence.reset then for k,_ in pairs(sequence.reset) do if CleveRoids.kmods[k] and CleveRoids.kmods[k]() then @@ -1749,6 +1776,17 @@ function CleveRoids.DoCastSequence(sequence) local actionText = (sequence.cond or "") .. active.action local resolvedText, conds = CleveRoids.GetParsedMsg(actionText) + -- Check if this is a macro execution {macroname} + local macroName = CleveRoids.GetMacroNameFromAction(active.action) + if macroName then + -- Execute the macro + local success = CleveRoids.ExecuteMacroByName(macroName) + if not success then + CleveRoids.currentSequence = prevSeq + end + return + end + local function cast_by_name(msg) msg = msg or "" if not string.find(msg, "%(%s*.-%s*%)%s*$") then @@ -1773,7 +1811,6 @@ function CleveRoids.DoCastSequence(sequence) end end --- Core.lua CleveRoids.DoConditionalCancelAura = function(msg) local s = CleveRoids.Trim(msg or "") if s == "" then return false end @@ -2347,11 +2384,14 @@ end function CleveRoids.Frame:PLAYER_LEAVE_COMBAT() CleveRoids.CurrentSpell.autoAttack = false CleveRoids.CurrentSpell.autoAttackLock = false + + -- Reset any sequence with reset=combat that has progressed past the first step for _, sequence in pairs(CleveRoids.Sequences) do - if CleveRoids.currentSequence ~= sequence and sequence.index > 1 and sequence.reset.combat then + if sequence.index > 1 and sequence.reset and sequence.reset.combat then CleveRoids.ResetSequence(sequence) end end + if CleveRoidMacros.realtime == 0 then CleveRoids.QueueActionUpdate() end @@ -2361,11 +2401,13 @@ function CleveRoids.Frame:PLAYER_TARGET_CHANGED() CleveRoids.CurrentSpell.autoAttack = false CleveRoids.CurrentSpell.autoAttackLock = false + -- Reset any sequence with reset=target that has progressed past the first step for _, sequence in pairs(CleveRoids.Sequences) do - if CleveRoids.currentSequence ~= sequence and sequence.index > 1 and sequence.reset.target then + if sequence.index > 1 and sequence.reset and sequence.reset.target then CleveRoids.ResetSequence(sequence) end end + if CleveRoidMacros.realtime == 0 then CleveRoids.QueueActionUpdate() end diff --git a/Utility.lua b/Utility.lua index 8cf28d3..8390088 100644 --- a/Utility.lua +++ b/Utility.lua @@ -748,28 +748,6 @@ function lib:AddEffect(guid, unitName, spellID, duration, stacks, caster) lib.objects[guid][spellID] = rec end -function lib:GetDuration(spellID) - return self.durations[spellID] or 0 -end - -function lib:AddEffect(guid, unitName, spellID, duration, stacks, caster) - if not guid or not spellID then return end - duration = duration or lib:GetDuration(spellID) - if duration <= 0 then return end - - lib.objects[guid] = lib.objects[guid] or {} - lib.guidToName[guid] = unitName - - local rec = lib.objects[guid][spellID] or {} - rec.spellID = spellID - rec.start = GetTime() - rec.duration = duration - rec.stacks = stacks or 0 - rec.caster = caster - - lib.objects[guid][spellID] = rec -end - function lib:UnitDebuff(unit, id) local _, guid = UnitExists(unit) if not guid then return nil end @@ -938,3 +916,64 @@ evLearn:SetScript("OnEvent", function() end end end) + +-- Cleanup dead/invalid targets +local evCleanup = CreateFrame("Frame", "CleveRoidsLibDebuffCleanupFrame", UIParent) +evCleanup:RegisterEvent("PLAYER_TARGET_CHANGED") +evCleanup:RegisterEvent("PLAYER_DEAD") +evCleanup:RegisterEvent("PLAYER_ENTERING_WORLD") + +local lastCleanup = 0 +local CLEANUP_THROTTLE = 2 -- Only run cleanup every 2 seconds max + +evCleanup:SetScript("OnEvent", function() + local timestamp = GetTime() + + -- Cleanup on zone change / login / death + if event == "PLAYER_ENTERING_WORLD" or event == "PLAYER_DEAD" then + -- Keep only current target's data + local _, currentGUID = UnitExists("target") + if currentGUID then + local temp = lib.objects[currentGUID] + lib.objects = {} + if temp then + lib.objects[currentGUID] = temp + end + else + lib.objects = {} -- Clear everything + end + lastCleanup = timestamp + return + end + + -- Throttle cleanup on target change + if event == "PLAYER_TARGET_CHANGED" then + if (timestamp - lastCleanup) < CLEANUP_THROTTLE then + return -- Don't cleanup too frequently + end + lastCleanup = timestamp + + -- Remove expired effects from all GUIDs + for guid, effects in pairs(lib.objects) do + local _, targetGUID = UnitExists("target") + local isCurrentTarget = (targetGUID == guid) + + -- Check if current target is dead + if isCurrentTarget and UnitIsDead("target") then + lib.objects[guid] = nil + else + -- Remove expired effects + for spellID, effect in pairs(effects) do + if effect.start + effect.duration < timestamp then + effects[spellID] = nil + end + end + + -- Remove GUID if no effects remain (but keep current target) + if not next(effects) and not isCurrentTarget then + lib.objects[guid] = nil + end + end + end + end +end)