Repository: WeakAuras/WeakAuras2

Issue #3234: TBC: Swing Timer megathread ticket
Created: 2021-07-25T18:08:24Z
Description
To get this started, we discussed some issues in: #3205 allready.
I have now found the genrall bug inside the swing timer that caused problems that made people belive that some haste changes are snapshoted at the beginn of a swing.
Original Version WeakAuras/GenericTrigger.lua 1593:
if lastSwingMain then
  if mainSpeedNew ~= mainSpeed then
    timer:CancelTimer(mainTimer)
    local multiplier = mainSpeedNew / mainSpeed
    local timeLeft = (lastSwingMain + swingDurationMain - GetTime()) * multiplier
    swingDurationMain = mainSpeedNew
    mainTimer = timer:ScheduleTimerFixed(swingEnd, timeLeft, "main")
  end
end

Fixed Version:
if lastSwingMain then
  if mainSpeedNew ~= mainSpeed then
    timer:CancelTimer(mainTimer)
    local multiplier = mainSpeedNew / mainSpeed
    local timeLeft = (lastSwingMain + swingDurationMain - GetTime()) * multiplier
    swingDurationMain = mainSpeedNew
    mainSwingOffset = (lastSwingMain + swingDurationMain) - (GetTime() + timeLeft) 
    mainTimer = timer:ScheduleTimerFixed(swingEnd, timeLeft, "main")
  end
end

That dose also mean that this WeakAuras/GenericTrigger.lua 1661:
if not WeakAuras.IsBCC() then
  swingTimerFrame:RegisterUnitEvent("UNIT_ATTACK_SPEED", "player");
end

was not a propper solution and needs to be changed back to:
swingTimerFrame:RegisterUnitEvent("UNIT_ATTACK_SPEED", "player");

To boil down why the swing timer was not working correctly under attack speed changes mid swing:
The code to set the ScheduleTimerFixed was working correctly. It calculated the right time when the timer should expire.
E.g the swing was at 30% before the attack speed changed, the swing is also at 30% after the attack speed changes.
The error results from what the WeakAuras.GetSwingTimerInfo returns.
It return the swing duration, the time the next swing will land and some other stuff.
Now the problem is that the time that the next swing hits is calculated by lastSwingMain + swingDurationMain - mainSwingOffset while mainSwingOffset is 0,  that leads to a wrong calculation of when the next swing should hit. Because its calculating it with the attack speed that was modified during the swing as if the new attack speed was allready present at the begin of the swing.
Because of that, using mainSwingOffset to correct the time the next swing lands works.
If more information is needed or you want more evedince i can give that to you but that will take some time.
But what i stated is an obvious bug and i showed how to fix it.
So all in all what has to be done is reenabling the UNIT_ATTACK_SPEED event for BC, fixe the bug, look into the off hand and see if there is something simelar.
CATION
My fix is more of a prove of concept because when you parry a mob in the same swing as your attack speed changes, mainSwingOffset is overwritten which can lead to problems, so there is probably a better fix to this issue. Probably it is better to change how WeakAuras.GetSwingTimerInfo(hand) gets/calculates the time of the next swing.
Example
Abacus of Violent Odds before the fix:
https://streamable.com/bv4pw8
Abacus of Violent Odds after the fix:
https://streamable.com/pvgz6m
WeakAuras Version
WeakAuras 3.5 and 3.6
World of Warcraft Flavor
The Burning Crusade
Tested with only WeakAuras

 Yes
 No

Lua Error
No response
Reproduction Steps

Use anything (except Seal of the Crusader) to change your attack speed mid swing
Look at how the Swing timer will either be done to early or to late

Last Good Version
No response
Screenshots
No response
Export String
No response

Duplicate issue #3235: 3.6.0 swing timer haste fix should be reverted (BCC)
Created: 2021-07-25T18:14:30Z

Closing comment (2021-07-26T15:57:49Z): duplicate of #3234