summaryrefslogtreecommitdiff
path: root/src/cgame/cg_predict.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cgame/cg_predict.c')
-rw-r--r--src/cgame/cg_predict.c384
1 files changed, 180 insertions, 204 deletions
diff --git a/src/cgame/cg_predict.c b/src/cgame/cg_predict.c
index d28c9ba6..fabe1065 100644
--- a/src/cgame/cg_predict.c
+++ b/src/cgame/cg_predict.c
@@ -36,33 +36,36 @@ of the entities that are actually solid, to make for more
efficient collision detection
====================
*/
-void CG_BuildSolidList( void ) {
- int i;
- centity_t *cent;
- snapshot_t *snap;
+void CG_BuildSolidList( void )
+{
+ int i;
+ centity_t *cent;
+ snapshot_t *snap;
entityState_t *ent;
cg_numSolidEntities = 0;
cg_numTriggerEntities = 0;
- if ( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport ) {
+ if( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport )
snap = cg.nextSnap;
- } else {
+ else
snap = cg.snap;
- }
- for ( i = 0 ; i < snap->numEntities ; i++ ) {
+ for( i = 0; i < snap->numEntities; i++ )
+ {
cent = &cg_entities[ snap->entities[ i ].number ];
ent = &cent->currentState;
- if ( ent->eType == ET_ITEM || ent->eType == ET_PUSH_TRIGGER || ent->eType == ET_TELEPORT_TRIGGER ) {
- cg_triggerEntities[cg_numTriggerEntities] = cent;
+ if( ent->eType == ET_ITEM || ent->eType == ET_PUSH_TRIGGER || ent->eType == ET_TELEPORT_TRIGGER )
+ {
+ cg_triggerEntities[ cg_numTriggerEntities ] = cent;
cg_numTriggerEntities++;
continue;
}
- if ( cent->nextState.solid ) {
- cg_solidEntities[cg_numSolidEntities] = cent;
+ if( cent->nextState.solid )
+ {
+ cg_solidEntities[ cg_numSolidEntities ] = cent;
cg_numSolidEntities++;
continue;
}
@@ -76,38 +79,42 @@ CG_ClipMoveToEntities
====================
*/
static void CG_ClipMoveToEntities ( const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
- int skipNumber, int mask, trace_t *tr, qboolean capsule ) {
- int i, x, zd, zu;
- trace_t trace;
+ int skipNumber, int mask, trace_t *tr, qboolean capsule )
+{
+ int i, x, zd, zu;
+ trace_t trace;
entityState_t *ent;
clipHandle_t cmodel;
- vec3_t bmins, bmaxs;
- vec3_t origin, angles;
- centity_t *cent;
+ vec3_t bmins, bmaxs;
+ vec3_t origin, angles;
+ centity_t *cent;
- for ( i = 0 ; i < cg_numSolidEntities ; i++ ) {
+ for( i = 0; i < cg_numSolidEntities; i++ )
+ {
cent = cg_solidEntities[ i ];
ent = &cent->currentState;
- if ( ent->number == skipNumber ) {
+ if( ent->number == skipNumber )
continue;
- }
- if ( ent->solid == SOLID_BMODEL ) {
+ if( ent->solid == SOLID_BMODEL )
+ {
// special value for bmodel
cmodel = trap_CM_InlineModel( ent->modelindex );
VectorCopy( cent->lerpAngles, angles );
BG_EvaluateTrajectory( &cent->currentState.pos, cg.physicsTime, origin );
- } else {
+ }
+ else
+ {
// encoded bbox
- x = (ent->solid & 255);
- zd = ((ent->solid>>8) & 255);
- zu = ((ent->solid>>16) & 255) - 32;
+ x = ( ent->solid & 255 );
+ zd = ( ( ent->solid >> 8 ) & 255 );
+ zu = ( ( ent->solid >> 16 ) & 255 ) - 32;
- bmins[0] = bmins[1] = -x;
- bmaxs[0] = bmaxs[1] = x;
- bmins[2] = -zd;
- bmaxs[2] = zu;
+ bmins[ 0 ] = bmins[ 1 ] = -x;
+ bmaxs[ 0 ] = bmaxs[ 1 ] = x;
+ bmins[ 2 ] = -zd;
+ bmaxs[ 2 ] = zu;
cmodel = trap_CM_TempBoxModel( bmins, bmaxs );
VectorCopy( vec3_origin, angles );
@@ -118,23 +125,24 @@ static void CG_ClipMoveToEntities ( const vec3_t start, const vec3_t mins, const
if( capsule )
{
trap_CM_TransformedCapsuleTrace ( &trace, start, end,
- mins, maxs, cmodel, mask, origin, angles);
- }
+ mins, maxs, cmodel, mask, origin, angles );
+ }
else
{
trap_CM_TransformedBoxTrace ( &trace, start, end,
- mins, maxs, cmodel, mask, origin, angles);
+ mins, maxs, cmodel, mask, origin, angles );
}
- if (trace.allsolid || trace.fraction < tr->fraction) {
+ if( trace.allsolid || trace.fraction < tr->fraction )
+ {
trace.entityNum = ent->number;
*tr = trace;
- } else if (trace.startsolid) {
- tr->startsolid = qtrue;
}
- if ( tr->allsolid ) {
+ else if( trace.startsolid )
+ tr->startsolid = qtrue;
+
+ if( tr->allsolid )
return;
- }
}
}
@@ -144,13 +152,14 @@ CG_Trace
================
*/
void CG_Trace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
- int skipNumber, int mask ) {
+ int skipNumber, int mask )
+{
trace_t t;
- trap_CM_BoxTrace ( &t, start, end, mins, maxs, 0, mask);
+ trap_CM_BoxTrace( &t, start, end, mins, maxs, 0, mask );
t.entityNum = t.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE;
// check all other solid models
- CG_ClipMoveToEntities (start, mins, maxs, end, skipNumber, mask, &t, qfalse);
+ CG_ClipMoveToEntities( start, mins, maxs, end, skipNumber, mask, &t, qfalse );
*result = t;
}
@@ -161,13 +170,14 @@ CG_CapTrace
================
*/
void CG_CapTrace( trace_t *result, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end,
- int skipNumber, int mask ) {
+ int skipNumber, int mask )
+{
trace_t t;
- trap_CM_CapsuleTrace ( &t, start, end, mins, maxs, 0, mask);
+ trap_CM_CapsuleTrace( &t, start, end, mins, maxs, 0, mask );
t.entityNum = t.fraction != 1.0 ? ENTITYNUM_WORLD : ENTITYNUM_NONE;
// check all other solid models
- CG_ClipMoveToEntities (start, mins, maxs, end, skipNumber, mask, &t, qtrue);
+ CG_ClipMoveToEntities( start, mins, maxs, end, skipNumber, mask, &t, qtrue );
*result = t;
}
@@ -219,9 +229,10 @@ Generates cg.predictedPlayerState by interpolating between
cg.snap->player_state and cg.nextFrame->player_state
========================
*/
-static void CG_InterpolatePlayerState( qboolean grabAngles ) {
- float f;
- int i;
+static void CG_InterpolatePlayerState( qboolean grabAngles )
+{
+ float f;
+ int i;
playerState_t *out;
snapshot_t *prev, *next;
@@ -232,84 +243,42 @@ static void CG_InterpolatePlayerState( qboolean grabAngles ) {
*out = cg.snap->ps;
// if we are still allowing local input, short circuit the view angles
- if ( grabAngles ) {
+ if( grabAngles )
+ {
usercmd_t cmd;
int cmdNum;
- cmdNum = trap_GetCurrentCmdNumber();
+ cmdNum = trap_GetCurrentCmdNumber( );
trap_GetUserCmd( cmdNum, &cmd );
PM_UpdateViewAngles( out, &cmd );
}
// if the next frame is a teleport, we can't lerp to it
- if ( cg.nextFrameTeleport ) {
+ if( cg.nextFrameTeleport )
return;
- }
- if ( !next || next->serverTime <= prev->serverTime ) {
+ if( !next || next->serverTime <= prev->serverTime )
return;
- }
f = (float)( cg.time - prev->serverTime ) / ( next->serverTime - prev->serverTime );
i = next->ps.bobCycle;
- if ( i < prev->ps.bobCycle ) {
+ if( i < prev->ps.bobCycle )
i += 256; // handle wraparound
- }
+
out->bobCycle = prev->ps.bobCycle + f * ( i - prev->ps.bobCycle );
- for ( i = 0 ; i < 3 ; i++ ) {
- out->origin[i] = prev->ps.origin[i] + f * (next->ps.origin[i] - prev->ps.origin[i] );
- if ( !grabAngles ) {
- out->viewangles[i] = LerpAngle(
- prev->ps.viewangles[i], next->ps.viewangles[i], f );
- }
- out->velocity[i] = prev->ps.velocity[i] +
- f * (next->ps.velocity[i] - prev->ps.velocity[i] );
- }
-
-}
-
-/*
-===================
-CG_TouchItem
-===================
-*/
-static void CG_TouchItem( centity_t *cent ) {
- gitem_t *item;
- int ammo, clips, maxclips;
-
- BG_unpackAmmoArray( item->giTag, cg.predictedPlayerState.ammo, cg.predictedPlayerState.powerups, &ammo, &clips, &maxclips );
-
- if ( !cg_predictItems.integer ) {
- return;
+ for( i = 0; i < 3; i++ )
+ {
+ out->origin[ i ] = prev->ps.origin[ i ] + f * ( next->ps.origin[ i ] - prev->ps.origin[ i ] );
+
+ if( !grabAngles )
+ out->viewangles[ i ] = LerpAngle( prev->ps.viewangles[ i ], next->ps.viewangles[ i ], f );
+
+ out->velocity[ i ] = prev->ps.velocity[ i ] +
+ f * (next->ps.velocity[ i ] - prev->ps.velocity[ i ] );
}
-/* if ( !BG_PlayerTouchesItem( &cg.predictedPlayerState, &cent->currentState, cg.time ) ) {
- return;
- }*/
-
- // never pick an item up twice in a prediction
- if ( cent->miscTime == cg.time ) {
- return;
- }
-
- // grab it
- BG_AddPredictableEventToPlayerstate( EV_ITEM_PICKUP, cent->currentState.modelindex , &cg.predictedPlayerState);
-
- // remove it from the frame so it won't be drawn
- cent->currentState.eFlags |= EF_NODRAW;
-
- // don't touch it again this prediction
- cent->miscTime = cg.time;
-
- // if its a weapon, give them some predicted ammo so the autoswitch will work
-/* if ( item->giType == IT_WEAPON ) {
- BG_packWeapon( item->giTag, cg.predictedPlayerState.stats );
- if ( ammo == 0 && clips == 0 ) {
- BG_packAmmoArray( item->giTag, cg.predictedPlayerState.ammo, cg.predictedPlayerState.powerups, 1, 0, 0 );
- }
- }*/
}
@@ -320,59 +289,51 @@ CG_TouchTriggerPrediction
Predict push triggers and items
=========================
*/
-static void CG_TouchTriggerPrediction( void ) {
- int i;
- trace_t trace;
+static void CG_TouchTriggerPrediction( void )
+{
+ int i;
+ trace_t trace;
entityState_t *ent;
- clipHandle_t cmodel;
- centity_t *cent;
- qboolean spectator;
+ clipHandle_t cmodel;
+ centity_t *cent;
+ qboolean spectator;
// dead clients don't activate triggers
- if ( cg.predictedPlayerState.stats[STAT_HEALTH] <= 0 ) {
+ if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 )
return;
- }
spectator = ( cg.predictedPlayerState.pm_type == PM_SPECTATOR );
- if ( cg.predictedPlayerState.pm_type != PM_NORMAL && !spectator ) {
+ if( cg.predictedPlayerState.pm_type != PM_NORMAL && !spectator )
return;
- }
- for ( i = 0 ; i < cg_numTriggerEntities ; i++ ) {
+ for( i = 0; i < cg_numTriggerEntities; i++ )
+ {
cent = cg_triggerEntities[ i ];
ent = &cent->currentState;
- if ( ent->eType == ET_ITEM && !spectator ) {
- CG_TouchItem( cent );
+ if( ent->solid != SOLID_BMODEL )
continue;
- }
-
- if ( ent->solid != SOLID_BMODEL ) {
- continue;
- }
cmodel = trap_CM_InlineModel( ent->modelindex );
- if ( !cmodel ) {
+ if( !cmodel )
continue;
- }
trap_CM_BoxTrace( &trace, cg.predictedPlayerState.origin, cg.predictedPlayerState.origin,
- cg_pmove.mins, cg_pmove.maxs, cmodel, -1 );
+ cg_pmove.mins, cg_pmove.maxs, cmodel, -1 );
- if ( !trace.startsolid ) {
+ if( !trace.startsolid )
continue;
- }
- if ( ent->eType == ET_TELEPORT_TRIGGER ) {
+ if( ent->eType == ET_TELEPORT_TRIGGER )
cg.hyperspace = qtrue;
- } else if ( ent->eType == ET_PUSH_TRIGGER ) {
+ else if( ent->eType == ET_PUSH_TRIGGER )
BG_TouchJumpPad( &cg.predictedPlayerState, ent );
- }
}
// if we didn't touch a jump pad this pmove frame
- if ( cg.predictedPlayerState.jumppad_frame != cg.predictedPlayerState.pmove_framecount ) {
+ if( cg.predictedPlayerState.jumppad_frame != cg.predictedPlayerState.pmove_framecount )
+ {
cg.predictedPlayerState.jumppad_frame = 0;
cg.predictedPlayerState.jumppad_ent = 0;
}
@@ -406,7 +367,8 @@ We detect prediction errors and allow them to be decayed off over several frames
to ease the jerk.
=================
*/
-void CG_PredictPlayerState( void ) {
+void CG_PredictPlayerState( void )
+{
int cmdNum, current, i;
playerState_t oldPlayerState;
qboolean moved;
@@ -418,20 +380,23 @@ void CG_PredictPlayerState( void ) {
// if this is the first frame we must guarantee
// predictedPlayerState is valid even if there is some
// other error condition
- if ( !cg.validPPS ) {
+ if( !cg.validPPS )
+ {
cg.validPPS = qtrue;
cg.predictedPlayerState = cg.snap->ps;
}
// demo playback just copies the moves
- if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) ) {
+ if( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) )
+ {
CG_InterpolatePlayerState( qfalse );
return;
}
// non-predicting local movement will grab the latest angles
- if ( cg_nopredict.integer || cg_synchronousClients.integer ) {
+ if( cg_nopredict.integer || cg_synchronousClients.integer )
+ {
CG_InterpolatePlayerState( qtrue );
return;
}
@@ -441,33 +406,33 @@ void CG_PredictPlayerState( void ) {
cg_pmove.trace = CG_Trace;
cg_pmove.pointcontents = CG_PointContents;
- //TA: FIXME BIG NEON SIGN..... COULD MAYBE BE A FIX FOR THAT HACK IN bg_pmove.c.. MAYBE \/
- if ( cg_pmove.ps->pm_type == PM_DEAD ) {
+ if( cg_pmove.ps->pm_type == PM_DEAD )
cg_pmove.tracemask = MASK_PLAYERSOLID & ~CONTENTS_BODY;
- }
- else {
+ else
cg_pmove.tracemask = MASK_PLAYERSOLID;
- }
- if ( cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR ) {
+
+ if( cg.snap->ps.persistant[ PERS_TEAM ] == TEAM_SPECTATOR )
cg_pmove.tracemask &= ~CONTENTS_BODY; // spectators can fly through bodies
- }
+
cg_pmove.noFootsteps = ( cgs.dmflags & DF_NO_FOOTSTEPS ) > 0;
// save the state before the pmove so we can detect transitions
oldPlayerState = cg.predictedPlayerState;
- current = trap_GetCurrentCmdNumber();
+ current = trap_GetCurrentCmdNumber( );
// if we don't have the commands right after the snapshot, we
// can't accurately predict a current position, so just freeze at
// the last good position we had
cmdNum = current - CMD_BACKUP + 1;
trap_GetUserCmd( cmdNum, &oldestCmd );
- if ( oldestCmd.serverTime > cg.snap->ps.commandTime
- && oldestCmd.serverTime < cg.time ) { // special check for map_restart
- if ( cg_showmiss.integer ) {
- CG_Printf ("exceeded PACKET_BACKUP on commands\n");
- }
+
+ if( oldestCmd.serverTime > cg.snap->ps.commandTime &&
+ oldestCmd.serverTime < cg.time )
+ { // special check for map_restart
+ if( cg_showmiss.integer )
+ CG_Printf( "exceeded PACKET_BACKUP on commands\n" );
+
return;
}
@@ -478,92 +443,103 @@ void CG_PredictPlayerState( void ) {
// the server time is beyond our current cg.time,
// because predicted player positions are going to
// be ahead of everything else anyway
- if ( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport ) {
+ if( cg.nextSnap && !cg.nextFrameTeleport && !cg.thisFrameTeleport )
+ {
cg.predictedPlayerState = cg.nextSnap->ps;
cg.physicsTime = cg.nextSnap->serverTime;
- } else {
+ }
+ else
+ {
cg.predictedPlayerState = cg.snap->ps;
cg.physicsTime = cg.snap->serverTime;
}
- if ( pmove_msec.integer < 8 ) {
- trap_Cvar_Set("pmove_msec", "8");
- }
- else if (pmove_msec.integer > 33) {
- trap_Cvar_Set("pmove_msec", "33");
- }
+ if( pmove_msec.integer < 8 )
+ trap_Cvar_Set( "pmove_msec", "8" );
+ else if( pmove_msec.integer > 33 )
+ trap_Cvar_Set( "pmove_msec", "33" );
cg_pmove.pmove_fixed = pmove_fixed.integer;// | cg_pmove_fixed.integer;
cg_pmove.pmove_msec = pmove_msec.integer;
// run cmds
moved = qfalse;
- for ( cmdNum = current - CMD_BACKUP + 1 ; cmdNum <= current ; cmdNum++ ) {
+
+ for( cmdNum = current - CMD_BACKUP + 1; cmdNum <= current; cmdNum++ )
+ {
// get the command
trap_GetUserCmd( cmdNum, &cg_pmove.cmd );
- if ( cg_pmove.pmove_fixed ) {
+ if( cg_pmove.pmove_fixed )
PM_UpdateViewAngles( cg_pmove.ps, &cg_pmove.cmd );
- }
// don't do anything if the time is before the snapshot player time
- if ( cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime ) {
+ if( cg_pmove.cmd.serverTime <= cg.predictedPlayerState.commandTime )
continue;
- }
// don't do anything if the command was from a previous map_restart
- if ( cg_pmove.cmd.serverTime > latestCmd.serverTime ) {
+ if( cg_pmove.cmd.serverTime > latestCmd.serverTime )
continue;
- }
// check for a prediction error from last frame
// on a lan, this will often be the exact value
// from the snapshot, but on a wan we will have
// to predict several commands to get to the point
// we want to compare
- if ( cg.predictedPlayerState.commandTime == oldPlayerState.commandTime ) {
+ if( cg.predictedPlayerState.commandTime == oldPlayerState.commandTime )
+ {
vec3_t delta;
- float len;
+ float len;
- if ( cg.thisFrameTeleport ) {
+ if( cg.thisFrameTeleport )
+ {
// a teleport will not cause an error decay
VectorClear( cg.predictedError );
- if ( cg_showmiss.integer ) {
+
+ if( cg_showmiss.integer )
CG_Printf( "PredictionTeleport\n" );
- }
+
cg.thisFrameTeleport = qfalse;
- } else {
+ }
+ else
+ {
vec3_t adjusted;
CG_AdjustPositionForMover( cg.predictedPlayerState.origin,
cg.predictedPlayerState.groundEntityNum, cg.physicsTime, cg.oldTime, adjusted );
- if ( cg_showmiss.integer ) {
- if (!VectorCompare( oldPlayerState.origin, adjusted )) {
+ if( cg_showmiss.integer )
+ {
+ if( !VectorCompare( oldPlayerState.origin, adjusted ) )
CG_Printf("prediction error\n");
- }
}
+
VectorSubtract( oldPlayerState.origin, adjusted, delta );
len = VectorLength( delta );
- if ( len > 0.1 ) {
- if ( cg_showmiss.integer ) {
- CG_Printf("Prediction miss: %f\n", len);
- }
- if ( cg_errorDecay.integer ) {
+
+ if( len > 0.1 )
+ {
+ if( cg_showmiss.integer )
+ CG_Printf( "Prediction miss: %f\n", len );
+
+ if( cg_errorDecay.integer )
+ {
int t;
float f;
t = cg.time - cg.predictedErrorTime;
f = ( cg_errorDecay.value - t ) / cg_errorDecay.value;
- if ( f < 0 ) {
+
+ if( f < 0 )
f = 0;
- }
- if ( f > 0 && cg_showmiss.integer ) {
- CG_Printf("Double prediction decay: %f\n", f);
- }
+
+ if( f > 0 && cg_showmiss.integer )
+ CG_Printf( "Double prediction decay: %f\n", f );
+
VectorScale( cg.predictedError, f, cg.predictedError );
- } else {
- VectorClear( cg.predictedError );
}
+ else
+ VectorClear( cg.predictedError );
+
VectorAdd( delta, cg.predictedError, cg.predictedError );
cg.predictedErrorTime = cg.oldTime;
}
@@ -575,29 +551,29 @@ void CG_PredictPlayerState( void ) {
for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
cg_pmove.autoWeaponHit[ i ] = qfalse;
- if ( cg_pmove.pmove_fixed ) {
- cg_pmove.cmd.serverTime = ((cg_pmove.cmd.serverTime + pmove_msec.integer-1) / pmove_msec.integer) * pmove_msec.integer;
- }
+ if( cg_pmove.pmove_fixed )
+ cg_pmove.cmd.serverTime = ( ( cg_pmove.cmd.serverTime + pmove_msec.integer - 1 ) /
+ pmove_msec.integer ) * pmove_msec.integer;
- Pmove (&cg_pmove);
+ Pmove( &cg_pmove );
moved = qtrue;
// add push trigger movement effects
- CG_TouchTriggerPrediction();
+ CG_TouchTriggerPrediction( );
// check for predictable events that changed from previous predictions
//CG_CheckChangedPredictableEvents(&cg.predictedPlayerState);
}
- if ( cg_showmiss.integer > 1 ) {
+ if( cg_showmiss.integer > 1 )
CG_Printf( "[%i : %i] ", cg_pmove.cmd.serverTime, cg.time );
- }
- if ( !moved ) {
- if ( cg_showmiss.integer ) {
+ if( !moved )
+ {
+ if( cg_showmiss.integer )
CG_Printf( "not moved\n" );
- }
+
return;
}
@@ -606,21 +582,21 @@ void CG_PredictPlayerState( void ) {
cg.predictedPlayerState.groundEntityNum,
cg.physicsTime, cg.time, cg.predictedPlayerState.origin );
- if ( cg_showmiss.integer ) {
- if (cg.predictedPlayerState.eventSequence > oldPlayerState.eventSequence + MAX_PS_EVENTS) {
- CG_Printf("WARNING: dropped event\n");
- }
+ if( cg_showmiss.integer )
+ {
+ if( cg.predictedPlayerState.eventSequence > oldPlayerState.eventSequence + MAX_PS_EVENTS )
+ CG_Printf( "WARNING: dropped event\n" );
}
// fire events and other transition triggered things
CG_TransitionPlayerState( &cg.predictedPlayerState, &oldPlayerState );
- if ( cg_showmiss.integer ) {
- if (cg.eventSequence > cg.predictedPlayerState.eventSequence) {
- CG_Printf("WARNING: double event\n");
+ if( cg_showmiss.integer )
+ {
+ if( cg.eventSequence > cg.predictedPlayerState.eventSequence )
+ {
+ CG_Printf( "WARNING: double event\n" );
cg.eventSequence = cg.predictedPlayerState.eventSequence;
}
}
}
-
-