//----------------------------------------------------------------------------- // Purpose: Runs movement commands for the player // Input : *player - // *ucmd - // *moveHelper - // Output : void CPlayerMove::RunCommand //----------------------------------------------------------------------------- void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *moveHelper ) { StartCommand( player, ucmd ); // Set globals appropriately gpGlobals->curtime = player->m_nTickBase * TICK_INTERVAL; gpGlobals->frametime = player->m_bGamePaused ? 0 : TICK_INTERVAL; if ( player->m_bGamePaused ) { // If no clipping and cheats enabled and noclipduring game enabled, then leave // forwardmove and angles stuff in usercmd if ( player->GetMoveType() == MOVETYPE_NOCLIP && sv_cheats->GetBool() && sv_noclipduringpause.GetBool() ) { gpGlobals->frametime = TICK_INTERVAL; } } /* // TODO: We can check whether the player is sending more commands than elapsed real time cmdtimeremaining -= ucmd->msec; if ( cmdtimeremaining < 0 ) { // return; } */ IGameSystem::FrameUpdatePrePlayerRunCommandAllSystems( player, ucmd ); // Do weapon selection if ( ucmd->weaponselect != 0 ) { CBaseCombatWeapon *weapon = dynamic_cast< CBaseCombatWeapon * >( CBaseEntity::Instance( ucmd->weaponselect ) ); if ( weapon ) { VPROF( "player->SelectItem()" ); player->SelectItem( weapon->GetName(), ucmd->weaponsubtype ); } } IServerVehicle *pVehicle = player->GetVehicle(); // Latch in impulse. if ( ucmd->impulse ) { // Discard impulse commands unless the vehicle allows them. // FIXME: UsingStandardWeapons seems like a bad filter for this. The flashlight is an impulse command, for example. if ( !pVehicle || player->UsingStandardWeaponsInVehicle() ) { player->m_nImpulse = ucmd->impulse; } } // Update player input button states VPROF_SCOPE_BEGIN( "player->UpdateButtonState" ); player->UpdateButtonState( ucmd->buttons ); VPROF_SCOPE_END(); CheckMovingGround( player, TICK_INTERVAL ); g_pMoveData->m_vecOldAngles = player->pl.v_angle; // Copy from command to player unless game .dll has set angle using fixangle if ( player->pl.fixangle == FIXANGLE_NONE ) { player->pl.v_angle = ucmd->viewangles; } else if( player->pl.fixangle == FIXANGLE_RELATIVE ) { player->pl.v_angle = ucmd->viewangles + player->pl.anglechange; } // Call standard client pre-think RunPreThink( player ); // Call Think if one is set RunThink( player, TICK_INTERVAL ); // Setup input. SetupMove( player, ucmd, moveHelper, g_pMoveData ); // Let the game do the movement. if ( !pVehicle ) { VPROF( "g_pGameMovement->ProcessMovement()" ); Assert( g_pGameMovement ); g_pGameMovement->ProcessMovement( player, g_pMoveData ); } else { VPROF( "pVehicle->ProcessMovement()" ); pVehicle->ProcessMovement( player, g_pMoveData ); } // Copy output FinishMove( player, ucmd, g_pMoveData ); // Let server invoke any needed impact functions VPROF_SCOPE_BEGIN( "moveHelper->ProcessImpacts" ); moveHelper->ProcessImpacts(); VPROF_SCOPE_END(); RunPostThink( player ); FinishCommand( player ); // Let time pass player->m_nTickBase++; }
//----------------------------------------------------------------------------- // Purpose: Runs movement commands for the player // Input : *player - // *ucmd - // *moveHelper - // Output : void CPlayerMove::RunCommand //----------------------------------------------------------------------------- void CPlayerMove::RunCommand ( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *moveHelper ) { const float playerCurTime = player->m_nTickBase * TICK_INTERVAL; const float playerFrameTime = player->m_bGamePaused ? 0 : TICK_INTERVAL; const float flTimeAllowedForProcessing = player->ConsumeMovementTimeForUserCmdProcessing( playerFrameTime ); if ( !player->IsBot() && ( flTimeAllowedForProcessing < playerFrameTime ) ) { // Make sure that the activity in command is erased because player cheated or dropped too many packets double dblWarningFrequencyThrottle = sv_maxusrcmdprocessticks_warning.GetFloat(); if ( dblWarningFrequencyThrottle >= 0 ) { static double s_dblLastWarningTime = 0; double dblTimeNow = Plat_FloatTime(); if ( !s_dblLastWarningTime || ( dblTimeNow - s_dblLastWarningTime >= dblWarningFrequencyThrottle ) ) { s_dblLastWarningTime = dblTimeNow; Warning( "sv_maxusrcmdprocessticks_warning at server tick %u: Ignored client %s usrcmd (%.6f < %.6f)!\n", gpGlobals->tickcount, player->GetPlayerName(), flTimeAllowedForProcessing, playerFrameTime ); } } return; // Don't process this command } StartCommand( player, ucmd ); // Set globals appropriately gpGlobals->curtime = playerCurTime; gpGlobals->frametime = playerFrameTime; // Prevent hacked clients from sending us invalid view angles to try to get leaf server code to crash if ( !ucmd->viewangles.IsValid() || !IsEntityQAngleReasonable(ucmd->viewangles) ) { ucmd->viewangles = vec3_angle; } // Add and subtract buttons we're forcing on the player ucmd->buttons |= player->m_afButtonForced; ucmd->buttons &= ~player->m_afButtonDisabled; if ( player->m_bGamePaused ) { // If no clipping and cheats enabled and noclipduring game enabled, then leave // forwardmove and angles stuff in usercmd if ( player->GetMoveType() == MOVETYPE_NOCLIP && sv_cheats->GetBool() && sv_noclipduringpause.GetBool() ) { gpGlobals->frametime = TICK_INTERVAL; } } /* // TODO: We can check whether the player is sending more commands than elapsed real time cmdtimeremaining -= ucmd->msec; if ( cmdtimeremaining < 0 ) { // return; } */ g_pGameMovement->StartTrackPredictionErrors( player ); CommentarySystem_PePlayerRunCommand( player, ucmd ); // Do weapon selection if ( ucmd->weaponselect != 0 ) { CBaseCombatWeapon *weapon = dynamic_cast< CBaseCombatWeapon * >( CBaseEntity::Instance( ucmd->weaponselect ) ); if ( weapon ) { VPROF( "player->SelectItem()" ); player->SelectItem( weapon->GetName(), ucmd->weaponsubtype ); } } IServerVehicle *pVehicle = player->GetVehicle(); // Latch in impulse. if ( ucmd->impulse ) { // Discard impulse commands unless the vehicle allows them. // FIXME: UsingStandardWeapons seems like a bad filter for this. The flashlight is an impulse command, for example. if ( !pVehicle || player->UsingStandardWeaponsInVehicle() ) { player->m_nImpulse = ucmd->impulse; } } // Update player input button states VPROF_SCOPE_BEGIN( "player->UpdateButtonState" ); player->UpdateButtonState( ucmd->buttons ); VPROF_SCOPE_END(); CheckMovingGround( player, TICK_INTERVAL ); g_pMoveData->m_vecOldAngles = player->pl.v_angle; // Copy from command to player unless game .dll has set angle using fixangle if ( player->pl.fixangle == FIXANGLE_NONE ) { player->pl.v_angle = ucmd->viewangles; } else if( player->pl.fixangle == FIXANGLE_RELATIVE ) { player->pl.v_angle = ucmd->viewangles + player->pl.anglechange; } // Call standard client pre-think RunPreThink( player ); // Call Think if one is set RunThink( player, TICK_INTERVAL ); // Setup input. SetupMove( player, ucmd, moveHelper, g_pMoveData ); // Let the game do the movement. if ( !pVehicle ) { VPROF( "g_pGameMovement->ProcessMovement()" ); Assert( g_pGameMovement ); g_pGameMovement->ProcessMovement( player, g_pMoveData ); } else { VPROF( "pVehicle->ProcessMovement()" ); pVehicle->ProcessMovement( player, g_pMoveData ); } // Copy output FinishMove( player, ucmd, g_pMoveData ); // If we have to restore the view angle then do so right now if ( !player->IsBot() && ( gpGlobals->tickcount - player->GetLockViewanglesTickNumber() < sv_maxusrcmdprocessticks_holdaim.GetInt() ) ) { player->pl.v_angle = player->GetLockViewanglesData(); } // Let server invoke any needed impact functions VPROF_SCOPE_BEGIN( "moveHelper->ProcessImpacts" ); moveHelper->ProcessImpacts(); VPROF_SCOPE_END(); RunPostThink( player ); g_pGameMovement->FinishTrackPredictionErrors( player ); FinishCommand( player ); // Let time pass if ( gpGlobals->frametime > 0 ) { player->m_nTickBase++; } }
// Game loop that updates the scene void VisionApp_cl::OnUpdateScene() { VISION_PROFILE_FUNCTION(VIS_PROFILE_GAMELOOP); IVisSceneManager_cl *pSceneManager = Vision::GetSceneManager(); VASSERT(pSceneManager); // Check whether we should use async physics IVisPhysicsModule_cl *pPhysicsModule = Vision::GetApplication()->GetPhysicsModule(); bool bAsyncPhysics; if (pPhysicsModule != NULL && pPhysicsModule->GetUseAsynchronousPhysics()) bAsyncPhysics = true; else bAsyncPhysics = false; //Timer is not longer updated here, because it needs to be updated right after the frame flip float fElapsedTime = Vision::GetTimer()->GetTimeDifference(); // Advance the scene update counter Vision::Game.SetUpdateSceneCount( Vision::Game.GetUpdateSceneCount() + 1 ); Vision::Callbacks.OnUpdateSceneBegin.TriggerCallbacks(); //Send any queued messages before we remove entities Vision::Game.ProcessMessageQueue(); // Delete "dead" entities from previous frame { VISION_PROFILE_FUNCTION( VIS_PROFILE_GAMELOOP_UPDATELOOP ); Vision::Game.FreeRemovedEntities(); } // Run the pre-physics loop: statistics, prethink, events & animations if ( Vision::Editor.IsPlaying() ) RunPreThink(fElapsedTime); //Process animation messages after processing animations Vision::Game.ProcessMessageQueue(); // Run the physics simulation (if physics simulation is set to synchronous) if ( Vision::Editor.IsPlaying() && !bAsyncPhysics) { RunPhysics(fElapsedTime); FetchPhysicsResults(); } // Run the post-physics loop: posthink if ( Vision::Editor.IsPlaying() ) RunThink(fElapsedTime); // for the editor, we call the EditorThinkFunction function in every mode for every entity: if (Vision::Editor.IsInEditor()) { const int iCount = VisBaseEntity_cl::ElementManagerGetSize(); for (int i=0;i<iCount;i++) { VisBaseEntity_cl *pEntity = VisBaseEntity_cl::ElementManagerGet(i); if (pEntity) pEntity->EditorThinkFunction(); } } // handle the lightsources (e.g. color animation) if (Vision::Editor.IsAnimatingOrPlaying()) VisLightSource_cl::HandleAllLightSources(fElapsedTime); // update the core engine and module system RunUpdateLoop(); Vision::Game.ResetUpdatedEntitiesList(); // Kick off asynchronous physics simulation if ( Vision::Editor.IsPlaying() && bAsyncPhysics ) { RunPhysics(fElapsedTime); } // Handle portal/visibility zone transitions VisObject3DVisData_cl::HandleAllNodeTransitions(); //Handle render contexts VisRenderContext_cl::HandleAllRenderContexts(fElapsedTime); //Animate textures (in animate mode) VisTextureAnimInstance_cl::HandleAllAnims(Vision::Editor.IsAnimatingOrPlaying() ? fElapsedTime : 0.f); // scroll sky only when animating scene IVSky *pSky = Vision::World.GetActiveSky(); if (pSky != NULL && Vision::Editor.IsAnimatingOrPlaying()) pSky->Tick(fElapsedTime); Vision::Callbacks.OnUpdateSceneFinished.TriggerCallbacks(); }
void CHL2WarsPlayerMove::RunCommand( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *moveHelper ) { CHL2WarsPlayer *pWarsPlayer = static_cast<CHL2WarsPlayer*>( player ); Assert( pWarsPlayer ); StartCommand( player, ucmd ); // Set globals appropriately gpGlobals->curtime = player->m_nTickBase * TICK_INTERVAL; gpGlobals->frametime = player->m_bGamePaused ? 0 : TICK_INTERVAL; // Add and subtract buttons we're forcing on the player ucmd->buttons |= player->m_afButtonForced; ucmd->buttons &= ~player->m_afButtonDisabled; if ( player->m_bGamePaused ) { // If no clipping and cheats enabled and noclipduring game enabled, then leave // forwardmove and angles stuff in usercmd if ( player->GetMoveType() == MOVETYPE_NOCLIP && sv_cheats->GetBool() )// && //sv_noclipduringpause.GetBool() ) { gpGlobals->frametime = TICK_INTERVAL; } } /* // TODO: We can check whether the player is sending more commands than elapsed real time cmdtimeremaining -= ucmd->msec; if ( cmdtimeremaining < 0 ) { // return; } */ g_pGameMovement->StartTrackPredictionErrors( player ); //CommentarySystem_PePlayerRunCommand( player, ucmd ); IServerVehicle *pVehicle = player->GetVehicle(); // Latch in impulse. if ( ucmd->impulse ) { // Discard impulse commands unless the vehicle allows them. // FIXME: UsingStandardWeapons seems like a bad filter for this. The flashlight is an impulse command, for example. if ( !pVehicle || player->UsingStandardWeaponsInVehicle() ) { player->m_nImpulse = ucmd->impulse; } } // Update player input button states VPROF_SCOPE_BEGIN( "player->UpdateButtonState" ); player->UpdateButtonState( ucmd->buttons ); VPROF_SCOPE_END(); CheckMovingGround( player, TICK_INTERVAL ); g_pMoveData->m_vecOldAngles = player->pl.v_angle; // Copy from command to player unless game .dll has set angle using fixangle if ( player->pl.fixangle == FIXANGLE_NONE ) { player->pl.v_angle = ucmd->viewangles; } else if( player->pl.fixangle == FIXANGLE_RELATIVE ) { player->pl.v_angle = ucmd->viewangles + player->pl.anglechange; } // TrackIR //player->SetEyeAngleOffset(ucmd->headangles); //player->SetEyeOffset(ucmd->headoffset); // TrackIR // Call standard client pre-think RunPreThink( player ); // Call Think if one is set RunThink( player, TICK_INTERVAL ); // Setup input. SetupMove( player, ucmd, moveHelper, g_pMoveData ); // Let the game do the movement. if( pWarsPlayer && !pWarsPlayer->GetControlledUnit() ) { if( ucmd->directmove ) { g_pMoveData->SetAbsOrigin( ucmd->vecmovetoposition ); } else { if ( !pVehicle ) { VPROF( "g_pGameMovement->ProcessMovement()" ); Assert( g_pGameMovement ); g_pGameMovement->ProcessMovement( player, g_pMoveData ); } else { VPROF( "pVehicle->ProcessMovement()" ); pVehicle->ProcessMovement( player, g_pMoveData ); } } } // Copy output FinishMove( player, ucmd, g_pMoveData ); // Let server invoke any needed impact functions VPROF_SCOPE_BEGIN( "moveHelper->ProcessImpacts" ); moveHelper->ProcessImpacts(); VPROF_SCOPE_END(); // put lag compensation here so it affects weapons //lagcompensation->StartLagCompensation( player, LAG_COMPENSATE_BOUNDS ); RunPostThink( player ); //lagcompensation->FinishLagCompensation( player ); // let the player drive marine movement here if( pWarsPlayer->GetControlledUnit() ) pWarsPlayer->GetControlledUnit()->GetIUnit()->UserCmd( ucmd ); g_pGameMovement->FinishTrackPredictionErrors( player ); FinishCommand( player ); // Let time pass player->m_nTickBase++; }
//----------------------------------------------------------------------------- // Purpose: Predicts a single movement command for player // Input : *moveHelper - // *player - // *u - //----------------------------------------------------------------------------- void CASW_Prediction::RunCommand( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *moveHelper ) { #if !defined( NO_ENTITY_PREDICTION ) VPROF( "CPrediction::RunCommand" ); #if defined( _DEBUG ) char sz[ 32 ]; Q_snprintf( sz, sizeof( sz ), "runcommand%04d", ucmd->command_number ); PREDICTION_TRACKVALUECHANGESCOPE( sz ); #endif C_ASW_Player *pASWPlayer = (C_ASW_Player*)player; Assert( pASWPlayer ); StartCommand( player, ucmd ); pASWPlayer->SetHighlightEntity( C_BaseEntity::Instance( ucmd->crosshair_entity ) ); // Set globals appropriately gpGlobals->curtime = player->m_nTickBase * TICK_INTERVAL; gpGlobals->frametime = TICK_INTERVAL; g_pGameMovement->StartTrackPredictionErrors( player ); // TODO // TODO: Check for impulse predicted? // Do weapon selection if ( ucmd->weaponselect != 0 ) { C_BaseCombatWeapon *weapon = dynamic_cast< C_BaseCombatWeapon * >( CBaseEntity::Instance( ucmd->weaponselect ) ); if (weapon) { pASWPlayer->ASWSelectWeapon(weapon, 0); //ucmd->weaponsubtype); // asw - subtype var used for sending marine profile index instead } } // Latch in impulse. IClientVehicle *pVehicle = player->GetVehicle(); if ( ucmd->impulse ) { // Discard impulse commands unless the vehicle allows them. // FIXME: UsingStandardWeapons seems like a bad filter for this. // The flashlight is an impulse command, for example. if ( !pVehicle || player->UsingStandardWeaponsInVehicle() ) { player->m_nImpulse = ucmd->impulse; } } // Get button states player->UpdateButtonState( ucmd->buttons ); // TODO // CheckMovingGround( player, ucmd->frametime ); // TODO // g_pMoveData->m_vecOldAngles = player->pl.v_angle; // Copy from command to player unless game .dll has set angle using fixangle // if ( !player->pl.fixangle ) { player->SetLocalViewAngles( ucmd->viewangles ); } // Call standard client pre-think RunPreThink( player ); // Call Think if one is set RunThink( player, TICK_INTERVAL ); // Setup input. { SetupMove( player, ucmd, moveHelper, g_pMoveData ); } // Run regular player movement if we're not controlling a marine if ( asw_allow_detach.GetBool() ) { if ( !pVehicle ) { Assert( g_pGameMovement ); g_pGameMovement->ProcessMovement( player, g_pMoveData ); } else { pVehicle->ProcessMovement( player, g_pMoveData ); } } // if ( !asw_allow_detach.GetBool() && pASWPlayer->GetMarine() ) // { // g_pMoveData->SetAbsOrigin( pASWPlayer->GetMarine()->GetAbsOrigin() ); // } pASWPlayer->SetCrosshairTracePos( ucmd->crosshairtrace ); FinishMove( player, ucmd, g_pMoveData ); RunPostThink( player ); // let the player drive marine movement here pASWPlayer->DriveMarineMovement( ucmd, moveHelper ); g_pGameMovement->FinishTrackPredictionErrors( player ); FinishCommand( player ); player->m_nTickBase++; #endif }