void CElementRPCs::SetElementPosition ( NetBitStreamInterface& bitStream ) { // Read out the entity id and the position ElementID ID; CVector vecPosition; unsigned char ucTimeContext; if ( bitStream.Read ( ID ) && bitStream.Read ( vecPosition.fX ) && bitStream.Read ( vecPosition.fY ) && bitStream.Read ( vecPosition.fZ ) && bitStream.Read ( ucTimeContext ) ) { // Grab the entity CClientEntity* pEntity = CElementIDs::GetElement ( ID ); if ( pEntity ) { // Update the sync context to the new one pEntity->SetSyncTimeContext ( ucTimeContext ); // If it's a player, use Teleport if ( pEntity->GetType () == CCLIENTPLAYER ) { unsigned char ucWarp = 1; bitStream.Read ( ucWarp ); CClientPlayer* pPlayer = static_cast < CClientPlayer* > ( pEntity ); if ( ucWarp ) { pPlayer->Teleport ( vecPosition ); pPlayer->ResetInterpolation (); } else { pPlayer->SetPosition ( vecPosition ); } // If local player, reset return position (so we can't warp back if connection fails) if ( pPlayer->IsLocalPlayer () ) { m_pClientGame->GetNetAPI ()->ResetReturnPosition (); } } else if ( pEntity->GetType () == CCLIENTVEHICLE ) { CClientVehicle* pVehicle = static_cast < CClientVehicle* > ( pEntity ); pVehicle->RemoveTargetPosition (); pVehicle->SetPosition ( vecPosition ); } else { // Set its position pEntity->SetPosition ( vecPosition ); } } } }
void CClientPlayerManager::DoPulse ( void ) { unsigned long ulCurrentTime = CClientTime::GetTime (); CClientPlayer * pPlayer = NULL; vector < CClientPlayer* > ::const_iterator iter = m_Players.begin (); for ( ; iter != m_Players.end (); ++iter ) { pPlayer = *iter; if ( !pPlayer->IsLocalPlayer () ) { // Pulse voice data if voice is enabled if ( g_pClientGame->GetVoiceRecorder()->IsEnabled() && pPlayer->GetVoice() ) pPlayer->GetVoice()->DoPulse(); // Flag him with connection error if its been too long since last puresync and force his position unsigned long ulLastPuresyncTime = pPlayer->GetLastPuresyncTime (); bool bHasConnectionTrouble = ( ulLastPuresyncTime != 0 && ulCurrentTime >= ulLastPuresyncTime + REMOTE_PLAYER_CONNECTION_TROUBLE_TIME ); if ( bHasConnectionTrouble && !g_pClientGame->IsDownloadingBigPacket () && !pPlayer->IsDeadOnNetwork () ) { pPlayer->SetHasConnectionTrouble ( true ); // Reset his controller so he doesn't get stuck shooting or something CControllerState State; memset ( &State, 0, sizeof ( CControllerState ) ); pPlayer->SetControllerState ( State ); // Grab his vehicle if any and force the position to where he was last sync CClientVehicle* pVehicle = pPlayer->GetOccupiedVehicle (); if ( pVehicle ) { // Is he driving the vehicle? if ( pPlayer->GetOccupiedVehicleSeat () == 0 ) { // Force his position to where he was last sync pVehicle->SetPosition ( pPlayer->GetLastPuresyncPosition () ); pVehicle->SetMoveSpeed ( CVector ( 0, 0, 0 ) ); pVehicle->SetTurnSpeed ( CVector ( 0, 0, 0 ) ); pPlayer->ResetInterpolation (); } } else { // Force his position to where he was last sync pPlayer->SetPosition ( pPlayer->GetLastPuresyncPosition () ); pPlayer->ResetInterpolation (); pPlayer->SetMoveSpeed ( CVector ( 0, 0, 0 ) ); pPlayer->ResetInterpolation (); } } else { pPlayer->SetHasConnectionTrouble ( false ); } } } }