Open LordExor opened 2 years ago
[TF2] Stunned movement faster than intended when moving diagonally
Issue transferred from https://github.com/ValveSoftware/Source-1-Games/issues/3947. @mastercoms posted on 2022-06-24T00:45:27:
Hello! I'm sure you all are aware of the issue where stunned movement is faster than intended when moving diagonally (when forwardmove > 0
&& sidemove > 0
), as there was a reverted patch which targeted this issue (Blue Moon, March 28, 2018 "Fixed player movement speed sometimes being faster than intended while under the effect of a movement stun (i.e. Natascha, The Sandman's ranged attack, Bonk! Atomic Punch)".
I'm not exactly sure what you all tried, but I know that it was reverted due to it causing all stuns to be much slower than intended even in the previously non-broken case, unless I misunderstood the issue. So apologies if the following suggestion is redundant.
I have found that this bug stems from when CheckParameters()
is called. CheckParameters()
scales diagonal movement down, such that the hypotenuse of forward move and side move does not exceed max speed. However, within ProcessMovement
, this is done AFTER StunMove()
, in PlayerMove()
. So, the stunned hypotenuse of forward move and side move is already lower than max speed, so the extent is not clamped, and thus the player has the "room" to increase their max speed by moving along a hypotenuse (c > a
, c > b
, c = sqrt(a^2 + b^2)
).
So, essentially, the root of the change is to call CheckParameters()
within CTFGameMovement::ProcessMovement()
, before StunMove()
and after ChargeMove()
, and add a if !(defined(TF_DLL) || defined(TF_CLIENT_DLL)) guard to CGameMovement::PlayerMove()
around CheckParameters()
to skip calling it again. I personally didn't see issues calling it before ChargeMove()
either, since ChargeMove()
forces forward speed to tf_max_charge_speed
, it doesn't really matter.
While testing this, I found another bug with the baby face's blaster. Because of how HighMaxSpeedMove()
works, it boosts the forward move and side move to be high enough to drive movement at the intended velocity. However, when under stunned movement, forward move and side move change, so HighMaxSpeedMove()
never boosts the speed.
To resolve this, you need to call HighMaxSpeedMove()
before CheckParameters()
and StunMove()
, so that the base forward move and side move value can be boosted for further changes by CheckParameters()
(to limit the hypotenuse) and StunMove()
(to scale down forward move and side move).
With these changes, a 0.6
slow (as applied by the Natascha at close range), slows down a full charge BFB Scout from 520
to 208
in all directions (40% of 520
), as intended and proper! And of course, normal Scout speed is slowed from 400
to 160
in all directions (40% of 400
). You can still temporarily boost your speed very slightly by circle strafing, but fixing that would require changing max speed and I think that would change the meaning of stunned movement (or else max speed would have probably been changed in the first place, as there are already mechanics for this). This was also a problem in the previous iteration, so even if unintentional, these changes are an improvement over the previous state as far as I can see.
If you are wondering, the GrapplingHookMove()
code does not get affected by this order change, since it sets max speed tf_grapplinghook_move_speed
to and forward and side move to 0.
Please let me know if you have any further questions and comments about the fix.
@nosoop commented on 2022-06-24T04:38:41:
A lot of good info here; just wanted to mention that it's also being tracked under #3721.
All movement stuns applied through weaponry can be bypassed with diagonal movement of any sort. This bug interferes with the functionality of three different items (BONK! Atomic Punch, Sandman, Natascha), nullifying their benefits—and in the case of BONK!, nullifying drawbacks.
The following video demonstrates the glitch. https://youtu.be/5KT-m_2yzJQ