/* =================== CG_TransitionSnapshot The transition point from snap to nextSnap has passed =================== */ static void CG_TransitionSnapshot( void ) { centity_t *cent; snapshot_t *oldFrame; int i; if ( !cg.snap ) { CG_Error( "CG_TransitionSnapshot: NULL cg.snap" ); } if ( !cg.nextSnap ) { CG_Error( "CG_TransitionSnapshot: NULL cg.nextSnap" ); } // execute any server string commands before transitioning entities CG_ExecuteNewServerCommands( cg.nextSnap->serverCommandSequence ); // clear the currentValid flag for all entities in the existing snapshot for ( i = 0 ; i < cg.snap->numEntities ; i++ ) { cent = &cg_entities[ cg.snap->entities[ i ].number ]; cent->currentValid = qfalse; } // move nextSnap to snap and do the transitions oldFrame = cg.snap; cg.snap = cg.nextSnap; BG_PlayerStateToEntityState( &cg.snap->ps, &cg_entities[ cg.snap->ps.clientNum ].currentState, qfalse ); cg_entities[ cg.snap->ps.clientNum ].interpolate = qfalse; for ( i = 0 ; i < cg.snap->numEntities ; i++ ) { cent = &cg_entities[ cg.snap->entities[ i ].number ]; CG_TransitionEntity( cent ); // remember time of snapshot this entity was last updated in cent->snapShotTime = cg.snap->serverTime; } cg.nextSnap = NULL; // check for playerstate transition events if ( oldFrame ) { playerState_t *ops, *ps; ops = &oldFrame->ps; ps = &cg.snap->ps; // teleporting checks are irrespective of prediction if ( ( ps->eFlags ^ ops->eFlags ) & EF_TELEPORT_BIT ) { cg.thisFrameTeleport = qtrue; // will be cleared by prediction code } // if we are not doing client side movement prediction for any // reason, then the client events and view changes will be issued now if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) || cg_nopredict.integer || cg_synchronousClients.integer ) { CG_TransitionPlayerState( ps, ops ); } } }
/* =================== CG_TransitionSnapshot The transition point from snap to nextSnap has passed =================== */ void CG_TransitionSnapshot( void ) { centity_t *cent; snapshot_t *oldFrame; int i; if ( !cg.snap ) { CG_Error( "CG_TransitionSnapshot: NULL cg.snap" ); } if ( !cg.nextSnap ) { CG_Error( "CG_TransitionSnapshot: NULL cg.nextSnap" ); } // execute any server string commands before transitioning entities CG_ExecuteNewServerCommands( cg.nextSnap->serverCommandSequence ); // clear the currentValid flag for all entities in the existing snapshot for ( i = 0 ; i < cg.snap->numEntities ; i++ ) { cent = &cg_entities[ cg.snap->entities[ i ].number ]; cent->currentValid = qfalse; } // move nextSnap to snap and do the transitions oldFrame = cg.snap; cg.snap = cg.nextSnap; // sort out solid entities //CG_BuildSolidList(); for ( i = 0 ; i < cg.snap->numEntities ; i++ ) { if ( 1 )//cg.snap->entities[ i ].number != 0 ) // I guess the player adds his/her events elsewhere, so doing this also gives us double events for the player! { cent = &cg_entities[ cg.snap->entities[ i ].number ]; CG_TransitionEntity( cent ); } } cg.nextSnap = NULL; // check for playerstate transition events if ( oldFrame ) { // if we are not doing client side movement prediction for any // reason, then the client events and view changes will be issued now if ( cg_timescale.value >= 1.0f ) { CG_TransitionPlayerState( &cg.snap->ps, &oldFrame->ps ); } } }
/* =================== CG_TransitionSnapshot The transition point from snap to nextSnap has passed =================== */ static void CG_TransitionSnapshot( void ) { centity_t *cent; snapshot_t *oldFrame; int i, id; if ( !cg.snap ) { CG_Error( "CG_TransitionSnapshot: NULL cg.snap" ); } if ( !cg.nextSnap ) { CG_Error( "CG_TransitionSnapshot: NULL cg.nextSnap" ); } // execute any server string commands before transitioning entities CG_ExecuteNewServerCommands( cg.nextSnap->serverCommandSequence ); // if we had a map_restart, set everthing with initial if ( !(cg.snap) || !(cg.nextSnap) ) { return; } // rain - I hate doing things like this for enums. Oh well. memset(&oldValid, 0, sizeof(oldValid)); // clear the currentValid flag for all entities in the existing snapshot for ( i = 0 ; i < cg.snap->numEntities ; i++ ) { cent = &cg_entities[ cg.snap->entities[ i ].number ]; cent->currentValid = qfalse; oldValid[cg.snap->entities[i].number] = qtrue; } // OSP -- check for MV updates from new snapshot info #ifdef MV_SUPPORT if(cg.snap->ps.powerups[PW_MVCLIENTLIST] != cg.mvClientList) { CG_mvProcessClientList(); } #endif // move nextSnap to snap and do the transitions oldFrame = cg.snap; cg.snap = cg.nextSnap; if( cg.snap->ps.clientNum == cg.clientNum ) { if( cg.xp < cg.snap->ps.stats[STAT_XP] ) { cg.xpChangeTime = cg.time; } cg.xp = cg.snap->ps.stats[STAT_XP]; } BG_PlayerStateToEntityState( &cg.snap->ps, &cg_entities[ cg.snap->ps.clientNum ].currentState, qfalse ); cg_entities[ cg.snap->ps.clientNum ].interpolate = qfalse; for ( i = 0 ; i < cg.snap->numEntities ; i++ ) { id = cg.snap->entities[ i ].number; CG_TransitionEntity( &cg_entities[ id ] ); // rain - #374 - ent doesn't exist in this frame, reset it. // this is to fix the silent landmines bug, which is caused // by a stale miscTime in the cent if (cg_entities[id].currentValid == qfalse && oldValid[id] == qtrue) { CG_ResetEntity(&cg_entities[id]); } if(cg.mvTotalClients > 0 && CG_mvMergedClientLocate(id)) { CG_mvUpdateClientInfo(id); } } if(cg.mvTotalClients > 0) { CG_mvTransitionPlayerState(&cg.snap->ps); } cg.nextSnap = NULL; // check for playerstate transition events if ( oldFrame ) { playerState_t *ops, *ps; ops = &oldFrame->ps; ps = &cg.snap->ps; // teleporting checks are irrespective of prediction if ( ( ps->eFlags ^ ops->eFlags ) & EF_TELEPORT_BIT ) { cg.thisFrameTeleport = qtrue; // will be cleared by prediction code } // if we are not doing client side movement prediction for any // reason, then the client events and view changes will be issued now if ( cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) || cg_nopredict.integer #ifdef ALLOW_GSYNC || cg_synchronousClients.integer #endif // ALLOW_GSYNC ) { CG_TransitionPlayerState( ps, ops ); } } }
/* =================== CG_TransitionSnapshot The transition point from snap to nextSnap has passed =================== */ static void CG_TransitionSnapshot(void) { snapshot_t *oldFrame; int i; if (!cg.snap) { CG_Error("CG_TransitionSnapshot: NULL cg.snap"); } if (!cg.nextSnap) { CG_Error("CG_TransitionSnapshot: NULL cg.nextSnap"); } // execute any server string commands before transitioning entities CG_ExecuteNewServerCommands(cg.nextSnap->serverCommandSequence); // if we had a map_restart, set everthing with initial if (!cg.snap || !cg.nextSnap) { return; } // rain - I hate doing things like this for enums. Oh well. memset(&oldValid, 0, sizeof (oldValid)); // clear the currentValid flag for all entities in the existing snapshot for (i = 0 ; i < cg.snap->numEntities ; ++i) { centity_t *cent = &cg_entities[cg.snap->entities[i].number]; cent->currentValid = qfalse; oldValid[cg.snap->entities[i].number] = qtrue; } // move nextSnap to snap and do the transitions oldFrame = cg.snap; cg.snap = cg.nextSnap; BG_PlayerStateToEntityState(&cg.snap->ps, &cg_entities[cg.snap->ps.clientNum].currentState, qfalse); cg_entities[cg.snap->ps.clientNum].interpolate = qfalse; for (i = 0 ; i < cg.snap->numEntities ; ++i) { int id = cg.snap->entities[i].number; CG_TransitionEntity(&cg_entities[id]); // rain - #374 - ent doesn't exist in this frame, reset it. // this is to fix the silent landmines bug, which is caused // by a stale miscTime in the cent if (cg_entities[id].currentValid == qfalse && oldValid[id] == qtrue) { CG_ResetEntity(&cg_entities[id]); } } cg.nextSnap = NULL; // check for playerstate transition events if (oldFrame) { playerState_t *ops, *ps; ops = &oldFrame->ps; ps = &cg.snap->ps; // teleporting checks are irrespective of prediction if ((ps->eFlags ^ ops->eFlags) & EF_TELEPORT_BIT) { cg.thisFrameTeleport = qtrue; // will be cleared by prediction code } // if we are not doing client side movement prediction for any // reason, then the client events and view changes will be issued now if (cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) || cg_nopredict.integer) { CG_TransitionPlayerState(ps, ops); } } }
/* =================== CG_TransitionSnapshot The transition point from snap to nextSnap has passed =================== */ static void CG_TransitionSnapshot() { centity_t *cent; snapshot_t *oldFrame; int oldWeapon; if ( !cg.snap ) { Sys::Drop( "CG_TransitionSnapshot: NULL cg.snap" ); } if ( !cg.nextSnap ) { Sys::Drop( "CG_TransitionSnapshot: NULL cg.nextSnap" ); } // execute any server string commands before transitioning entities CG_ExecuteServerCommands( cg.nextSnap ); // clear the currentValid flag for all entities in the existing snapshot for ( unsigned i = 0; i < cg.snap->entities.size(); i++ ) { cent = &cg_entities[ cg.snap->entities[ i ].number ]; cent->currentValid = false; } // move nextSnap to snap and do the transitions oldFrame = cg.snap; cg.snap = cg.nextSnap; // Need to store the previous weapon because BG_PlayerStateToEntityState might change it // so the CG_OnPlayerWeaponChange callback is never called oldWeapon = oldFrame->ps.weapon; BG_PlayerStateToEntityState( &cg.snap->ps, &cg_entities[ cg.snap->ps.clientNum ].currentState, false ); cg_entities[ cg.snap->ps.clientNum ].interpolate = false; for ( unsigned i = 0; i < cg.snap->entities.size(); i++ ) { cent = &cg_entities[ cg.snap->entities[ i ].number ]; CG_TransitionEntity( cent ); // remember time of snapshot this entity was last updated in cent->snapShotTime = cg.snap->serverTime; } cg.nextSnap = nullptr; // check for playerstate transition events playerState_t *ops = &oldFrame->ps, *ps = &cg.snap->ps; // teleporting checks are irrespective of prediction if ((ps->eFlags ^ ops->eFlags) & EF_TELEPORT_BIT) { cg.thisFrameTeleport = true; // will be cleared by prediction code } // if we are not doing client side movement prediction for any // reason, then the client events and view changes will be issued now if (cg.demoPlayback || (cg.snap->ps.pm_flags & PMF_FOLLOW) || cg_nopredict.integer || cg.pmoveParams.synchronous) { CG_TransitionPlayerState(ps, ops); } // Callbacks for changes in playerState like weapon/class/team if (oldWeapon != ps->weapon) { CG_OnPlayerWeaponChange(); } if (ops->stats[STAT_ITEMS] != ps->stats[STAT_ITEMS]) { CG_OnPlayerUpgradeChange(); } }
/* =================== CG_TransitionSnapshot The transition point from snap to nextSnap has passed =================== */ static void CG_TransitionSnapshot( void ) { centity_t *cent; snapshot_t *oldFrame; int i; server_sound_t *snd; if ( !cg.snap ) { CG_Error( "CG_TransitionSnapshot: NULL cg.snap" ); } if ( !cg.nextSnap ) { CG_Error( "CG_TransitionSnapshot: NULL cg.nextSnap" ); } // execute any server string commands before transitioning entities CG_ExecuteNewServerCommands( cg.nextSnap->serverCommandSequence ); // if we had a map_restart, set everthing with initial if ( !cg.snap ) { } // clear the currentValid flag for all entities in the existing snapshot for ( i = 0 ; i < cg.snap->numEntities ; i++ ) { cent = &cg_entities[ cg.snap->entities[ i ].number ]; cent->currentValid = qfalse; } // move nextSnap to snap and do the transitions oldFrame = cg.snap; cg.snap = cg.nextSnap; BG_PlayerStateToEntityState( &cg.snap->ps, &cg_entities[ cg.snap->ps.clientNum ].currentState, qfalse ); cg_entities[ cg.snap->ps.clientNum ].interpolate = qfalse; for ( i = 0 ; i < cg.snap->numEntities ; i++ ) { cent = &cg_entities[ cg.snap->entities[ i ].number ]; CG_TransitionEntity( cent ); // remember time of snapshot this entity was last updated in cent->snapShotTime = cg.snap->serverTime; } for ( i=0;i<cg.snap->number_of_sounds;i++ ) { snd = &cg.snap->sounds[i]; if ( snd->sound_index == 0 ) // wombat: we get these sometimes, no clue why continue; if (snd->stop_flag) { trap_S_StopLoopingSound( snd->entity_number ); } else { trap_S_StartSound( snd->origin, snd->entity_number, snd->channel, cgs.gameSounds[snd->sound_index] ); } } cg.nextSnap = NULL; // check for playerstate transition events if ( oldFrame ) { playerState_t *ops, *ps; ops = &oldFrame->ps; ps = &cg.snap->ps; // teleporting checks are irrespective of prediction //if ( ( ps->eFlags ^ ops->eFlags ) & EF_TELEPORT_BIT ) { // cg.thisFrameTeleport = qtrue; // will be cleared by prediction code //} // if we are not doing client side movement prediction for any // reason, then the client events and view changes will be issued now if ( cg.demoPlayback /*|| (cg.snap->ps.pm_flags & PMF_FOLLOW)*/ || cg_nopredict.integer || cg_synchronousClients.integer ) { CG_TransitionPlayerState( ps, ops ); } } }