update SwingTimer

Offhand is still not working because we don't have the CLEU arg isOffHand, that came with Cata
This commit is contained in:
NoM0Re
2025-02-17 00:34:30 +01:00
parent 02fe8164f6
commit 86b49b4010
3 changed files with 152 additions and 91 deletions
+106 -82
View File
@@ -1774,7 +1774,7 @@ function GenericTrigger.Add(data, region)
end
elseif Private.InternalEventByIDList[trueEvent] then
tinsert(trigger_events, trueEvent..":"..i)
elseif trueEvent:match("^UNIT_") or Private.UnitEventList[trueEvent] then
elseif trueEvent:match("^UNIT_") then
isUnitEvent = true
if string.lower(strsub(i, #i - 3)) == "pets" then
@@ -1940,6 +1940,8 @@ do
local selfGUID;
local mainSpeed, offSpeed = UnitAttackSpeed("player")
local casting = false
local skipNextAttack, skipNextAttackCount
local isAttacking
function WeakAuras.GetSwingTimerInfo(hand)
if(hand == "main") then
@@ -1971,6 +1973,10 @@ do
return 0, math.huge;
end
local function swingTriggerUpdate()
Private.ScanEvents("SWING_TIMER_UPDATE")
end
local function swingEnd(hand)
if(hand == "main") then
lastSwingMain, swingDurationMain, mainSwingOffset = nil, nil, nil;
@@ -1979,65 +1985,84 @@ do
elseif(hand == "ranged") then
lastSwingRange, swingDurationRange = nil, nil;
end
Private.ScanEvents("SWING_TIMER_END");
swingTriggerUpdate()
end
local function swingStart(hand)
mainSpeed, offSpeed = UnitAttackSpeed("player")
offSpeed = offSpeed or 0
local currentTime = GetTime()
if hand == "main" then
lastSwingMain = currentTime
swingDurationMain = mainSpeed
mainSwingOffset = 0
if mainTimer then
timer:CancelTimer(mainTimer)
end
if mainSpeed and mainSpeed > 0 then
mainTimer = timer:ScheduleTimer(swingEnd, mainSpeed, hand)
else
swingEnd(hand)
end
elseif hand == "off" then
lastSwingOff = currentTime
swingDurationOff = offSpeed
if offTimer then
timer:CancelTimer(offTimer)
end
if offSpeed and offSpeed > 0 then
offTimer = timer:ScheduleTimer(swingEnd, offSpeed, hand)
else
swingEnd(hand)
end
elseif hand == "ranged" then
local rangeSpeed = UnitRangedDamage("player")
lastSwingRange = currentTime
swingDurationRange = rangeSpeed
if rangeTimer then
timer:CancelTimer(rangeTimer)
end
if rangeSpeed and rangeSpeed > 0 then
rangeTimer = timer:ScheduleTimer(swingEnd, rangeSpeed, hand)
else
swingEnd(hand)
end
end
end
local function swingTimerCLEUCheck(ts, event, sourceGUID, _, _, destGUID, _, _, ...)
Private.StartProfileSystem("generictrigger swing");
if(sourceGUID == selfGUID) then
if(event == "SWING_DAMAGE" or event == "SWING_MISSED") then
if event == "SPELL_EXTRA_ATTACKS" then
skipNextAttack = ts
skipNextAttackCount = select(4, ...)
elseif(event == "SWING_DAMAGE" or event == "SWING_MISSED") then
if tonumber(skipNextAttack) and (ts - skipNextAttack) < 0.04 and tonumber(skipNextAttackCount) then
if skipNextAttackCount > 0 then
skipNextAttackCount = skipNextAttackCount - 1
return
end
end
local isOffHand = select(event == "SWING_DAMAGE" and 10 or 2, ...);
local event;
local currentTime = GetTime();
mainSpeed, offSpeed = UnitAttackSpeed("player");
offSpeed = offSpeed or 0;
if not(lastSwingMain) then
lastSwingMain = currentTime;
swingDurationMain = mainSpeed;
mainSwingOffset = 0;
event = "SWING_TIMER_START";
timer:CancelTimer(mainTimer);
mainTimer = timer:ScheduleTimer(swingEnd, mainSpeed, "main");
elseif(OffhandHasWeapon() and not lastSwingOff) then
lastSwingOff = currentTime;
swingDurationOff = offSpeed;
event = "SWING_TIMER_START";
timer:CancelTimer(offTimer);
offTimer = timer:ScheduleTimer(swingEnd, offSpeed, "off");
else
-- A swing occurred while both weapons are supposed to be on cooldown
-- Simply refresh the timer of the weapon swing which would have ended sooner
local mainRem, offRem = (lastSwingMain or math.huge) + mainSpeed - currentTime, (lastSwingOff or math.huge) + offSpeed - currentTime;
if(mainRem < offRem or not OffhandHasWeapon()) then
timer:CancelTimer(mainTimer, true);
lastSwingMain = currentTime;
swingDurationMain = mainSpeed;
event = "SWING_TIMER_CHANGE";
mainTimer = timer:ScheduleTimer(swingEnd, mainSpeed, "main");
else
timer:CancelTimer(mainTimer, true);
lastSwingOff = currentTime;
swingDurationOff = offSpeed;
event = "SWING_TIMER_CHANGE";
offTimer = timer:ScheduleTimer(swingEnd, offSpeed, "off");
if not isOffHand then
swingStart("main")
elseif(isOffHand) then
swingStart("off")
end
swingTriggerUpdate()
end
Private.ScanEvents(event);
end
elseif (destGUID == selfGUID and (select(1, ...) == "PARRY" or select(4, ...) == "PARRY")) then
elseif (destGUID == selfGUID and (... == "PARRY" or select(4, ...) == "PARRY")) then
if (lastSwingMain) then
local timeLeft = lastSwingMain + swingDurationMain - GetTime();
if (timeLeft > 0.6 * swingDurationMain) then
local timeLeft = lastSwingMain + swingDurationMain - GetTime() - (mainSwingOffset or 0);
if (timeLeft > 0.2 * swingDurationMain) then
local offset = 0.4 * swingDurationMain
if (timeLeft - offset < 0.2 * swingDurationMain) then
offset = timeLeft - 0.2 * swingDurationMain
end
timer:CancelTimer(mainTimer);
mainTimer = timer:ScheduleTimer(swingEnd, timeLeft - 0.4 * swingDurationMain, "main");
mainSwingOffset = 0.4 * swingDurationMain
Private.ScanEvents("SWING_TIMER_CHANGE");
elseif (timeLeft > 0.2 * swingDurationMain) then
timer:CancelTimer(mainTimer);
mainTimer = timer:ScheduleTimer(swingEnd, timeLeft - 0.2 * swingDurationMain, "main");
mainSwingOffset = 0.2 * swingDurationMain
Private.ScanEvents("SWING_TIMER_CHANGE");
mainTimer = timer:ScheduleTimer(swingEnd, timeLeft - offset, "main");
mainSwingOffset = (mainSwingOffset or 0) + offset
swingTriggerUpdate()
end
end
end
@@ -2045,8 +2070,9 @@ do
end
local function swingTimerCheck(event, unit, spell)
if unit ~= "player" then return end
if event ~= "PLAYER_EQUIPMENT_CHANGED" and unit and unit ~= "player" then return end
Private.StartProfileSystem("generictrigger swing");
local now = GetTime()
if event == "UNIT_ATTACK_SPEED" then
local mainSpeedNew, offSpeedNew = UnitAttackSpeed("player")
offSpeedNew = offSpeedNew or 0
@@ -2054,64 +2080,60 @@ do
if mainSpeedNew ~= mainSpeed then
timer:CancelTimer(mainTimer)
local multiplier = mainSpeedNew / mainSpeed
local timeLeft = (lastSwingMain + swingDurationMain - GetTime()) * multiplier
local timeLeft = (lastSwingMain + swingDurationMain - now) * multiplier
swingDurationMain = mainSpeedNew
mainSwingOffset = (lastSwingMain + swingDurationMain) - (now + timeLeft)
mainTimer = timer:ScheduleTimer(swingEnd, timeLeft, "main")
Private.ScanEvents("SWING_TIMER_CHANGE")
end
end
if lastSwingOff then
if offSpeedNew ~= offSpeed then
timer:CancelTimer(offTimer)
local multiplier = offSpeedNew / mainSpeed
local timeLeft = (lastSwingOff + swingDurationOff - GetTime()) * multiplier
local timeLeft = (lastSwingOff + swingDurationOff - now) * multiplier
swingDurationOff = offSpeedNew
offTimer = timer:ScheduleTimer(swingEnd, timeLeft, "off")
Private.ScanEvents("SWING_TIMER_CHANGE")
end
end
mainSpeed, offSpeed = mainSpeedNew, offSpeedNew
swingTriggerUpdate()
elseif casting and (event == "UNIT_SPELLCAST_INTERRUPTED" or event == "UNIT_SPELLCAST_FAILED") then
casting = false
elseif event == "PLAYER_EQUIPMENT_CHANGED" and isAttacking then
swingStart("main")
swingStart("off")
swingStart("ranged")
swingTriggerUpdate()
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
if Private.reset_swing_spells[spell] or casting then
if casting then
casting = false
end
local event;
mainSpeed, offSpeed = UnitAttackSpeed("player");
lastSwingMain = GetTime();
swingDurationMain = mainSpeed;
mainSwingOffset = 0;
if (lastSwingMain) then
timer:CancelTimer(mainTimer);
event = "SWING_TIMER_CHANGE";
else
event = "SWING_TIMER_START";
-- check next frame
swingTimerFrame:SetScript("OnUpdate", function(self)
if isAttacking then
swingStart("main")
swingTriggerUpdate()
end
mainTimer = timer:ScheduleTimer(swingEnd, mainSpeed, "main");
Private.ScanEvents(event);
elseif Private.reset_ranged_swing_spells[spell] then
local event;
local currentTime = GetTime();
local speed = UnitRangedDamage("player");
if(lastSwingRange) then
timer:CancelTimer(rangeTimer, true)
event = "SWING_TIMER_CHANGE";
else
event = "SWING_TIMER_START";
self:SetScript("OnUpdate", nil)
end)
end
lastSwingRange = currentTime;
swingDurationRange = speed;
rangeTimer = timer:ScheduleTimer(swingEnd, speed, "ranged");
Private.ScanEvents(event);
if Private.reset_ranged_swing_spells[spell] then
swingStart("ranged")
swingTriggerUpdate()
end
elseif event == "UNIT_SPELLCAST_START" then
if not Private.noreset_swing_spells[spell] then
-- pause swing timer
casting = true
lastSwingMain, swingDurationMain, mainSwingOffset = nil, nil, nil
lastSwingOff, swingDurationOff = nil, nil
Private.ScanEvents("SWING_TIMER_END")
swingTriggerUpdate()
end
elseif event == "PLAYER_REGEN_DISABLED" then
isAttacking = true
elseif event == "PLAYER_REGEN_ENABLED" then
isAttacking = nil
end
Private.StopProfileSystem("generictrigger swing");
end
@@ -2120,7 +2142,9 @@ do
if not(swingTimerFrame) then
swingTimerFrame = CreateFrame("Frame");
swingTimerFrame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
swingTimerFrame:RegisterEvent("PLAYER_ENTER_COMBAT");
swingTimerFrame:RegisterEvent("PLAYER_REGEN_DISABLED");
swingTimerFrame:RegisterEvent("PLAYER_REGEN_ENABLED");
swingTimerFrame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED");
swingTimerFrame:RegisterEvent("UNIT_ATTACK_SPEED");
swingTimerFrame:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED");
swingTimerFrame:RegisterEvent("UNIT_SPELLCAST_START")
+4 -3
View File
@@ -4434,9 +4434,6 @@ Private.event_prototypes = {
type = "unit",
events = {},
internal_events = {
"SWING_TIMER_START",
"SWING_TIMER_CHANGE",
"SWING_TIMER_END",
"SWING_TIMER_UPDATE"
},
force_events = "SWING_TIMER_UPDATE",
@@ -4532,6 +4529,10 @@ Private.event_prototypes = {
{
hidden = true,
test = "(inverse and duration == 0) or (not inverse and duration > 0)"
},
{
hidden = true,
test = "remainingCheck"
}
},
automaticrequired = true,
+36
View File
@@ -3208,7 +3208,10 @@ Private.reset_swing_spells = {
[GetSpellInfo(20549)] = true, -- War Stomp
[GetSpellInfo(56815)] = true, -- Rune Strike
[GetSpellInfo(5384)] = true, -- Feign Death
[GetSpellInfo(2764)] = true, -- Throw
[GetSpellInfo(5019)] = true, -- Shoot
}
Private.reset_ranged_swing_spells = {
[GetSpellInfo(2764)] = true, -- Throw
[GetSpellInfo(5019)] = true, -- Shoot Wands
@@ -3216,6 +3219,39 @@ Private.reset_ranged_swing_spells = {
[GetSpellInfo(5384)] = true, -- Feign Death
}
Private.noreset_swing_spells = {
[GetSpellInfo(23063)] = true, -- Dense Dynamite
[GetSpellInfo(4054)] = true, -- Rough Dynamite
[GetSpellInfo(4064)] = true, -- Rough Copper Bomb
[GetSpellInfo(4061)] = true, -- Coarse Dynamite
[GetSpellInfo(8331)] = true, -- Ez-Thro Dynamite
[GetSpellInfo(4065)] = true, -- Large Copper Bomb
[GetSpellInfo(4066)] = true, -- Small Bronze Bomb
[GetSpellInfo(4062)] = true, -- Heavy Dynamite
[GetSpellInfo(4067)] = true, -- Big Bronze Bomb
[GetSpellInfo(4068)] = true, -- Iron Grenade
[GetSpellInfo(23000)] = true, -- Ez-Thro Dynamite II
[GetSpellInfo(12421)] = true, -- Mithril Frag Bomb
[GetSpellInfo(4069)] = true, -- Big Iron Bomb
[GetSpellInfo(12562)] = true, -- The Big One
[GetSpellInfo(12543)] = true, -- Hi-Explosive Bomb
[GetSpellInfo(19769)] = true, -- Thorium Grenade
[GetSpellInfo(19784)] = true, -- Dark Iron Bomb
[GetSpellInfo(30216)] = true, -- Fel Iron Bomb
[GetSpellInfo(19821)] = true, -- Arcane Bomb
[GetSpellInfo(39965)] = true, -- Frost Grenade
[GetSpellInfo(30461)] = true, -- The Bigger One
[GetSpellInfo(30217)] = true, -- Adamantite Grenade
[GetSpellInfo(35476)] = true, -- Drums of Battle
[GetSpellInfo(35475)] = true, -- Drums of War
[GetSpellInfo(35477)] = true, -- Drums of Speed
[GetSpellInfo(35478)] = true, -- Drums of Restoration
[GetSpellInfo(34120)] = true, -- Steady Shot (rank 1)
[GetSpellInfo(19434)] = true, -- Aimed Shot (rank 1)
[GetSpellInfo(1464)] = true, -- Slam (rank 1)
--35474 Drums of Panic DO reset the swing timer, do not add
}
WeakAuras.StopMotion = WeakAuras.StopMotion or {}
WeakAuras.StopMotion.texture_types = WeakAuras.StopMotion.texture_types or {}
WeakAuras.StopMotion.texture_data = WeakAuras.StopMotion.texture_data or {}