diff options
Diffstat (limited to 'src/cgame')
-rw-r--r-- | src/cgame/cg_local.h | 3 | ||||
-rw-r--r-- | src/cgame/cg_tutorial.c | 11 | ||||
-rw-r--r-- | src/cgame/cg_view.c | 56 |
3 files changed, 62 insertions, 8 deletions
diff --git a/src/cgame/cg_local.h b/src/cgame/cg_local.h index 73933525..87911919 100644 --- a/src/cgame/cg_local.h +++ b/src/cgame/cg_local.h @@ -1100,6 +1100,9 @@ typedef struct vec3_t kick_angles; // weapon kicks vec3_t kick_origin; + + qboolean thirdPersonFollow; + // temp working variables for player view float bobfracsin; int bobcycle; diff --git a/src/cgame/cg_tutorial.c b/src/cgame/cg_tutorial.c index 4f4608a0..77d0d8fb 100644 --- a/src/cgame/cg_tutorial.c +++ b/src/cgame/cg_tutorial.c @@ -574,9 +574,14 @@ static void CG_SpectatorText( char *text, playerState_t *ps ) if( ps->pm_flags & PMF_FOLLOW ) { - Q_strcat( text, MAX_TUTORIAL_TEXT, - va( "Press %s to stop following\n", - CG_KeyNameForCommand( "+button2" ) ) ); + if( !cg.thirdPersonFollow ) + Q_strcat( text, MAX_TUTORIAL_TEXT, + va( "Press %s to switch to third-person spectator mode\n", + CG_KeyNameForCommand( "+button2" ) ) ); + else + Q_strcat( text, MAX_TUTORIAL_TEXT, + va( "Press %s to return to free spectator mode\n", + CG_KeyNameForCommand( "+button2" ) ) ); Q_strcat( text, MAX_TUTORIAL_TEXT, va( "Press %s or ", diff --git a/src/cgame/cg_view.c b/src/cgame/cg_view.c index 7d4693a8..3e873d9d 100644 --- a/src/cgame/cg_view.c +++ b/src/cgame/cg_view.c @@ -277,6 +277,10 @@ static void CG_OffsetThirdPersonView( void ) float focusDist; float forwardScale, sideScale; vec3_t surfNormal; + float angleOffsets[3]; + usercmd_t cmd; + int cmdNum; + int i; BG_GetClientNormal( &cg.predictedPlayerState, surfNormal ); @@ -284,6 +288,9 @@ static void CG_OffsetThirdPersonView( void ) VectorCopy( cg.refdefViewAngles, focusAngles ); + cmdNum = trap_GetCurrentCmdNumber(); + trap_GetUserCmd( cmdNum, &cmd ); + // if dead, look at killer if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 ) { @@ -306,8 +313,24 @@ static void CG_OffsetThirdPersonView( void ) AngleVectors( cg.refdefViewAngles, forward, right, up ); - forwardScale = cos( cg_thirdPersonAngle.value / 180 * M_PI ); - sideScale = sin( cg_thirdPersonAngle.value / 180 * M_PI ); + for( i = 0; i < 3; i++ ) + { + if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) + angleOffsets[ i ] = SHORT2ANGLE(cmd.angles[ i ]); + else + angleOffsets[ i ] = 0; + + if( i == YAW ) + angleOffsets[ i ] += cg_thirdPersonAngle.value; + + while( angleOffsets[ i ] > 180.0f ) + angleOffsets[ i ] -= 360.0f; + while( angleOffsets[ i ] < -180.0f ) + angleOffsets[ i ] += 360.0f; + } + + forwardScale = cos( angleOffsets[ YAW ] / 180 * M_PI ); + sideScale = sin( angleOffsets[ YAW ] / 180 * M_PI ); VectorMA( view, -cg_thirdPersonRange.value * forwardScale, forward, view ); VectorMA( view, -cg_thirdPersonRange.value * sideScale, right, view ); @@ -338,8 +361,11 @@ static void CG_OffsetThirdPersonView( void ) if ( focusDist < 1 ) { focusDist = 1; // should never happen } - cg.refdefViewAngles[ PITCH ] = -180 / M_PI * atan2( focusPoint[ 2 ], focusDist ); - cg.refdefViewAngles[ YAW ] -= cg_thirdPersonAngle.value; + + cg.refdefViewAngles[ PITCH ] = -180 / M_PI * atan2( focusPoint[ 2 ], focusDist ) + + angleOffsets[ PITCH ]; + + cg.refdefViewAngles[ YAW ] -= angleOffsets[ YAW ]; } @@ -685,10 +711,29 @@ static int CG_CalcFov( void ) int inwater; int attribFov; usercmd_t cmd; + usercmd_t oldcmd; int cmdNum; cmdNum = trap_GetCurrentCmdNumber( ); trap_GetUserCmd( cmdNum, &cmd ); + trap_GetUserCmd( cmdNum - 1, &oldcmd ); + + // switch follow modes if necessary: cycle between free -> follow -> third-person follow + if( cmd.buttons & BUTTON_USE_HOLDABLE && !( oldcmd.buttons & BUTTON_USE_HOLDABLE ) ) + { + if ( cg.snap->ps.pm_flags & PMF_FOLLOW ) + { + if( !cg.thirdPersonFollow ) + cg.thirdPersonFollow = qtrue; + else + { + cg.thirdPersonFollow = qfalse; + trap_SendClientCommand( "follow\n" ); + } + } + else if ( cg.snap->ps.persistant[ PERS_SPECSTATE ] != SPECTATOR_NOT ) + trap_SendClientCommand( "follow\n" ); + } if( cg.predictedPlayerState.pm_type == PM_INTERMISSION || ( cg.snap->ps.persistant[ PERS_SPECSTATE ] != SPECTATOR_NOT ) ) @@ -1232,7 +1277,8 @@ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demo CG_PredictPlayerState( ); // decide on third person view - cg.renderingThirdPerson = cg_thirdPerson.integer || ( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 ); + cg.renderingThirdPerson = ( cg_thirdPerson.integer || ( cg.snap->ps.stats[ STAT_HEALTH ] <= 0 ) || + ( cg.thirdPersonFollow ) ); // build cg.refdef inwater = CG_CalcViewValues( ); |