
Ice Lance IsInFlight value changes when Snapshot is used
mwojtkowski opened this issue ยท 3 comments
Before You Begin
- I confirm that I have downloaded the latest version of the addon.
- I am not playing on a private server.
- I checked for an existing, open ticket for this issue and was not able to find one.
- I edited the title of this issue (above) so that it describes the issue I am reporting.
- I am reporting an issue with the default priority included with the specialization (imported or edited priorities are not supported).
Spec
Mage - Frost
Describe the Issue
I was testing the latest version from github (346cbd3) with Frost Mage fixes and noticed something. I have weakaura that I use to check several values (InFligh, Icicles, Winter's Chill etc.) in real time, and when I did the snapshot, I saw that it had "Ice Lance in-flight? Yes" but my weakaura was showing false. So I've added Hekili:Print to IsInFlight function and saw this:
this is when you click snapshot while Ice Lance is in flight
The IsInFlight("ice_lance") function returns false, but when you press the snapshot button, it will return true for (in my case) 35ms and then false again for the rest of the Ice Lance flight.
In comparison this is how it looks for Frostbolt
How to Reproduce
Modified IsInFlight function
function state:IsInFlight( action, real )
if real and ( realQueue[ action ] or 0 ) == 0 then return false end
local queue = real and realQueue or virtualQueue
for i, entry in ipairs( queue ) do
if entry.action == action and entry.type == "PROJECTILE_IMPACT" and entry.start <= self.query_time then
if entry.action == "ice_lance" then
Hekili:Print(string.format("%.3f Ice Lance is in flight (%s)", GetTime() ,(real and "real" or "virtual")))
end
return true
end
end
return false
end
Snapshot (Link)
Raidbots Sim Report (Link)
No response
Additional Information
No response
Contact Information
No response
function state:IsInFlight( action, real )
if real and ( realQueue[ action ] or 0 ) == 0 then return false end
local queue = real and realQueue or virtualQueue
for i, entry in ipairs( queue ) do
if entry.action == action and entry.type == "PROJECTILE_IMPACT" and entry.start <= self.query_time then
if entry.action == "ice_lance" then
Hekili:Print(string.format("%.3f Ice Lance is in flight (%s)", GetTime() ,(real and "real" or "virtual")))
end
return true
end
end
return false
end
Using GetTime()
here ignores the perilous effects of time-travel; the predicted game state is not cromulent against real time. You probably want to make these values go in the snapshot, since that's when the actual values are referenced (real and virtual).
For those values, it's not necessarily clear (1) which display is making predictions, which impacts whether events are watched; (2) how far into generating predictions the engine has gotten at the time of that frame; to the addon engine, it is already the future and further into the future for each step in a prediction set.
if Hekili.ActiveDebug then Hekili:Debug( "%s @ %.3f, step %d (+%.3f) - Ice Lance in Flight[ %s], Remaining Flight Time[ %.3f ]", self.display, self.now, self.index, self.offset + self.delay, action.ice_lance.in_flight, action.ice_lance.in_flight_remains ) end
If you take a snapshot, that'll tell you what the value was and when the addon imagines it was checking, rather that when it was actually checking. Assuming no errors in the code above. You'll see that display, now, and step will stay fairly sane but offset+delay will jump around because the addon tests whether an ability can be used now, soon, and later on a per action list entry basis -- forward and backward in virtual time.
...Yeah.
If you're looking to see the real value of whether Ice Lance is presently in flight for realsies, you could put your print into the reset_precast
hook in MageFrost.lua -- it runs once per set of recommendations generated.
Hekili:Print( "%s @ %.3f[ %s ] - Ice Lance in Flight[ %s ], Remaining Flight Time[ %.3f ]", self.display, self.now, real and "real" or "fake", max( 0, entry.time - self.query_time ) and "Yeah" or "Nah", max( 0, entry.time - self.query_time ) )
I think the above would print once per display at reset and that I made the entries ignore time-travel.
Last consideration, in_flight
and in_flight_remains
are liars because a little finesse is needed to make spell queuing work.
elseif k == "in_flight" then
if ability.flightTime then
return ability.lastCast + max( ability.flightTime, 0.25 ) > state.query_time
end
return state:IsInFlight( t.action ) or ability.isProjectile and ability.lastCast + 0.25 > state.query_time
elseif k == "in_flight_remains" then
if ability.flightTime then
return max( 0, ability.lastCast + max( ability.flightTime, 0.25 ) - state.query_time )
end
return max( state:InFlightRemains( t.action ), ability.isProjectile and ability.lastCast + 0.25 - state.query_time or 0 )
Every projectile has an added travel time of 0.25s so that there's room to react/queue spells for things like Frost Bolt into Ice Lance.
Finally, what am I doing with my life?