From c9468e403385dc4192b93a34b46422dc7d1425e6 Mon Sep 17 00:00:00 2001 From: Meow <30401521+me0wg4ming@users.noreply.github.com> Date: Wed, 4 Mar 2026 00:13:37 +0100 Subject: [PATCH] fix: swing timer reset bugs (extra attacks, parry, slam) Extra attacks (Sword Specialization, Windfury, Hand of Justice) no longer double the swing timer. Added fallback detection for servers that don't set HITINFO_NOACTION correctly: if AUTO_ATTACK_SELF fires while more than 20% of the current swing remains, it's treated as an extra attack and ignored. Parry reset now uses correct Vanilla mechanic: resets timer to exactly 60% of weapon speed instead of incorrectly subtracting 40% from remaining time. Slam now hard-resets the swing timer from now instead of chaining from the previous nextSwing, which caused inflated swing times (e.g. 3.76s showing as 4.3s). --- modules/swingtimer.lua | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/swingtimer.lua b/modules/swingtimer.lua index 5dc61c2b..758f53b7 100644 --- a/modules/swingtimer.lua +++ b/modules/swingtimer.lua @@ -545,8 +545,25 @@ pfUI:RegisterModule("swingtimer", "vanilla:tbc", function () local hitInfo = arg4 or 0 local isOffhand = bit.band(hitInfo, HITINFO_LEFTSWING) ~= 0 local noAction = bit.band(hitInfo, HITINFO_NOACTION) ~= 0 - -- HITINFO_NOACTION: server did not advance the swing clock, ignore + -- HITINFO_NOACTION: server did not advance the swing clock (extra attack), ignore if noAction then return end + + -- Fallback extra attack detection: some servers (e.g. Turtle WoW) do not set + -- HITINFO_NOACTION for extra attacks (Sword Specialization, Windfury, Hand of Justice). + -- An extra attack fires a second AUTO_ATTACK_SELF while the current swing timer is + -- still running with significant time remaining. In that case, the swing clock was + -- NOT reset by the server, so we must not reset our timer either. + local now = GetTime() + if not isOffhand and swingState.mainhand.swinging then + local remaining = swingState.mainhand.nextSwing - now + -- If more than 20% of swing speed remains, this is an extra attack, not a real swing + if remaining > swingState.mainhand.speed * 0.2 then return end + end + if isOffhand and swingState.offhand.swinging then + local remaining = swingState.offhand.nextSwing - now + if remaining > swingState.offhand.speed * 0.2 then return end + end + StartSwing(isOffhand) elseif event == "AUTO_ATTACK_OTHER" then