Skip to content

Commit df49fe1

Browse files
committed
gameplay: movement speed modifiers were incorrect
stunned movement was not applying correctly to diagonal movement because diagonal movement is a combination of two axes they exceed max speed until clamped by CheckParameters stunned movement slows were applying before this clamp, so they did not properly slow the actual speed of the player which could be much lower than the unclamped speed in addition, high max speed boosts (like the Baby Face's Blaster) did not apply unless the input speed was default speed since stunned movement manipulates input speed directly instead of changing player velocity, this broke the input speed boost and thus scout's max speed would be capped higher but not have the input speed to drive it. 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). however, with this fix, the slow amount is drastically more effective than it was before. so, we apply legacy handling to reduce slow amount by a percentage value relative to the old effective scaling. a scaling value was chosen to get a near average between the effective slow applied with a 100% slow, and the full slow amount applied with the fix note that there is still technically an issue with strafe tapping boosting your movement speed, but this is a game movement mechanic which I don't think is related to stuns, which seem to be intended to apply to movement controls, not exactly correlating to output velocity. or else stuns would not be a different movement mechanic vs. percentage movement speed slows. ref: ValveSoftware/Source-1-Games#3721
1 parent 5f353db commit df49fe1

File tree

3 files changed

+93
-13
lines changed

3 files changed

+93
-13
lines changed

src/game/server/tf/tf_player.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21628,6 +21628,17 @@ bool CTFPlayer::CanBreatheUnderwater() const
2162821628
return false;
2162921629
}
2163021630

21631+
//-----------------------------------------------------------------------------
21632+
// Purpose: Debug concommand to stun the player
21633+
//-----------------------------------------------------------------------------
21634+
void StunPlayer()
21635+
{
21636+
CTFPlayer* pPlayer = ToTFPlayer(ToTFPlayer(UTIL_PlayerByIndex(1)));
21637+
float flStunAmount = 0.60f;
21638+
pPlayer->m_Shared.StunPlayer(10.0f, flStunAmount, TF_STUN_MOVEMENT, pPlayer);
21639+
}
21640+
static ConCommand cc_StunPlayer("tf_stun_player", StunPlayer, "Stuns you.", FCVAR_CHEAT);
21641+
2163121642
//-----------------------------------------------------------------------------
2163221643
// Purpose:
2163321644
//-----------------------------------------------------------------------------

