void Save( SActivationInfo *pActInfo ) { m_name = GetPortString( pActInfo, EIP_Name ); PathUtil::RemoveExtension(m_name); if(gEnv->IsEditor()) { m_state = ES_Idle; pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false); IActor* pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if (pClientActor && !pClientActor->IsDead()) ActivateOutput(pActInfo, EOP_SaveOrLoadDone, true); } else { if(IGame *pGame = gEnv->pGame) { pGame->GetIGameFramework()->RegisterListener(this, "CFlowSaveGameNode", FRAMEWORKLISTENERPRIORITY_DEFAULT); } pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true); m_state = ES_WaitForSaveDone; } if(gEnv->pGame) { gEnv->pGame->GetIGameFramework()->SaveGame(gEnv->pGame->CreateSaveGameName().c_str(), true, false, eSGR_FlowGraph, false, m_name.c_str()); } }
bool CBitmapUi::CanDrawCrosshair() const { assert( m_pGameFramework != NULL ); if ( ! g_pGameCVars->g_show_crosshair ) { return false; } IActor* pPlayer = m_pGameFramework->GetClientActor(); if ( pPlayer == NULL ) { return false; } bool isPlayerDead = pPlayer->IsDead(); if ( isPlayerDead ) { return false; } bool thirdPersonMode = pPlayer->IsThirdPerson(); bool crosshairEnabledInThirdPerson = ( g_pGameCVars->g_show_crosshair_tp != 0 ); if ( thirdPersonMode && ! crosshairEnabledInThirdPerson ) { return false; } IItem* pItem = pPlayer->GetCurrentItem(); if ( pItem == NULL ) { return false; } IWeapon* pWeapon = pItem->GetIWeapon(); if ( pWeapon == NULL ) { return false; } bool carryingMeleeWeapon = pWeapon->CanMeleeAttack(); if ( carryingMeleeWeapon ) { return false; } bool isWeaponZoomed = pWeapon->IsZoomed(); bool usingWeaponSightForAiming = ( ! thirdPersonMode && isWeaponZoomed ); if ( usingWeaponSightForAiming ) { return false; } return true; }
void CProceduralContextRagdoll::Update( float timePassedSeconds ) { if( m_bInBlendOut ) { m_blendOutTimeCurrent -= timePassedSeconds; const float blendOutFactor = max( m_blendOutTime > 0.0f ? m_blendOutTimeCurrent/m_blendOutTime : 0.0f, 0.0f ); if( IEntity* pEntity = gEnv->pEntitySystem->GetEntity( m_targetEntityId ) ) { if(IPhysicalEntity* pent = pEntity->GetPhysics()) { pe_status_nparts parts; int partCount = pent->GetStatus(&parts); for (int i=0; i<partCount; ++i) { pe_params_part pp; pe_params_joint pj; pp.ipart = i; pent->GetParams(&pp); pj.op[1] = pp.partid; pj.ks = Vec3(max(m_stiffness * blendOutFactor, 1.0f)); pent->SetParams(&pj); } } } if( blendOutFactor == 0.0f ) { IActor* piActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor( m_targetEntityId ); if( piActor ) { ForceRagdollFinish( piActor, false ); } Reset(); m_bInRagdoll = piActor ? piActor->IsDead() : true; } } else if( m_bInRagdoll && !m_bEntityAlive && !m_bFromProcClip ) { IActor* piActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor( m_targetEntityId ); if( piActor ) { ForceRagdollFinish( piActor, true ); } } }
void CC4Projectile::Update(SEntityUpdateContext &ctx, int updateSlot) { if(gEnv->bMultiplayer) { IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerId); if(!pActor || pActor->IsDead()) { if(gEnv->bServer) { Destroy(); } else { GetEntity()->Hide(true); } RemoveLight(); if(m_isShowingUIIcon) { SHUDEvent hudEvent(eHUDEvent_RemoveC4Icon); hudEvent.AddData((int)GetEntityId()); CHUDEventDispatcher::CallEvent(hudEvent); m_isShowingUIIcon = false; } } } if(m_pLightSource) { UpdateLight(ctx.fFrameTime, false); } if(m_disarmTimer > 0.f) { m_disarmTimer -= ctx.fFrameTime; if(m_disarmTimer <= 0.f) { m_disarmTimer = 0.f; Arm(true); } } BaseClass::Update(ctx, updateSlot); }
void CPlayerPlugin_CurrentlyTargetting::Update(float dt) { m_currentTargetTime += dt; //updated locally for all players (so doesn't have to be synced) assert (IsEntered()); if (m_ownerPlayer->IsClient()) { EntityId newTargetId = !m_ownerPlayer->IsDead() ? m_ownerPlayer->GetGameObject()->GetWorldQuery()->GetLookAtEntityId() : 0; if (newTargetId) { IActor * targettedActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(newTargetId); if (targettedActor == NULL || targettedActor->IsDead()) { newTargetId = 0; } } if (m_currentTarget != newTargetId) { m_currentTarget = newTargetId; CCCPOINT_IF(m_currentTarget, PlayerState_LocalPlayerNowTargettingSomebody); CCCPOINT_IF(!m_currentTarget, PlayerState_LocalPlayerNowTargettingNobody); m_currentTargetTime = 0.0f; CHANGED_NETWORK_STATE(m_ownerPlayer, CPlayer::ASPECT_CURRENTLYTARGETTING_CLIENT); } } #if PLAYER_PLUGIN_DEBUGGING IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_currentTarget); PlayerPluginWatch ("Target e%05d (%s %s) - %.2f", m_currentTarget, pEntity ? pEntity->GetName() : "NULL", pEntity ? pEntity->GetClass()->GetName() : "entity", m_currentTargetTime); #endif }
void CAutoTester::UpdatePerformanceTestInGame() { IActor* pPlayer = gEnv->pGame->GetIGameFramework()->GetClientActor(); if (pPlayer) { float timeSeconds=gEnv->pTimer->GetFrameStartTime().GetSeconds(); if (pPlayer->IsDead()) { CryLogAlways("CAutoTester::UpdatePerformanceTestInGame() detected that our player is dead - requesting revive"); // IGameRulesSpawningModule *pSpawningModule = g_pGame->GetGameRules()->GetSpawningModule(); // if (pSpawningModule) // { // CryLog("CAutoTester::UpdatePerformanceTestInGame() Requesting revive"); // pSpawningModule->ClRequestRevive(pPlayer->GetEntityId()); // } GameWarning(" TODO: ClRequestRevive ot implemented!"); } else { if (!m_stateData.testPerformance.m_bConfigExecuted) { if (timeSeconds > m_stateData.testPerformance.m_delayToStart) { CryLogAlways("CAutoTester::UpdatePerformanceTestInGame() executing configfile=%s", m_stateData.testPerformance.m_configFile); gEnv->pConsole->ExecuteString(string().Format("exec %s", m_stateData.testPerformance.m_configFile)); m_stateData.testPerformance.m_bConfigExecuted = true; } } } //CryWatch("time=%f; timeOut=%f", timeSeconds, m_stateData.testPerformance.m_timeOut); if (timeSeconds > m_stateData.testPerformance.m_timeOut) { CryLogAlways("CAutoTester::UpdatePerformanceTestInGame() finished running test - disconnecting to generate telemetry"); gEnv->pConsole->ExecuteString("disconnect"); m_stateData.testPerformance.m_subState = CAutoTester::k_testPerformance_substate_waiting_to_submit_telemetry; m_stateData.testPerformance.m_timeOut = timeSeconds + 10.0f; } } }
virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case eFE_Activate: if (IsPortActive(pActInfo, 0)) { IActor* pActor = GetAIActor(pActInfo); if(pActor) { if (!pActor->IsDead()) { pActor->SetHealth( GetPortFloat(pActInfo, 1) ); ActivateOutput(pActInfo, 0, pActor->GetHealth()); // use pActor->GetHealth (might have been clamped to maxhealth] } } else { GameWarning("CFlowActorSetHealth - No Entity or Entity not an actor!"); } } } }
//-------------------------------------------------------------------------------------------------- // Name: SpawnScreenExplosionEffect // Desc: Spawns screen explosion effect //-------------------------------------------------------------------------------------------------- void CExplosionGameEffect::SpawnScreenExplosionEffect(const SExplosionContainer &explosionContainer) { // Disclaimer: this code was originally from GameRulesClientServer::ProcessClientExplosionScreenFX() const ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo; if(explosionInfo.pressure < 1.0f) return; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(pClientActor != NULL && !pClientActor->IsDead()) { CPlayer* pPlayer = static_cast<CPlayer*>(pClientActor); bool hasFlashBangEffect = explosionInfo.blindAmount > 0.0f; // Flashbang friends and self?... if(hasFlashBangEffect) { bool flashBangSelf = true; bool flashBangFriends = false; #ifndef _RELEASE flashBangSelf = g_pGameCVars->g_flashBangSelf != 0; flashBangFriends = g_pGameCVars->g_flashBangFriends != 0; #endif bool ownFlashBang = pPlayer->GetEntityId() == explosionInfo.shooterId; if((!flashBangSelf && ownFlashBang) || // FlashBang self? ((g_pGame->GetGameRules()->GetFriendlyFireRatio()<=0.0f) && (!flashBangFriends) && (!ownFlashBang) && pPlayer->IsFriendlyEntity(explosionInfo.shooterId))) // FlashBang friends? { return; } } // Distance float dist = (pClientActor->GetEntity()->GetWorldPos() - explosionInfo.pos).len(); // Is the explosion in Player's FOV (let's suppose the FOV a bit higher, like 80) SMovementState state; if(IMovementController *pMV = pClientActor->GetMovementController()) { pMV->GetMovementState(state); } Vec3 eyeToExplosion = explosionInfo.pos - state.eyePosition; Vec3 eyeDir = pClientActor->GetLinkedVehicle() ? pPlayer->GetVehicleViewDir() : state.eyeDirection; eyeToExplosion.Normalize(); float eyeDirectionDP = eyeDir.Dot(eyeToExplosion); bool inFOV = (eyeDirectionDP > 0.68f); // All explosions have radial blur (default 30m radius) const float maxBlurDistance = (explosionInfo.maxblurdistance >0.0f) ? explosionInfo.maxblurdistance : 30.0f; if((maxBlurDistance > 0.0f) && (g_pGameCVars->g_radialBlur > 0.0f) && (explosionInfo.radius > 0.5f)) { if (inFOV && (dist < maxBlurDistance)) { const int intersectionObjTypes = ent_static | ent_terrain; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; m_deferredScreenEffects.RequestRayCast(CDeferredExplosionEffect::eDET_RadialBlur, explosionInfo.pos, -eyeToExplosion, dist, maxBlurDistance, intersectionObjTypes, intersectionFlags, NULL, 0); } } // Flashbang effect if(hasFlashBangEffect && ((dist < (explosionInfo.radius*g_pGameCVars->g_flashBangNotInFOVRadiusFraction)) || (inFOV && (dist < explosionInfo.radius)))) { ray_hit hit; const int intersectionObjTypes = ent_static | ent_terrain; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; const int intersectionMaxHits = 1; int collision = gEnv->pPhysicalWorld->RayWorldIntersection( explosionInfo.pos, -eyeToExplosion*dist, intersectionObjTypes, intersectionFlags, &hit, intersectionMaxHits); // If there was no obstacle between flashbang grenade and player if(!collision) { bool enabled = true; if(enabled) { CCCPOINT (FlashBang_Explode_BlindLocalPlayer); float timeScale = max(0.0f, 1 - (dist/explosionInfo.radius)); float lookingAt = max(g_pGameCVars->g_flashBangMinFOVMultiplier, (eyeDirectionDP + 1)*0.5f); float time = explosionInfo.flashbangScale * timeScale *lookingAt; // time is determined by distance to explosion CRY_ASSERT_MESSAGE(pClientActor->IsPlayer(),"Effect shouldn't be spawned if not a player"); SPlayerStats* pStats = static_cast<SPlayerStats*>(pPlayer->GetActorStats()); NET_BATTLECHATTER(BC_Blinded, pPlayer); if(pClientActor->GetEntityId() == explosionInfo.shooterId) { g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_BlindSelf); } else { g_pGame->GetGameRules()->SuccessfulFlashBang(explosionInfo, time); } pPlayer->StartFlashbangEffects(time, explosionInfo.shooterId); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Time", time); gEnv->p3DEngine->SetPostEffectParam("FlashBang_BlindAmount", explosionInfo.blindAmount); gEnv->p3DEngine->SetPostEffectParam("Flashbang_DifractionAmount", time); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Active", 1.0f); CRecordingSystem *pRecordingSystem = g_pGame->GetRecordingSystem(); if (pRecordingSystem) { pRecordingSystem->OnPlayerFlashed(time, explosionInfo.blindAmount); } } } else { CCCPOINT (FlashBang_Explode_NearbyButBlockedByGeometry); } } else if(inFOV && (dist < explosionInfo.radius)) { if(explosionInfo.damage>10.0f || explosionInfo.pressure>100.0f) { // Add some angular impulse to the client actor depending on distance, direction... float dt = (1.0f - dist/explosionInfo.radius); dt = dt * dt; float angleZ = gf_PI*0.15f*dt; float angleX = gf_PI*0.15f*dt; if (pClientActor) { static_cast<CActor*>(pClientActor)->AddAngularImpulse(Ang3(cry_random(-angleX*0.5f,angleX),0.0f,cry_random(-angleZ,angleZ)),0.0f,dt*2.0f); } } } } }//-------------------------------------------------------------------------------------------------
bool CStickyProjectile::StickToEntity( const SStickParams& stickParams, IEntity* pTargetEntity ) { IEntity* pProjectileEntity = stickParams.m_pProjectile->GetEntity(); ICharacterInstance* pCharInstance = pTargetEntity->GetCharacter(0); if( pCharInstance) { IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId()); if (!pActor || (stickParams.m_bStickToFriendlies || !pActor->IsFriendlyEntity(stickParams.m_ownerId)) && (gEnv->bMultiplayer || !pActor->IsDead())) { m_stuckJoint = GetJointIdFromPartId(*pTargetEntity, stickParams.m_targetPartId); m_stuckNormal = stickParams.m_stickNormal; m_stuckPartId = stickParams.m_targetPartId; ICharacterModelSkeleton* pICharacterModelSkeleton = pCharInstance->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeleton = pCharInstance->GetISkeletonPose(); const char* boneName = pICharacterModelSkeleton->GetJointNameByID(m_stuckJoint); const QuatT jointWorld = QuatT(pTargetEntity->GetWorldTM()) * pSkeleton->GetAbsJointByID(m_stuckJoint); QuatT loc; CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc ); pProjectileEntity->SetWorldTM(Matrix34(loc)); // Get the local pos and rot. loc = jointWorld.GetInverted() * loc; m_stuckPos = loc.t; m_stuckRot = loc.q; // Attach. if(AttachToCharacter( stickParams.m_pProjectile, *pTargetEntity, *pCharInstance, boneName)) { m_flags |= eSF_IsStuck; m_flags |= pActor ? pActor->IsPlayer() ? eSF_StuckToPlayer : eSF_StuckToAI : 0; SetParentId(pTargetEntity->GetId()); m_childId = pProjectileEntity->GetId(); return true; } } } else { m_stuckNormal = stickParams.m_stickNormal; m_stuckPartId = stickParams.m_targetPartId; QuatT loc; CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc ); AttachTo(stickParams.m_pProjectile, pTargetEntity); pProjectileEntity->SetWorldTM(Matrix34(loc)); // Set as Stuck. SetParentId(pTargetEntity->GetId()); m_childId = pProjectileEntity->GetId(); m_flags |= eSF_IsStuck; //Store position and rotation relative to parent entity m_stuckPos = pProjectileEntity->GetPos(); m_stuckRot = pProjectileEntity->GetRotation(); return true; } return false; }
//------------------------------------------------------------------------- void CGameRulesStandardState::Update( float frameTime ) { if (gEnv->bServer) { if(m_state == EGRS_Intro) { // We assume there is an intro, if we reach this point and an intro hasnt been registered, we know there isn't one. Onwards and upwards. if(!m_pGameRules->IsIntroSequenceRegistered()) { ChangeState(EGRS_PreGame); } } if (m_state == EGRS_PreGame) { if (m_isStarting) { const float remainingTime = m_pGameRules->GetRemainingStartTimer(); if (remainingTime <= 0.f) { CryLog("CGameRulesStandardState::Update(), starting game"); ChangeState(EGRS_InGame); } } else { bool bOk = true; CGameLobby* pGameLobby = g_pGame->GetGameLobby(); const int numPlayers = m_pGameRules->GetPlayerCount(true); if (pGameLobby) { if (m_isWaitingForOverrideTimer) { //-- test override timer m_startTimerOverrideWait -= frameTime; bOk = (m_startTimerOverrideWait <= 0.0f); if (!bOk) { bOk = true; //-- testing min player count doesn't apply to private games const bool publicGame = !pGameLobby->IsPrivateGame(); const bool onlineGame = pGameLobby->IsOnlineGame(); if (publicGame && onlineGame) { // Start only when we have enough players if (m_pGameRules->GetTeamCount() > 1) { //-- team game, insist at least 1 player per team const int numPlayersPerTeamMin = g_pGameCVars->g_gameRules_startTimerMinPlayersPerTeam; const int numPlayersTeam1 = m_pGameRules->GetTeamPlayerCount(1, true); const int numPlayersTeam2 = m_pGameRules->GetTeamPlayerCount(2, true); bOk = ((numPlayersTeam1 >= numPlayersPerTeamMin) && (numPlayersTeam2 >= numPlayersPerTeamMin)); } else { //-- not a team game, so just insist on minimum 2 players const int numPlayersMin = g_pGameCVars->g_gameRules_startTimerMinPlayers; bOk = (numPlayers >= numPlayersMin); } const int numPlayersInLobby = pGameLobby->GetSessionNames().Size(); bOk |= (numPlayersInLobby == numPlayers); } if (bOk) { //-- Enforce a percentage of lobby players in game before starting countdown bOk = (!gEnv->IsClient() || (g_pGame->GetClientActorId() != 0)) && CheckInitialChannelPlayers(); } } } else { bOk = false; if (numPlayers) { //-- Start the override timer. m_startTimerOverrideWait = g_pGameCVars->g_gameRules_startTimerOverrideWait; m_isWaitingForOverrideTimer = true; } } } if (bOk) { CryLog("CGameRulesStandardState::Update(), we have %i players, starting the game", numPlayers); float startTimeLength = #if !defined(_RELEASE) g_pGameCVars->g_gameRules_skipStartTimer ? 0.0f : #endif g_pGameCVars->g_gameRules_startTimerLength; #if USE_PC_PREMATCH bool bDoPCPrematch = false; CGameRules::EPrematchState prematchState = m_pGameRules->GetPrematchState(); if (prematchState==CGameRules::ePS_Prematch) { int numRequiredPlayers = g_pGameCVars->g_minPlayersForRankedGame - m_pGameRules->GetPlayerCount(true); if ((numRequiredPlayers > 0) || (pGameLobby && pGameLobby->UseLobbyTeamBalancing() && !pGameLobby->IsGameBalanced())) { bDoPCPrematch = true; CPlaylistManager *pPlaylistManager = g_pGame->GetPlaylistManager(); if (pGameLobby && pPlaylistManager) { if (!pGameLobby->IsRankedGame() || pPlaylistManager->IsUsingCustomVariant()) { // Private games don't do prematch bDoPCPrematch = false; } } if (bDoPCPrematch) { // If we are waiting for players on pc, spawn ingame and set a prematch state which waits for players. m_pGameRules->StartPrematch(); startTimeLength = 0.f; } } if (!bDoPCPrematch) { m_pGameRules->SkipPrematch(); } } #endif m_pGameRules->ResetGameStartTimer(startTimeLength); StartCountdown(true); } } } else if (m_state == EGRS_PostGame) { const float prevUpdateStamp = m_timeInPostGame; const float timeInPost = (prevUpdateStamp + frameTime); const float timeToShowHUDMessage = g_pGameCVars->g_gameRules_postGame_HUDMessageTime; const float timeToShowTop3 = g_pGameCVars->g_gameRules_postGame_Top3Time; const float timeToShowScoreboard = g_pGameCVars->g_gameRules_postGame_ScoreboardTime; float killcamLength = m_pGameRules->GameEndedByWinningKill() ? g_pGameCVars->kc_length : 0.f; if (g_pGameCVars->kc_showHighlightsAtEndOfGame) { CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem(); if(pRecordingSystem) { killcamLength += pRecordingSystem->GetHighlightsReelLength(); killcamLength = min(killcamLength, 20.f); } } const float totalPostGameTime = timeToShowHUDMessage + timeToShowTop3 + timeToShowScoreboard + killcamLength; if (timeInPost > totalPostGameTime) { CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem(); if (!pRecordingSystem || (!pRecordingSystem->IsPlaybackQueued() && !pRecordingSystem->IsPlayingBack())) { CGameLobby *pGameLobby = g_pGame->GetGameLobby(); if (pGameLobby) { CryLog("[GameRules] Server trying to return to lobby"); pGameLobby->SvFinishedGame(frameTime); } } else if(pRecordingSystem) { pRecordingSystem->StopHighlightReel(); } } m_timeInPostGame = timeInPost; } } CPlayer * pPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetClientActor()); if((pPlayer && pPlayer->ShouldPlayIntro() || gEnv->bServer) && m_pGameRules->IsIntroSequenceRegistered() && !m_bHaveNotifiedIntroListeners) { // All flowgraph nodes that want to listen, should be created at this point OnIntroStart_NotifyListeners(); } #ifndef _RELEASE if(g_pGameCVars->g_hud_postgame_debug) { const char* stateName = ""; switch(m_state) { case EGRS_Reset: { stateName = "EGRS_Reset"; break;} case EGRS_Intro: { stateName = "EGRS_Intro"; break;} case EGRS_PreGame: { stateName = "EGRS_PreGame"; break;} case EGRS_InGame: { stateName = "EGRS_InGame"; break;} case EGRS_PostGame: { stateName = "EGRS_PostGame"; break;} case EGRS_MAX: { stateName = "EGRS_MAX"; break;} } CryWatch("GameRulesStandardState - State = %s", stateName); if(m_state == EGRS_PostGame) { const char* postGameStateName = ""; switch(m_postGameState) { case ePGS_Unknown: { postGameStateName = "ePGS_Unknown"; break; } case ePGS_Starting: { postGameStateName = "ePGS_Starting"; break; } case ePGS_HudMessage: { postGameStateName = "ePGS_HudMessage"; break; } case ePGS_FinalKillcam: { postGameStateName = "ePGS_FinalKillcam"; break; } case ePGS_HighlightReel: { postGameStateName = "ePGS_HighlightReel"; break; } case ePGS_Top3: { postGameStateName = "ePGS_Top3"; break; } case ePGS_Scoreboard: { postGameStateName = "ePGS_Scoreboard"; break; } } CryWatch("GameRulesStandardState -PostGameState = %s", postGameStateName); } } #endif if (gEnv->IsClient()) { if (m_state == EGRS_PreGame) { if( !gEnv->IsDedicated() ) { if (m_isStarting) { const float timeTillStartInSeconds = m_pGameRules->GetRemainingStartTimer(); SHUDEventWrapper::UpdateGameStartCountdown( ePreGameCountdown_MatchStarting, timeTillStartInSeconds ); } else { SHUDEventWrapper::UpdateGameStartCountdown( ePreGameCountdown_WaitingForPlayers, 0.0f ); } } } else if (m_state == EGRS_InGame && !gEnv->IsDedicated() ) { if (m_introMessageShown == false) // Show only once { CGameRules *pGameRules = g_pGame->GetGameRules(); if (pGameRules && pGameRules->HasGameActuallyStarted()) { if (EntityId localPlayerId = g_pGame->GetIGameFramework()->GetClientActorId()) { int teamId = g_pGame->GetGameRules()->GetTeam(localPlayerId); bool bTeamGame = (pGameRules->GetTeamCount() > 1); IActor *pActor = g_pGame->GetIGameFramework()->GetClientActor(); if (pActor->GetSpectatorMode()==CActor::eASM_None && !pActor->IsDead() && (!bTeamGame || teamId!=0)) { if (IGameRulesPlayerStatsModule *statsModule = pGameRules->GetPlayerStatsModule()) { const SGameRulesPlayerStat *stats = statsModule->GetPlayerStats(localPlayerId); if (stats->deaths <= 0) // Not died ever { if (m_startMatchString.empty() == false) { const char* gamemodeName = g_pGame->GetGameRules()->GetEntity()->GetClass()->GetName(); CryFixedStringT<32> strSignalName; strSignalName.Format("StartGame%s", gamemodeName); TAudioSignalID signalId = g_pGame->GetGameAudio()->GetSignalID(strSignalName); CryFixedStringT<64> localisedStartString = CHUDUtils::LocalizeString( m_startMatchString.c_str() ); if (bTeamGame) { CryFixedStringT<16> strTeamName; strTeamName.Format("@ui_hud_team_%d", teamId); SHUDEventWrapper::TeamMessage(strTeamName.c_str(), teamId, SHUDEventWrapper::SMsgAudio(signalId), false, true); SHUDEventWrapper::SimpleBannerMessage(localisedStartString.c_str(), SHUDEventWrapper::kMsgAudioNULL); } else { SHUDEventWrapper::RoundMessageNotify(localisedStartString.c_str(), SHUDEventWrapper::SMsgAudio(signalId)); } } } } m_introMessageShown = true; // Or not if has already died, but don't check again anyway. } } } } } else if(m_state == EGRS_PostGame && !gEnv->IsDedicated()) { if (!gEnv->bServer) { m_timeInPostGame += frameTime; } m_timeInCurrentPostGameState += frameTime; switch (m_postGameState) { case ePGS_Starting: { CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem(); if (pRecordingSystem != NULL && (pRecordingSystem->IsPlayingBack() || pRecordingSystem->IsPlaybackQueued())) { // Currently showing a killcam, skip to the killcam stage of the postgame flow EnterPostGameState(ePGS_FinalKillcam); } else { if (m_pGameRules->GetRoundsModule()) { EnterPostGameState(ePGS_Top3); } else { EnterPostGameState(ePGS_HudMessage); } } break; } case ePGS_HudMessage: { if (m_timeInCurrentPostGameState > g_pGameCVars->g_gameRules_postGame_HUDMessageTime) { EnterPostGameState(ePGS_FinalKillcam); } break; } case ePGS_FinalKillcam: { CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem(); if (!pRecordingSystem || !(pRecordingSystem->IsPlayingBack() || (pRecordingSystem->IsPlaybackQueued() && pRecordingSystem->HasWinningKillcam()))) { EnterPostGameState(ePGS_Top3); } #ifndef _RELEASE else if(g_pGameCVars->g_hud_postgame_debug && pRecordingSystem) { CryWatch("PostGameState - Waiting for final killcam to end:"); CryWatch("IsPlaybackQueued: %s, IsPlayingBack: %s", pRecordingSystem->IsPlaybackQueued() ? "True" : "False", pRecordingSystem->IsPlayingBack() ? "True" : "False"); } #endif break; } case ePGS_HighlightReel: { CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem(); if (!pRecordingSystem || (!pRecordingSystem->IsPlaybackQueued() && !pRecordingSystem->IsPlayingBack())) { CGameLobby *pGameLobby = g_pGame->GetGameLobby(); if (pGameLobby) { CryLog("[GameRules] Client trying to return to lobby"); pGameLobby->SvFinishedGame(frameTime); EnterPostGameState(ePGS_LeavingGame); } } #ifndef _RELEASE else if(g_pGameCVars->g_hud_postgame_debug && pRecordingSystem) { CryWatch("PostGameState - Waiting for highlight reel to end:"); CryWatch("IsPlaybackQueued: %s, IsPlayingBack: %s, IsPlayingHighlightsReel: %s", pRecordingSystem->IsPlaybackQueued() ? "True" : "False", pRecordingSystem->IsPlayingBack() ? "True" : "False", pRecordingSystem->IsPlayingHighlightsReel() ? "True" : "False"); } #endif break; } case ePGS_Top3: { if (m_timeInCurrentPostGameState > g_pGameCVars->g_gameRules_postGame_Top3Time) { EnterPostGameState(ePGS_Scoreboard); } break; } case ePGS_Scoreboard: { if(m_timeInCurrentPostGameState > g_pGameCVars->g_gameRules_postGame_ScoreboardTime) { if(!m_bHasShownHighlightReel && g_pGameCVars->kc_showHighlightsAtEndOfGame) { EnterPostGameState(ePGS_HighlightReel); } else { CGameLobby *pGameLobby = g_pGame->GetGameLobby(); if (pGameLobby) { CryLog("[GameRules] Client trying to return to lobby [No highlight reel]"); pGameLobby->SvFinishedGame(frameTime); } } } break; } } } } }