From 5097748e7b51a85e46047659a429532793d3fc93 Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Sat, 2 Jul 2005 19:29:17 +0000 Subject: * Fixed the PTRC system interfering with the observer mode * Refactored observer mode code * Fixed poison cloud being distorted in observer mode (by not rendering it) * Fixed walking wall smoothing being distorted in observer mode (by not performing any smoothing) --- src/cgame/cg_view.c | 20 ++++++-- src/game/bg_misc.c | 2 +- src/game/g_active.c | 22 ++------ src/game/g_client.c | 3 +- src/game/g_cmds.c | 142 +++++++++++++++++++++++++--------------------------- src/game/g_combat.c | 12 +++++ src/game/g_local.h | 7 +-- src/ui/ui_shared.h | 3 ++ 8 files changed, 111 insertions(+), 100 deletions(-) (limited to 'src') diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c index e88bb8f8..12772a3d 100644 --- a/src/cgame/cg_view.c +++ b/src/cgame/cg_view.c @@ -577,7 +577,8 @@ static void CG_OffsetFirstPersonView( void ) cg.upMoveTime = cg.time; } - if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED ) + if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED && + !( cg.snap->ps.pm_flags & PMF_FOLLOW ) ) { float fraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 2 * PCLOUD_ROLL_FREQUENCY ); float pitchFraction = sin( ( (float)cg.time / 1000.0f ) * M_PI * 5 * PCLOUD_ROLL_FREQUENCY ); @@ -788,7 +789,8 @@ static int CG_CalcFov( void ) inwater = qfalse; if( cg.predictedPlayerState.stats[ STAT_STATE ] & SS_POISONCLOUDED && - cg.predictedPlayerState.stats[ STAT_HEALTH ] > 0 ) + cg.predictedPlayerState.stats[ STAT_HEALTH ] > 0 && + !( cg.snap->ps.pm_flags & PMF_FOLLOW ) ) { phase = cg.time / 1000.0 * PCLOUD_ZOOM_FREQUENCY * M_PI * 2; v = PCLOUD_ZOOM_AMPLITUDE * sin( phase ); @@ -948,6 +950,12 @@ static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t o qboolean performed = qfalse; vec3_t inAxis[ 3 ], lastAxis[ 3 ], outAxis[ 3 ]; + if( cg.snap->ps.pm_flags & PMF_FOLLOW ) + { + VectorCopy( in, out ); + return; + } + //set surfNormal if( !( ps->stats[ STAT_STATE ] & SS_WALLCLIMBINGCEILING ) ) VectorCopy( ps->grapplePoint, surfNormal ); @@ -990,7 +998,7 @@ static void CG_smoothWWTransitions( playerState_t *ps, const vec3_t in, vec3_t o timeMod = 1.0f; } - + //add the op CG_addSmoothOp( rotAxis, rotAngle, timeMod ); } @@ -1042,6 +1050,12 @@ static void CG_smoothWJTransitions( playerState_t *ps, const vec3_t in, vec3_t o qboolean performed = qfalse; vec3_t inAxis[ 3 ], outAxis[ 3 ]; + if( cg.snap->ps.pm_flags & PMF_FOLLOW ) + { + VectorCopy( in, out ); + return; + } + AnglesToAxis( in, inAxis ); //iterate through ops diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c index 83d509dd..b22a94e8 100644 --- a/src/game/bg_misc.c +++ b/src/game/bg_misc.c @@ -208,7 +208,7 @@ buildableAttributes_t bg_buildableList[ ] = TR_GRAVITY, //trType_t traj; 0.0, //float bounce; TRAPPER_BP, //int buildPoints; - ( 1 << S1 )|( 1 << S2 )|( 1 << S3 ), //int stages + ( 1 << S2 )|( 1 << S3 ), //int stages //NEEDS ADV BUILDER SO S2 AND UP TRAPPER_HEALTH, //int health; TRAPPER_REGEN, //int regenRate; TRAPPER_SPLASHDAMAGE, //int splashDamage; diff --git a/src/game/g_active.c b/src/game/g_active.c index ee5d1aa3..d22a8b2b 100644 --- a/src/game/g_active.c +++ b/src/game/g_active.c @@ -1398,40 +1398,24 @@ SpectatorClientEndFrame void SpectatorClientEndFrame( gentity_t *ent ) { gclient_t *cl; + int clientNum, flags; // if we are doing a chase cam or a remote view, grab the latest info if( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) { - int clientNum, flags; - clientNum = ent->client->sess.spectatorClient; - // team follow1 and team follow2 go to whatever clients are playing - if( clientNum == -1 ) - clientNum = level.follow1; - else if( clientNum == -2 ) - clientNum = level.follow2; - if( clientNum >= 0 ) { cl = &level.clients[ clientNum ]; if( cl->pers.connected == CON_CONNECTED && cl->sess.sessionTeam != TEAM_SPECTATOR ) { - flags = ( cl->ps.eFlags & ~( EF_VOTED | EF_TEAMVOTED ) ) | ( ent->client->ps.eFlags & ( EF_VOTED | EF_TEAMVOTED ) ); + flags = ( cl->ps.eFlags & ~( EF_VOTED | EF_TEAMVOTED ) ) | + ( ent->client->ps.eFlags & ( EF_VOTED | EF_TEAMVOTED ) ); ent->client->ps = cl->ps; ent->client->ps.pm_flags |= PMF_FOLLOW; ent->client->ps.eFlags = flags; - return; - } - else - { - // drop them to free spectators unless they are dedicated camera followers - if( ent->client->sess.spectatorClient >= 0 ) - { - ent->client->sess.spectatorState = SPECTATOR_FREE; - ClientBegin( ent->client - level.clients ); - } } } } diff --git a/src/game/g_client.c b/src/game/g_client.c index 24b7900c..e5c90d70 100644 --- a/src/game/g_client.c +++ b/src/game/g_client.c @@ -1559,7 +1559,8 @@ void ClientDisconnect( int clientNum ) level.clients[ i ].sess.spectatorState == SPECTATOR_FOLLOW && level.clients[ i ].sess.spectatorClient == clientNum ) { - G_StopFollowing( &g_entities[ i ] ); + if( !G_FollowNewClient( &g_entities[ i ], 1 ) ) + G_StopFollowing( &g_entities[ i ] ); } } diff --git a/src/game/g_cmds.c b/src/game/g_cmds.c index 47e5b3ba..619989c7 100644 --- a/src/game/g_cmds.c +++ b/src/game/g_cmds.c @@ -1991,6 +1991,7 @@ void G_StopFollowing( gentity_t *ent ) ent->client->ps.persistant[ PERS_TEAM ] = TEAM_SPECTATOR; ent->client->sess.sessionTeam = TEAM_SPECTATOR; ent->client->sess.spectatorState = SPECTATOR_FREE; + ent->client->sess.spectatorClient = -1; ent->client->ps.pm_flags &= ~PMF_FOLLOW; ent->client->ps.stats[ STAT_STATE ] &= ~SS_WALLCLIMBING; @@ -2002,6 +2003,69 @@ void G_StopFollowing( gentity_t *ent ) ent->client->ps.clientNum = ent - g_entities; } +/* +================= +G_FollowNewClient + +This was a really nice, elegant function. Then I fucked it up. +================= +*/ +qboolean G_FollowNewClient( gentity_t *ent, int dir ) +{ + int clientnum = ent->client->sess.spectatorClient; + int original = clientnum; + qboolean selectAny = qfalse; + + if( dir > 1 ) + dir = 1; + else if( dir < -1 ) + dir = -1; + else if( dir == 0 ) + return qtrue; + + // select any if no target exists + if( clientnum < 0 || clientnum >= level.maxclients ) + { + clientnum = original = 0; + selectAny = qtrue; + } + + do + { + clientnum += dir; + + if( clientnum >= level.maxclients ) + clientnum = 0; + + if( clientnum < 0 ) + clientnum = level.maxclients - 1; + + // avoid selecting existing follow target + if( clientnum == original && !selectAny ) + continue; //effectively break; + + // can't follow self + if( &level.clients[ clientnum ] == ent->client ) + continue; + + // can only follow connected clients + if( level.clients[ clientnum ].pers.connected != CON_CONNECTED ) + continue; + + // can't follow another spectator + if( level.clients[ clientnum ].sess.sessionTeam == TEAM_SPECTATOR ) + continue; + + // this is good, we can use it + ent->client->sess.spectatorClient = clientnum; + ent->client->sess.spectatorState = SPECTATOR_FOLLOW; + return qtrue; + + } while( clientnum != original ); + + return qfalse; +} + /* ================= Cmd_Follow_f @@ -2016,43 +2080,10 @@ void Cmd_Follow_f( gentity_t *ent, qboolean toggle ) { if( ent->client->sess.spectatorState == SPECTATOR_FOLLOW ) G_StopFollowing( ent ); - else - { - //follow somebody, anybody - int clientnum = ent->client->sess.spectatorClient; - int original = clientnum; - - do - { - clientnum++; - - if( clientnum >= level.maxclients ) - clientnum = 0; - - if( clientnum < 0 ) - clientnum = level.maxclients - 1; - - // can't follow self - if( &level.clients[ clientnum ] == ent->client ) - continue; - - // can only follow connected clients - if( level.clients[ clientnum ].pers.connected != CON_CONNECTED ) - continue; - - // can't follow another spectator - if( level.clients[ clientnum ].sess.sessionTeam == TEAM_SPECTATOR ) - continue; - - // this is good, we can use it - ent->client->sess.spectatorClient = clientnum; - ent->client->sess.spectatorState = SPECTATOR_FOLLOW; - break; - - } while( clientnum != original ); - } + else if( ent->client->sess.spectatorState == SPECTATOR_FREE ) + G_FollowNewClient( ent, 1 ); } - else + else if( ent->client->sess.spectatorState == SPECTATOR_FREE ) { trap_Argv( 1, arg, sizeof( arg ) ); i = G_ClientNumberFromString( ent, arg ); @@ -2084,49 +2115,14 @@ Cmd_FollowCycle_f */ void Cmd_FollowCycle_f( gentity_t *ent, int dir ) { - int clientnum; - int original; - - // first set them to spectator + // won't work unless spectating if( ent->client->sess.spectatorState == SPECTATOR_NOT ) return; if( dir != 1 && dir != -1 ) G_Error( "Cmd_FollowCycle_f: bad dir %i", dir ); - clientnum = ent->client->sess.spectatorClient; - original = clientnum; - - do - { - clientnum += dir; - - if( clientnum >= level.maxclients ) - clientnum = 0; - - if( clientnum < 0 ) - clientnum = level.maxclients - 1; - - // can't follow self - if( &level.clients[ clientnum ] == ent->client ) - continue; - - // can only follow connected clients - if( level.clients[ clientnum ].pers.connected != CON_CONNECTED ) - continue; - - // can't follow another spectator - if( level.clients[ clientnum ].sess.sessionTeam == TEAM_SPECTATOR ) - continue; - - // this is good, we can use it - ent->client->sess.spectatorClient = clientnum; - ent->client->sess.spectatorState = SPECTATOR_FOLLOW; - return; - - } while( clientnum != original ); - - // leave it where it was + G_FollowNewClient( ent, dir ); } /* diff --git a/src/game/g_combat.c b/src/game/g_combat.c index 0bf8b1b8..515ecfe7 100644 --- a/src/game/g_combat.c +++ b/src/game/g_combat.c @@ -163,6 +163,18 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int if( level.intermissiontime ) return; + // stop any following clients + for( i = 0; i < level.maxclients; i++ ) + { + if( level.clients[ i ].sess.sessionTeam == TEAM_SPECTATOR && + level.clients[ i ].sess.spectatorState == SPECTATOR_FOLLOW && + level.clients[ i ].sess.spectatorClient == self->client->ps.clientNum ) + { + if( !G_FollowNewClient( &g_entities[ i ], 1 ) ) + G_StopFollowing( &g_entities[ i ] ); + } + } + self->client->ps.pm_type = PM_DEAD; self->suicideTime = 0; diff --git a/src/game/g_local.h b/src/game/g_local.h index 00b38bbe..2db714f2 100644 --- a/src/game/g_local.h +++ b/src/game/g_local.h @@ -600,9 +600,10 @@ char *G_NewString( const char *string ); // // g_cmds.c // -void Cmd_Score_f( gentity_t *ent ); -void G_StopFollowing( gentity_t *ent ); -void Cmd_Follow_f( gentity_t *ent, qboolean toggle ); +void Cmd_Score_f( gentity_t *ent ); +void G_StopFollowing( gentity_t *ent ); +qboolean G_FollowNewClient( gentity_t *ent, int dir ); +void Cmd_Follow_f( gentity_t *ent, qboolean toggle ); // // g_physics.c diff --git a/src/ui/ui_shared.h b/src/ui/ui_shared.h index 51f6eac0..d0864c02 100644 --- a/src/ui/ui_shared.h +++ b/src/ui/ui_shared.h @@ -443,4 +443,7 @@ int trap_PC_FreeSource( int handle ); int trap_PC_ReadToken( int handle, pc_token_t *pc_token ); int trap_PC_SourceFileAndLine( int handle, char *filename, int *line ); +void BindingFromName( const char *cvar ); +extern char g_nameBind1[ 32 ]; +extern char g_nameBind2[ 32 ]; #endif -- cgit