Fixed ladder bugs

► Fixed a bug where players could respawn on ladders.
► Fixed an issue where players disconnecting while on a ladder would cause it to become inoperable.
► Movement fixes.
► Fixed an exploit where some players could use climb ladders at insane speeds.
► Fixed an issue where players could dismount ladders and go through walls.
This commit is contained in:
speedvoltage 2025-03-06 23:24:43 +01:00
parent aea94b32cb
commit b504bb2e33
5 changed files with 68 additions and 5 deletions

View file

@ -166,6 +166,12 @@ CHL2MP_Player::~CHL2MP_Player( void )
void CHL2MP_Player::UpdateOnRemove( void )
{
if ( auto p = GetLadderMove() )
{
UTIL_Remove( ( CBaseEntity * ) ( p->m_hReservedSpot.Get() ) );
p->m_hReservedSpot = NULL;
}
if ( m_hRagdoll )
{
UTIL_RemoveImmediate( m_hRagdoll );
@ -955,6 +961,22 @@ bool CHL2MP_Player::BumpWeapon( CBaseCombatWeapon *pWeapon )
return true;
}
void CHL2MP_Player::LadderRespawnFix()
{
if ( auto lm = GetLadderMove() )
{
if ( lm->m_bForceLadderMove )
{
lm->m_bForceLadderMove = false;
if ( lm->m_hReservedSpot )
{
UTIL_Remove( ( CBaseEntity * ) lm->m_hReservedSpot.Get() );
lm->m_hReservedSpot = NULL;
}
}
}
}
void CHL2MP_Player::ChangeTeam( int iTeam )
{
/* if ( GetNextTeamChangeTime() >= gpGlobals->curtime )
@ -966,6 +988,8 @@ void CHL2MP_Player::ChangeTeam( int iTeam )
return;
}*/
LadderRespawnFix();
bool bKill = false;
if ( HL2MPRules()->IsTeamplay() != true && iTeam != TEAM_SPECTATOR )
@ -1298,6 +1322,8 @@ void CHL2MP_Player::DetonateTripmines( void )
void CHL2MP_Player::Event_Killed( const CTakeDamageInfo &info )
{
LadderRespawnFix();
//update damage info with our accumulated physics force
CTakeDamageInfo subinfo = info;
subinfo.SetDamageForce( m_vecTotalBulletForce );

View file

@ -143,6 +143,8 @@ public:
bool IsThreatAimingTowardMe( CBaseEntity* threat, float cosTolerance = 0.8f ) const;
bool IsThreatFiringAtMe( CBaseEntity* threat ) const;
void LadderRespawnFix();
private:
CNetworkQAngle( m_angEyeAngles );

View file

@ -823,6 +823,9 @@ public:
}
}
float GetLadderCooldownTime() const { return m_flLadderCooldownTime; }
void SetLadderCooldownTime( float cooldownTime ) { m_flLadderCooldownTime = cooldownTime; }
private:
// How much of a movement time buffer can we process from this user?
int m_nMovementTicksForUserCmdProcessingRemaining;
@ -838,6 +841,7 @@ private:
int DetermineSimulationTicks( void );
void AdjustPlayerTimeBase( int simulation_ticks );
float m_flLadderCooldownTime;
public:

View file

@ -468,8 +468,27 @@ bool CHL2GameMovement::ExitLadderViaDismountNode( CFuncLadder *ladder, bool stri
continue;
}
// Now perform a trace to ensure there is a clear line of sight
// between the player and the dismount node
trace_t losTrace;
Vector playerPos = mv->GetAbsOrigin() + player->GetViewOffset(); // Player's view position
UTIL_TraceLine( playerPos, org, MASK_PLAYERSOLID, player, COLLISION_GROUP_PLAYER_MOVEMENT, &losTrace );
// Peter: If there's an obstruction (a wall or other object)
// between the player and the dismount node, skip it.
// There is an option in Hammer to prevent this, but
// level designer tend to forget to properly set this, so maps
// like dm_assault that have two ladders on either side means
// players can clip through walls and I fail to see
// why this should be a gameplay feature.
if ( losTrace.fraction != 1.0f )
{
continue;
}
// Find the best dot product
Vector vecToSpot = org - ( mv->GetAbsOrigin() + player->GetViewOffset() );
Vector vecToSpot = org - playerPos;
vecToSpot.z = 0.0f;
float d = VectorNormalize( vecToSpot );
@ -964,6 +983,14 @@ bool CHL2GameMovement::LadderMove( void )
if ( !ladder )
{
#ifdef GAME_DLL
// Check if the player is still in the cooldown period after dismounting the ladder
if ( gpGlobals->curtime < GetHL2Player()->GetLadderCooldownTime() )
{
// Player is still in cooldown, prevent mounting
return false;
}
#endif
Findladder( 64.0f, &bestLadder, bestOrigin, NULL );
}
@ -1083,6 +1110,11 @@ bool CHL2GameMovement::LadderMove( void )
{
mv->m_vecVelocity.z = mv->m_vecVelocity.z + 50;
}
#ifdef GAME_DLL
// Set cooldown time for remounting the ladder (0.5 seconds) - server-side only
GetHL2Player()->SetLadderCooldownTime( gpGlobals->curtime + 0.5f );
#endif
return false;
}
@ -1188,9 +1220,7 @@ bool CHL2GameMovement::CanAccelerate()
}
#endif
BaseClass::CanAccelerate();
return true;
return BaseClass::CanAccelerate();
}
@ -1200,4 +1230,4 @@ bool CHL2GameMovement::CanAccelerate()
IGameMovement *g_pGameMovement = ( IGameMovement * )&g_GameMovement;
EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CGameMovement, IGameMovement,INTERFACENAME_GAMEMOVEMENT, g_GameMovement );
#endif
#endif

View file

@ -1026,6 +1026,7 @@ void CHL2MPRules::RestartGame()
pPlayer->GetActiveWeapon()->Holster();
}
pPlayer->RemoveAllItems( true );
pPlayer->LadderRespawnFix();
respawn( pPlayer, false );
pPlayer->Reset();
}