//------------------------------------------------------------------------ void CGameRulesHoldObjectiveBase::CleanUpEntity(SHoldEntityDetails *pDetails) { CCCPOINT(HoldObjective_CleanUpActiveCaptureEntity); if (pDetails->m_localPlayerIsWithinRange) { CHUDEventDispatcher::CallEvent(SHUDEvent(eHUDEvent_OnSiteAboutToExplode)); } OnRemoveHoldEntity(pDetails); gEnv->pEntitySystem->RemoveEntityEventListener(pDetails->m_id, ENTITY_EVENT_ENTERAREA, this); gEnv->pEntitySystem->RemoveEntityEventListener(pDetails->m_id, ENTITY_EVENT_LEAVEAREA, this); if (m_spawnPOIType == eSPT_Avoid) { IGameRulesSpawningModule *pSpawningModule = g_pGame->GetGameRules()->GetSpawningModule(); if (pSpawningModule) { pSpawningModule->RemovePOI(pDetails->m_id); } } IEntity *pEntity = gEnv->pEntitySystem->GetEntity(pDetails->m_id); if (pEntity) { IScriptTable *pScript = pEntity->GetScriptTable(); if (pScript != NULL && pScript->GetValueType("DeactivateCapturePoint") == svtFunction) { IScriptSystem *pScriptSystem = gEnv->pScriptSystem; pScriptSystem->BeginCall(pScript, "DeactivateCapturePoint"); pScriptSystem->PushFuncParam(pScript); pScriptSystem->PushFuncParam(true); pScriptSystem->EndCall(); } CGameRules *pGameRules = g_pGame->GetGameRules(); EGameMode gamemode = pGameRules->GetGameMode(); if (gamemode == eGM_CrashSite) { Announce("Destruct", k_announceType_CS_Destruct); } } pDetails->Reset(); // Fade out effect m_effectData.alphaLerp.Set(1.0f,0.0f,0.0f); }
//------------------------------------------------------------------------ void CGameRulesKingOfTheHillObjective::OnChangedTeam( EntityId entityId, int oldTeamId, int newTeamId ) { BaseType::OnChangedTeam(entityId, oldTeamId, newTeamId); if ((g_pGame->GetIGameFramework()->GetClientActorId() == entityId) && newTeamId) { // Local player has changed teams, reset icons int currActiveIndex = -1; for (int i = 0; i < HOLD_OBJECTIVE_MAX_ENTITIES; ++ i) { SHoldEntityDetails *pDetails = &m_entities[i]; if (pDetails->m_id) { SKotHEntity *pKotHEntity = static_cast<SKotHEntity *>(pDetails->m_pAdditionalData); CRY_ASSERT(pKotHEntity); pKotHEntity->m_needsIconUpdate = true; ++currActiveIndex; if (pDetails->m_controllingTeamId == 1 || pDetails->m_controllingTeamId == 2) { CRY_TODO( 23,03,2010, "HUD: OnSiteCaptured events are being sent multiple times from multiple places. /FH"); SHUDEvent siteIsCaptured(eHUDEvent_OnSiteCaptured); siteIsCaptured.eventIntData = currActiveIndex; siteIsCaptured.eventIntData2 = pDetails->m_controllingTeamId; CHUDEventDispatcher::CallEvent(siteIsCaptured); } IEntity *pEntity = gEnv->pEntitySystem->GetEntity(pDetails->m_id); if (pEntity) { IScriptTable *pScript = pEntity->GetScriptTable(); if (pScript && pScript->GetValueType("LocalPlayerChangedTeam") == svtFunction) { IScriptSystem *pScriptSystem = gEnv->pScriptSystem; pScriptSystem->BeginCall(pScript, "LocalPlayerChangedTeam"); pScriptSystem->PushFuncParam(pScript); pScriptSystem->EndCall(); } } } } } }
//------------------------------------------------------------------------ void CGameRules::ServerSimpleHit(const SimpleHitInfo &simpleHitInfo) { switch (simpleHitInfo.type) { case 0: // tag { if (!simpleHitInfo.targetId) { return; } // tagged entities are temporary in MP, not in SP. bool temp = gEnv->bMultiplayer; AddTaggedEntity(simpleHitInfo.shooterId, simpleHitInfo.targetId, temp); } break; case 1: // tac { if (!simpleHitInfo.targetId) { return; } CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(simpleHitInfo.targetId); if (pActor && pActor->CanSleep()) { pActor->Fall(Vec3(0.0f, 0.0f, 0.0f), simpleHitInfo.value); } } break; case 0xe: // freeze { if (!simpleHitInfo.targetId) { return; } // call OnFreeze bool allow = true; if (m_serverStateScript.GetPtr() && m_serverStateScript->GetValueType("OnFreeze") == svtFunction) { HSCRIPTFUNCTION func = 0; m_serverStateScript->GetValue("OnFreeze", func); Script::CallReturn(m_serverStateScript->GetScriptSystem(), func, m_script, ScriptHandle(simpleHitInfo.targetId), ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value, allow); gEnv->pScriptSystem->ReleaseFunc(func); } if (!allow) { return; } if (IEntity *pEntity = gEnv->pEntitySystem->GetEntity(simpleHitInfo.targetId)) { IScriptTable *pScriptTable = pEntity->GetScriptTable(); // call OnFrost if (pScriptTable && pScriptTable->GetValueType("OnFrost") == svtFunction) { HSCRIPTFUNCTION func = 0; pScriptTable->GetValue("OnFrost", func); Script::Call(pScriptTable->GetScriptSystem(), func, pScriptTable, ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value); gEnv->pScriptSystem->ReleaseFunc(func); } FreezeEntity(simpleHitInfo.targetId, true, true, simpleHitInfo.value > 0.999f); } } break; default: assert(!"Unknown Simple Hit type!"); } }
//------------------------------------------------------------------------ void CGameRulesHoldObjectiveBase::DoAddEntityId(int type, EntityId entityId, int index, bool isNewEntity) { CRY_ASSERT(index < HOLD_OBJECTIVE_MAX_ENTITIES); CryLog("CGameRulesHoldObjectiveBase::DoAddEntityId() received objective, eid=%i, index=%i", entityId, index); SHoldEntityDetails *pDetails = &m_entities[index]; pDetails->m_id = entityId; if (m_spawnPOIType == eSPT_Avoid) { IGameRulesSpawningModule *pSpawningModule = g_pGame->GetGameRules()->GetSpawningModule(); if (pSpawningModule) { pSpawningModule->AddAvoidPOI(entityId, m_spawnPOIDistance, true, AreObjectivesStatic()); } } OnNewHoldEntity(pDetails, index); CCCPOINT(HoldObjective_AddEntity); gEnv->pEntitySystem->AddEntityEventListener(entityId, ENTITY_EVENT_ENTERAREA, this); gEnv->pEntitySystem->AddEntityEventListener(entityId, ENTITY_EVENT_LEAVEAREA, this); if (gEnv->bServer) { CHANGED_NETWORK_STATE(g_pGame->GetGameRules(), HOLD_OBJECTIVE_STATE_ASPECT); } if(isNewEntity) { //Not playing for the first time because it clashes with game start Announce("Incoming", k_announceType_CS_Incoming, m_shouldPlayIncomingAudio); m_shouldPlayIncomingAudio = true; } IEntity *pEntity = gEnv->pEntitySystem->GetEntity(entityId); if (pEntity) { IScriptTable *pScript = pEntity->GetScriptTable(); CRY_TODO(11, 02, 2009, "function name from xml?"); if (pScript) { if (pScript->GetValueType("ActivateCapturePoint") == svtFunction) { if (isNewEntity) { // Set flag to say we're expecting a trackview to start - so we can set the start position in the callback m_bExpectingMovieStart = true; if (!m_bAddedMovieListener) { if (gEnv->pMovieSystem) { CryLog("CGameRulesHoldObjectiveBase::CGameRulesHoldObjectiveBase() adding movie listener"); gEnv->pMovieSystem->AddMovieListener(NULL, this); m_bAddedMovieListener = true; } } } IScriptSystem *pScriptSystem = gEnv->pScriptSystem; pScriptSystem->BeginCall(pScript, "ActivateCapturePoint"); pScriptSystem->PushFuncParam(pScript); pScriptSystem->PushFuncParam(isNewEntity); pScriptSystem->EndCall(); } SmartScriptTable propertiesTable; if (pScript->GetValue("Properties", propertiesTable)) { pDetails->m_controlRadius = 5.f; propertiesTable->GetValue("ControlRadius", pDetails->m_controlRadius); pDetails->m_controlRadiusSqr = (pDetails->m_controlRadius * pDetails->m_controlRadius); pDetails->m_controlHeight = 5.f; propertiesTable->GetValue("ControlHeight", pDetails->m_controlHeight); pDetails->m_controlOffsetZ = 0.f; propertiesTable->GetValue("ControlOffsetZ", pDetails->m_controlOffsetZ); } } const IActor *pLocalPlayer = g_pGame->GetIGameFramework()->GetClientActor(); if (pLocalPlayer != NULL && IsActorEligible(pLocalPlayer)) { CheckLocalPlayerInside(pDetails, pEntity, pLocalPlayer->GetEntity()); } } }
//------------------------------------------------------------------------ bool CGameRules::OnPromoteToServer(SHostMigrationInfo& hostMigrationInfo, uint32& state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLogAlways("[Host Migration]: CGameRules::OnPromoteToServer() started"); // Server time will change after we migrate (change from old server time to new server time) m_gameStartedTime.SetValue(m_gameStartedTime.GetValue() - m_cachedServerTime.GetValue()); m_gameStartTime.SetValue(m_gameStartTime.GetValue() - m_cachedServerTime.GetValue()); // If this migration has reset (we're not the original anticipated host, remove any entities from the first attempt if (!m_hostMigrationCachedEntities.empty()) { HostMigrationRemoveDuplicateDynamicEntities(); } // Now we know we're the server, remove the actors for anyone we know isn't going to migrate CGameLobby *pGameLobby = g_pGame->GetGameLobby(); CRY_ASSERT(pGameLobby); if (pGameLobby) { TPlayers playersToRemove; IActorSystem *pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem(); playersToRemove.reserve(pActorSystem->GetActorCount()); IActorIteratorPtr actorIt = pActorSystem->CreateActorIterator(); IActor *pActor; while (pActor = actorIt->Next()) { if (pActor->IsPlayer()) { CRY_ASSERT(pActor->GetChannelId()); SCryMatchMakingConnectionUID conId = pGameLobby->GetConnectionUIDFromChannelID((int) pActor->GetChannelId()); if (pGameLobby->GetSessionNames().Find(conId) == SSessionNames::k_unableToFind) { CryLog(" player '%s' has not got a corresponding CGameLobby entry, removing actor", pActor->GetEntity()->GetName()); playersToRemove.push_back(pActor->GetEntityId()); } } } const int numPlayersToRemove = playersToRemove.size(); for (int i = 0; i < numPlayersToRemove; ++ i) { FakeDisconnectPlayer(playersToRemove[i]); } } for (uint32 i = 0; i < MAX_PLAYERS; ++ i) { m_migratedPlayerChannels[i] = 0; } IItemSystem *pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); IEntityItPtr it = gEnv->pEntitySystem->GetEntityIterator(); it->MoveFirst(); for (uint32 i = 0; i < m_hostMigrationItemMaxCount; ++ i) { m_pHostMigrationItemInfo[i].Reset(); } uint32 itemIndex = 0; IEntity *pEntity = NULL; while (pEntity = it->Next()) { IItem *pItem = pItemSystem->GetItem(pEntity->GetId()); if (pItem) { if (pItem->GetOwnerId()) { IEntity *pOwner = gEnv->pEntitySystem->GetEntity(pItem->GetOwnerId()); if (pOwner) { EntityId currentItemId = 0; IActor *pOwnerActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pOwner->GetId()); if (pOwnerActor) { IItem *pCurrentItem = pOwnerActor->GetCurrentItem(); currentItemId = pCurrentItem ? pCurrentItem->GetEntityId() : 0; } CryLog("[CG] Item '%s' is owned by '%s'", pEntity->GetName(), pOwner->GetName()); //m_pHostMigrationItemInfo[itemIndex].Set(pEntity->GetId(), pOwner->GetId(), pItem->IsUsed(), (pItem->GetEntityId() == currentItemId)); itemIndex ++; if (itemIndex >= m_hostMigrationItemMaxCount) { CRY_ASSERT(itemIndex < m_hostMigrationItemMaxCount); break; } } } } // Tell entities that we're host migrating // - Currently only used by ForbiddenArea but may well be needed for other entities later // - Currently only called on the new server, add to OnDemoteToClient if we need to use this on a client IScriptTable *pScript = pEntity->GetScriptTable(); if (pScript != NULL && pScript->GetValueType("OnHostMigration") == svtFunction) { m_pScriptSystem->BeginCall(pScript, "OnHostMigration"); m_pScriptSystem->PushFuncParam(pScript); m_pScriptSystem->PushFuncParam(true); m_pScriptSystem->EndCall(); } } // This needs initialising on the new server otherwise the respawn timer will be counting down // from uninitialised data. Likewise for the pre-round timer. ResetReviveCycleTime(); const int numRespawnParams = m_respawndata.size(); for (int i = 0; i < numRespawnParams; ++ i) { SEntityRespawnData *pData = &m_respawndata[i]; pEntity = gEnv->pEntitySystem->GetEntity(pData->m_currentEntityId); if (pEntity == NULL) { CryLog(" detected respawn entity (id=%u) is not present, scheduling for respawn", pData->m_currentEntityId); ScheduleEntityRespawn(pData->m_currentEntityId, false, g_pGameCVars->g_defaultItemRespawnTimer); } } CryLog("[Host Migration]: CGameRules::OnPromoteToServer() finished"); CCCPOINT(HostMigration_OnPromoteToServer); return true; }
//------------------------------------------------------------------------ bool CGameRules::OnPromoteToServer(SHostMigrationInfo &hostMigrationInfo, uint32 &state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLogAlways("[Host Migration]: CGameRules::OnPromoteToServer() started"); // Server time will change after we migrate (change from old server time to new server time) m_gameStartedTime.SetValue(m_gameStartedTime.GetValue() - m_cachedServerTime.GetValue()); m_gameStartTime.SetValue(m_gameStartTime.GetValue() - m_cachedServerTime.GetValue()); // If this migration has reset (we're not the original anticipated host, remove any entities from the first attempt if (!m_hostMigrationCachedEntities.empty()) { HostMigrationRemoveDuplicateDynamicEntities(); } for (uint32 i = 0; i < MAX_PLAYERS; ++ i) { m_migratedPlayerChannels[i] = 0; } IEntityItPtr it = gEnv->pEntitySystem->GetEntityIterator(); it->MoveFirst(); for (uint32 i = 0; i < m_hostMigrationItemMaxCount; ++ i) { m_pHostMigrationItemInfo[i].Reset(); } uint32 itemIndex = 0; IEntity *pEntity = NULL; // Tell entities that we're host migrating // - Currently only used by ForbiddenArea but may well be needed for other entities later // - Currently only called on the new server, add to OnDemoteToClient if we need to use this on a client IScriptTable *pScript = pEntity->GetScriptTable(); if (pScript != NULL && pScript->GetValueType("OnHostMigration") == svtFunction) { m_pScriptSystem->BeginCall(pScript, "OnHostMigration"); m_pScriptSystem->PushFuncParam(pScript); m_pScriptSystem->PushFuncParam(true); m_pScriptSystem->EndCall(); } // This needs initialising on the new server otherwise the respawn timer will be counting down // from uninitialised data. Likewise for the pre-round timer. ResetReviveCycleTime(); // the server does not listen for entity_event_done, clients do however, when we migrate // the new server needs to remove any of these events he may be listening for TEntityTeamIdMap::iterator entityTeamsIt = m_entityteams.begin(); for (; entityTeamsIt != m_entityteams.end(); ++ entityTeamsIt) { EntityId entityId = entityTeamsIt->first; RemoveEntityEventDoneListener(entityId); #if !defined(_RELEASE) IEntity *pTeamEntity = gEnv->pEntitySystem->GetEntity(entityId); CryLog("[GameRules] OnPromoteToServer RemoveEntityEventLister(%d(%s), ENTITY_EVENT_DONE, %p)", entityId, pTeamEntity ? pTeamEntity->GetName() : "null", this); #endif } ClearRemoveEntityEventListeners(); const int numRespawnParams = m_respawndata.size(); for (int i = 0; i < numRespawnParams; ++ i) { SEntityRespawnData *pData = &m_respawndata[i]; pEntity = gEnv->pEntitySystem->GetEntity(pData->m_currentEntityId); if (pEntity == NULL) { CryLog(" detected respawn entity (id=%u) is not present, scheduling for respawn", pData->m_currentEntityId); ScheduleEntityRespawn(pData->m_currentEntityId, false, g_pGameCVars->g_defaultItemRespawnTimer); } } CryLog("[Host Migration]: CGameRules::OnPromoteToServer() finished"); CCCPOINT(HostMigration_OnPromoteToServer); return true; }