src/game/shared/gamemovement.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4550,7 +4550,10 @@ void CGameMovement::PlayerMove( void )
45504550
{
45514551
VPROF( "CGameMovement::PlayerMove" );
45524552

4553+
// TF runs this with speed modifiers
4554+
#if !defined(TF_DLL) && !defined(TF_CLIENT_DLL)
45534555
CheckParameters();
4556+
#endif
45544557

45554558
// clear output applied velocity
45564559
mv->m_outWishVel.Init();

src/game/shared/tf/tf_gamemovement.cpp

Lines changed: 79 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040

4141
ConVar tf_duck_debug_spew( "tf_duck_debug_spew", "0", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY );
42-
ConVar tf_showspeed( "tf_showspeed", "0", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY );
42+
ConVar tf_showspeed( "tf_showspeed", "0", FCVAR_REPLICATED | FCVAR_CHEAT, "1 = show speed during collisions, 2 = always show speed" );
4343
ConVar tf_avoidteammates( "tf_avoidteammates", "1", FCVAR_REPLICATED | FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "Controls how teammates interact when colliding.\n 0: Teammates block each other\n 1: Teammates pass through each other, but push each other away (default)" );
4444
ConVar tf_avoidteammates_pushaway( "tf_avoidteammates_pushaway", "1", FCVAR_REPLICATED, "Whether or not teammates push each other away when occupying the same space" );
4545
ConVar tf_solidobjects( "tf_solidobjects", "1", FCVAR_REPLICATED | FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY );
@@ -317,6 +317,12 @@ void CTFGameMovement::ProcessMovement( CBasePlayer *pBasePlayer, CMoveData *pMov
317317
// Handle charging demomens
318318
ChargeMove();
319319

320+
// Handle scouts that can move really fast with buffs
321+
HighMaxSpeedMove();
322+
323+
// Limit diagonal movement
324+
CheckParameters();
325+
320326
// Handle player stun.
321327
StunMove();
322328

@@ -326,9 +332,6 @@ void CTFGameMovement::ProcessMovement( CBasePlayer *pBasePlayer, CMoveData *pMov
326332
// Handle grappling hook move
327333
GrapplingHookMove();
328334

329-
// Handle scouts that can move really fast with buffs
330-
HighMaxSpeedMove();
331-
332335
// Run the command.
333336
PlayerMove();
334337

@@ -434,17 +437,19 @@ bool CTFGameMovement::GrapplingHookMove()
434437
if ( tf_grapplinghook_use_acceleration.GetBool() )
435438
{
436439
// Use acceleration with dampening
437-
float flSpeed = mv->m_vecVelocity.Length();
440+
float flSpeed = mv->m_vecVelocity.LengthSqr();
438441
if ( flSpeed > 0.f ) {
442+
flSpeed = FastSqrt( flSpeed );
439443
float flDampen = Min( tf_grapplinghook_dampening.GetFloat() * gpGlobals->frametime, flSpeed );
440444
mv->m_vecVelocity *= ( flSpeed - flDampen ) / flSpeed;
441445
}
442446

443447
mv->m_vecVelocity += vDesiredMove.Normalized() * ( tf_grapplinghook_acceleration.GetFloat() * gpGlobals->frametime );
444448

445-
flSpeed = mv->m_vecVelocity.Length();
449+
flSpeed = mv->m_vecVelocity.LengthSqr();
446450
if ( flSpeed > mv->m_flMaxSpeed )
447451
{
452+
flSpeed = FastSqrt( flSpeed );
448453
mv->m_vecVelocity *= mv->m_flMaxSpeed / flSpeed;
449454
}
450455
}
@@ -530,6 +535,13 @@ bool CTFGameMovement::ChargeMove()
530535
return true;
531536
}
532537

538+
#ifdef STAGING_ONLY
539+
static ConVar tf_movement_stun_multiplier("tf_movement_stun_multiplier", "1", FCVAR_REPLICATED, "Multiplier for movement speed when stunned.");
540+
static ConVar tf_movement_stun_clip("tf_movement_stun_clip", "0.41421356237", FCVAR_REPLICATED, "Clip off stun amount.");
541+
#endif
542+
static ConVar tf_movement_stun_legacy_threshold("tf_movement_stun_legacy_threshold", "1.25", FCVAR_REPLICATED, "Relative point for legacy stun amount handling.");
543+
static ConVar tf_movement_stun_legacy_on_charge("tf_movement_stun_legacy_on_charge", "1", FCVAR_REPLICATED, "Always apply full stun to charging players.");
544+
533545
//-----------------------------------------------------------------------------
534546
// Purpose:
535547
//-----------------------------------------------------------------------------
@@ -565,6 +577,42 @@ bool CTFGameMovement::StunMove()
565577

566578
// Handle movement stuns
567579
float flStunAmount = m_pTFPlayer->m_Shared.GetAmountStunned( TF_STUN_MOVEMENT );
580+
if ( flStunAmount )
581+
{
582+
// Handle legacy clipping value. Before the fix to stunned movement, stuns were applied to diagonal movement of sqrt(2) magnitude.
583+
// This means effectively that the stun would have to reduce past the ~141.4% movement speed to have any effect.
584+
//
585+
// So, a stun amount would at minimum need to be greater than ~0.414 to reduce movement speed below 100%.
586+
// Since this effectively meant stuns were clipped, there was non-linear scaling of stun amount to actual movement speed reduction.
587+
//
588+
// A stun value of 0.414 (or below) would have 0% effective stun, 0.6 would have ~31% effective stun, 1.0 would have ~59% effective stun.
589+
//
590+
// This legacy handling has been added so that we get similar slow amounts for stuns that were previously applied, but
591+
// also have them be linear and consistent from 0 to 1.
592+
if ( tf_movement_stun_legacy_on_charge.GetBool() && m_pTFPlayer->m_Shared.InCond( TF_COND_SHIELD_CHARGE ) )
593+
{
594+
// Slow down charging players the full amount. Charging players never had diagonal movement, so
595+
// they always got the full slow amount, which would end their charge. Being able to end
596+
// their charge is incredibly important, so we don't want to change that.
597+
flStunAmount = flStunAmount;
598+
}
599+
else if ( flStunAmount > tf_movement_stun_legacy_threshold.GetFloat() )
600+
{
601+
// For any stun amount greater than the threshold, we use the legacy clip behavior.
602+
flStunAmount = max( flStunAmount - 0.41421356237f, 0.0f ); // Reduce by sqrt(2) - 1.0f (see above)
603+
}
604+
else
605+
{
606+
#ifdef STAGING_ONLY
607+
// For playing around with the scaling.
608+
flStunAmount = max( flStunAmount - tf_movement_stun_clip.GetFloat(), 0.0f ) * tf_movement_stun_multiplier.GetFloat();
609+
#else
610+
// This equation essentially calculates the percentage of the stun amount that was effectively applied to diagonal movement
611+
// at a certain stun amount and applies that to all stun amounts consistently now.
612+
flStunAmount *= ( ( -0.41421356237f / tf_movement_stun_legacy_threshold.GetFloat() ) + 1 );
613+
#endif
614+
}
615+
}
568616
// Lerp to the desired amount
569617
if ( flStunAmount )
570618
{
@@ -1089,10 +1137,11 @@ void CTFGameMovement::PreventBunnyJumping()
10891137
return;
10901138

10911139
// Current player speed
1092-
float spd = mv->m_vecVelocity.Length();
1093-
if ( spd <= maxscaledspeed )
1140+
float spd = mv->m_vecVelocity.LengthSqr();
1141+
if ( spd <= maxscaledspeed * maxscaledspeed )
10941142
return;
10951143

1144+
spd = FastSqrt(spd);
10961145
// Apply this cropping fraction to velocity
10971146
float fraction = ( maxscaledspeed / spd );
10981147

@@ -1871,7 +1920,8 @@ void CTFGameMovement::WalkMove( void )
18711920
{
18721921
// Made it to the destination (remove the base velocity).
18731922
mv->SetAbsOrigin( trace.endpos );
1874-
VectorSubtract( mv->m_vecVelocity, player->GetBaseVelocity(), mv->m_vecVelocity );
1923+
Vector baseVelocity = player->GetBaseVelocity();
1924+
VectorSubtract( mv->m_vecVelocity, baseVelocity, mv->m_vecVelocity );
18751925

18761926
// Save the wish velocity.
18771927
mv->m_outWishVel += ( vecWishDirection * flWishSpeed );
@@ -1880,6 +1930,22 @@ void CTFGameMovement::WalkMove( void )
18801930
// NOTE YWB 7/5/07: Don't do this here, our version of CategorizePosition encompasses this test
18811931
// StayOnGround();
18821932

1933+
#if 1
1934+
// Debugging!!!
1935+
Vector vecTestVelocity = mv->m_vecVelocity;
1936+
vecTestVelocity.z = 0.0f;
1937+
float flTestSpeed = VectorLength( vecTestVelocity );
1938+
if ( tf_showspeed.GetInt() == 2 && baseVelocity.IsZero() && ( flTestSpeed > ( mv->m_flMaxSpeed + 1.0f ) ) )
1939+
{
1940+
Msg( "Step Max Speed < %f\n", flTestSpeed );
1941+
}
1942+
1943+
if ( tf_showspeed.GetInt() == 2 )
1944+
{
1945+
Msg( "Speed = %f\n", flTestSpeed );
1946+
}
1947+
#endif
1948+
18831949
#ifdef CLIENT_DLL
18841950
// Track how far we moved (if we're a Scout or an Engineer carrying a building).
18851951
CTFPlayer* pTFPlayer = ToTFPlayer( player );
@@ -1918,19 +1984,19 @@ void CTFGameMovement::WalkMove( void )
19181984
// NOTE YWB 7/5/07: Don't do this here, our version of CategorizePosition encompasses this test
19191985
// StayOnGround();
19201986

1921-
#if 0
1987+
#if 1
19221988
// Debugging!!!
19231989
Vector vecTestVelocity = mv->m_vecVelocity;
19241990
vecTestVelocity.z = 0.0f;
19251991
float flTestSpeed = VectorLength( vecTestVelocity );
1926-
if ( baseVelocity.IsZero() && ( flTestSpeed > ( mv->m_flMaxSpeed + 1.0f ) ) )
1992+
if ( tf_showspeed.GetInt() == 1 && baseVelocity.IsZero() && ( flTestSpeed > ( mv->m_flMaxSpeed + 1.0f ) ) )
19271993
{
19281994
Msg( "Step Max Speed < %f\n", flTestSpeed );
19291995
}
19301996

1931-
if ( tf_showspeed.GetBool() )
1997+
if ( tf_showspeed.GetInt() == 1 )
19321998
{
1933-
Msg( "Speed=%f\n", flTestSpeed );
1999+
Msg( "Speed = %f\n", flTestSpeed );
19342000
}
19352001

19362002
#endif

0 commit comments

Comments
 (0)