Spectator observer fixes

► Fixed an issue where spectators could spectate a player who joined team Spectator.
► Switch to free roaming when joining team spectator.
► Switch to free roaming when player leaves the game.
This commit is contained in:
speedvoltage 2025-03-11 12:32:56 +01:00
parent a62efecf62
commit da6e3d2033
3 changed files with 77 additions and 1 deletions

View file

@ -2287,7 +2287,7 @@ bool CBasePlayer::StartObserverMode(int mode)
AddSolidFlags( FSOLID_NOT_SOLID );
SetObserverMode( mode );
SetObserverMode( OBS_MODE_ROAMING );
if ( gpGlobals->eLoadType != MapLoad_Background )
{
@ -4644,6 +4644,29 @@ void CBasePlayer::PostThink()
ClientSettingsChanged();
}
if ( IsObserver() && !IsHLTV() )
{
if ( m_iObserverMode == OBS_MODE_POI || m_iObserverMode == OBS_MODE_FIXED )
{
// Remove a pointless second third person view
m_iObserverMode = OBS_MODE_ROAMING;
}
if ( m_iObserverLastMode == OBS_MODE_ROAMING )
{
SetMoveType( MOVETYPE_OBSERVER );
}
if ( m_iObserverMode != OBS_MODE_IN_EYE )
{
m_Local.m_iHideHUD = HIDEHUD_CROSSHAIR;
}
else
{
m_Local.m_iHideHUD &= ~HIDEHUD_CROSSHAIR;
}
}
m_vecSmoothedVelocity = m_vecSmoothedVelocity * SMOOTHING_FACTOR + GetAbsVelocity() * ( 1 - SMOOTHING_FACTOR );
if ( !g_fGameOver && !m_iPlayerLocked )
@ -6607,6 +6630,11 @@ bool CBasePlayer::ClientCommand( const CCommand &args )
else
{
// switch to next spec mode if no parameter given
CBaseEntity *target = FindNextObserverTarget( false );
if ( !target )
return true;
mode = GetObserverMode() + 1;
if ( mode > LAST_PLAYER_OBSERVERMODE )
@ -6648,6 +6676,10 @@ bool CBasePlayer::ClientCommand( const CCommand &args )
{
SetObserverTarget( target );
}
else
{
SetObserverMode( OBS_MODE_ROAMING );
}
}
else if ( GetObserverMode() == OBS_MODE_FREEZECAM )
{
@ -6666,6 +6698,10 @@ bool CBasePlayer::ClientCommand( const CCommand &args )
{
SetObserverTarget( target );
}
else
{
SetObserverMode( OBS_MODE_ROAMING );
}
}
else if ( GetObserverMode() == OBS_MODE_FREEZECAM )
{
@ -6684,6 +6720,10 @@ bool CBasePlayer::ClientCommand( const CCommand &args )
{
SetObserverTarget( target );
}
else
{
SetObserverMode( OBS_MODE_ROAMING );
}
}
return true;

View file

@ -294,6 +294,8 @@ void CHL2MPRules::Think( void )
CGameRules::Think();
ObserverTargetFix();
if ( g_fGameOver ) // someone else quit the game already
{
// check to see if we should change levels now
@ -373,6 +375,39 @@ void CHL2MPRules::Think( void )
#endif
}
#ifdef GAME_DLL
void CHL2MPRules::ObserverTargetFix()
{
// Fixes a bug where a specator could spectate another spectator
for ( int i = 1; i <= gpGlobals->maxClients; ++i )
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex( i );
if ( !pPlayer )
continue;
if ( pPlayer->GetObserverMode() == OBS_MODE_CHASE || pPlayer->GetObserverMode() == OBS_MODE_IN_EYE )
{
CBasePlayer *pTarget = ToBasePlayer( pPlayer->GetObserverTarget() );
if ( pTarget )
{
if ( pTarget->GetTeamNumber() == TEAM_SPECTATOR )
{
pPlayer->SetObserverMode( OBS_MODE_ROAMING );
pPlayer->SetObserverTarget( NULL );
}
}
else
{
pPlayer->SetObserverMode( OBS_MODE_ROAMING );
pPlayer->SetObserverTarget( NULL );
}
}
}
}
#endif
void CHL2MPRules::GoToIntermission( void )
{
#ifndef CLIENT_DLL

View file

@ -152,6 +152,7 @@ public:
void CheckAllPlayersReady( void );
virtual bool IsConnectedUserInfoChangeAllowed( CBasePlayer *pPlayer );
void ObserverTargetFix();
private: