bool CGameStartup::InitFramework(SSystemInitParams &startupParams) { MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "Init Game Framework" ); #if !defined(_LIB) m_frameworkDll = GetFrameworkDLL(startupParams.szBinariesDir); if (!m_frameworkDll) { // failed to open the framework dll CryFatalError("Failed to open the GameFramework DLL!"); return false; } IGameFramework::TEntryFunction CreateGameFramework = (IGameFramework::TEntryFunction)CryGetProcAddress(m_frameworkDll, DLL_INITFUNC_CREATEGAME ); if (!CreateGameFramework) { // the dll is not a framework dll CryFatalError("Specified GameFramework DLL is not valid!"); return false; } #endif //_LIB m_pFramework = CreateGameFramework(); if (!m_pFramework) { CryFatalError("Failed to create the GameFramework Interface!"); // failed to create the framework return false; } #ifdef WIN32 if (startupParams.pSystem == NULL || (!startupParams.bEditor && !gEnv->IsDedicated())) { ::ShowCursor(FALSE); // Hide the cursor during loading (it will be shown again in Run()) } #endif // initialize the engine if (!m_pFramework->Init(startupParams)) { CryFatalError("Failed to initialize CryENGINE!"); return false; } ModuleInitISystem(m_pFramework->GetISystem(),"CryGame"); #ifdef WIN32 SetWindowLongPtr(reinterpret_cast<HWND>(gEnv->pRenderer->GetHWND()), GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); #endif return true; }
CScriptDomain::CScriptDomain(ERuntimeVersion runtimeVersion) : m_bRootDomain(true) , m_bDestroying(false) , m_name("root") { const char *version = "v2.0.50727"; switch(runtimeVersion) { case eRV_2_50215: version = "v2.0.50215"; break; case eRV_2_50727: break; case eRV_4_20506: version = "v4.0.20506"; break; case eRV_4_30128: version = "v4.0.30128"; break; case eRV_4_30319: version = "v4.0.30319"; break; } // Crashing on this line is an indicator of mono being incorrectly configured, Make sure Bin(32/64)/mono.exe, Bin(32/64)/mono-2.0.dll & Engine/Mono are up-to-date. m_pDomain = mono_jit_init_version("CryMono", version); if(!m_pDomain) CryFatalError("Failed to initialize root domain with runtime version %s!", version); }
void CView::CreateAudioListener() { if (m_pAudioListener == NULL) { SEntitySpawnParams oEntitySpawnParams; oEntitySpawnParams.sName = "SoundListener"; oEntitySpawnParams.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("SoundListener"); m_pAudioListener = gEnv->pEntitySystem->SpawnEntity(oEntitySpawnParams, true); if (m_pAudioListener != NULL) { m_pAudioListener->SetFlagsExtended(m_pAudioListener->GetFlagsExtended() | ENTITY_FLAG_EXTENDED_AUDIO_LISTENER); gEnv->pEntitySystem->AddEntityEventListener(m_pAudioListener->GetId(), ENTITY_EVENT_DONE, this); CryFixedStringT<64> sTemp; sTemp.Format("SoundListener(%d)", static_cast<int>(m_pAudioListener->GetId())); m_pAudioListener->SetName(sTemp.c_str()); IEntityAudioProxyPtr pIEntityAudioProxy = crycomponent_cast<IEntityAudioProxyPtr>(m_pAudioListener->CreateProxy(ENTITY_PROXY_AUDIO)); CRY_ASSERT(pIEntityAudioProxy.get()); } else { CryFatalError("<Sound>: audio listener creation failed in CView ctor!"); } } }
// ---------------------------------------------------------------------------- void CAnimActionTriState::Exit() { #ifndef _RELEASE if ( !m_entered ) CryFatalError( "CAnimActionTriState::Exit: Exit without Enter call" ); #endif TBase::Exit(); // -------------------------------------------------------------------------- // Movement Control Method const bool runningOnLayerZero = ( m_rootScope->GetBaseLayer() == 0 ); if ( runningOnLayerZero ) { CRY_ASSERT( m_mcmHorizontalOld != eMCM_Undefined ); CRY_ASSERT( m_mcmVerticalOld != eMCM_Undefined ); m_animChar.SetMovementControlMethods( m_mcmHorizontalOld, m_mcmVerticalOld ); } // -------------------------------------------------------------------------- // Collider Mode // TODO m_subState = eSS_Exit; SendTriStateEvent(Exit); }
void CView::CreateAudioListener() { if (m_pAudioListener == nullptr) { SEntitySpawnParams oEntitySpawnParams; oEntitySpawnParams.sName = "AudioListener"; oEntitySpawnParams.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("AudioListener"); m_pAudioListener = gEnv->pEntitySystem->SpawnEntity(oEntitySpawnParams, true); if (m_pAudioListener != nullptr) { // We don't want the audio listener to serialize as the entity gets completely removed and recreated during save/load! m_pAudioListener->SetFlags(m_pAudioListener->GetFlags() | (ENTITY_FLAG_TRIGGER_AREAS | ENTITY_FLAG_NO_SAVE)); m_pAudioListener->SetFlagsExtended(m_pAudioListener->GetFlagsExtended() | ENTITY_FLAG_EXTENDED_AUDIO_LISTENER); gEnv->pEntitySystem->AddEntityEventListener(m_pAudioListener->GetId(), ENTITY_EVENT_DONE, this); CryFixedStringT<64> sTemp; sTemp.Format("AudioListener(%d)", static_cast<int>(m_pAudioListener->GetId())); m_pAudioListener->SetName(sTemp.c_str()); IEntityAudioProxyPtr pIEntityAudioProxy = crycomponent_cast<IEntityAudioProxyPtr>(m_pAudioListener->CreateProxy(ENTITY_PROXY_AUDIO)); CRY_ASSERT(pIEntityAudioProxy.get()); } else { CryFatalError("<Audio>: Audio listener creation failed in CView::CreateAudioListener!"); } } else { m_pAudioListener->SetFlagsExtended(m_pAudioListener->GetFlagsExtended() | ENTITY_FLAG_EXTENDED_AUDIO_LISTENER); m_pAudioListener->InvalidateTM(ENTITY_XFORM_POS); } }
CAudioSystemImpl_sdlmixer::CAudioSystemImpl_sdlmixer() { m_sGameFolder = PathUtil::GetGameFolder(); if (m_sGameFolder.empty()) { CryFatalError("<Audio - SDLMixer>: Needs a valid game folder to proceed!"); } #if defined(INCLUDE_SDLMIXER_IMPL_PRODUCTION_CODE) m_sFullImplString = "SDL Mixer 2.0 ("; m_sFullImplString += m_sGameFolder + PathUtil::RemoveSlash(ms_sSDLSoundLibraryPath) + ")"; #endif // INCLUDE_SDLMIXER_IMPL_PRODUCTION_CODE #if defined(WIN32) || defined(WIN64) m_nMemoryAlignment = 16; #elif defined(MAC) m_nMemoryAlignment = 16; #elif defined(LINUX) && !defined(ANDROID) m_nMemoryAlignment = 16; #elif defined(IOS) m_nMemoryAlignment = 16; #elif defined(ANDROID) m_nMemoryAlignment = 16; #else #error "Undefined platform." #endif }
void CScriptTable::PushRef( IScriptTable *pObj ) { int nRef = ((CScriptTable*)pObj)->m_nRef; if (nRef != DELETED_REF) lua_getref( L,nRef ); else CryFatalError( "Access to deleted script object" ); }
bool CGameStartup::InitFramework(SSystemInitParams& startupParams) { MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "Init Game Framework" ); #if !defined(_LIB) m_frameworkDll = GetFrameworkDLL(startupParams.szBinariesDir); if (!m_frameworkDll) { CryFatalError("Failed to open the GameFramework DLL!"); return false; } IGameFramework::TEntryFunction CreateGameFramework = (IGameFramework::TEntryFunction)CryGetProcAddress(m_frameworkDll, DLL_INITFUNC_CREATEGAME); if (!CreateGameFramework) { CryFatalError("Specified GameFramework DLL is not valid!"); return false; } #endif m_pFramework = CreateGameFramework(); if (!m_pFramework) { CryFatalError("Failed to create the GameFramework Interface!"); return false; } if (!m_pFramework->Init(startupParams)) { CryFatalError("Failed to initialize CryENGINE!"); return false; } ModuleInitISystem(m_pFramework->GetISystem(), GAME_NAME); #if CRY_PLATFORM_WINDOWS SetWindowLongPtr(reinterpret_cast<HWND>(gEnv->pRenderer->GetHWND()), GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); #endif return true; }
IArea const* const CAreaManager::GetArea(size_t const nAreaIndex) const { #if defined(DEBUG_AREAMANAGER) if (nAreaIndex >= m_apAreas.size()) { CryFatalError("<AreaManager>: GetArea index out of bounds (Count: %d Index: %d)!", static_cast<int>(m_apAreas.size()), static_cast<int>(nAreaIndex)); } #endif // DEBUG_AREAMANAGER return static_cast<IArea*>(m_apAreas.at(nAreaIndex)); }
void CEntityAudioProxy::Reload(IEntity* pEntity, SEntitySpawnParams& params) { // Currently we do not need to do anything here. // Just make sure the EAP is properly initialized before this is called and that the parent entities match. #if defined(INCLUDE_ENTITYSYSTEM_PRODUCTION_CODE) if (pEntity == nullptr || m_pEntity == nullptr || pEntity != m_pEntity || pEntity->GetId() != m_pEntity->GetId()) { CryFatalError("<Audio> CEntityAudioProxy::Reload() while not being properly initialized yet!"); } #endif // INCLUDE_ENTITYSYSTEM_PRODUCTION_CODE }
/*static*/ void CRecordingSystem::ExtractCompleteStreamData( SKillCamStreamData& streamData, SPlaybackInstanceData& rPlaybackInstanceData, SFirstPersonDataContainer& rFirstPersonDataContainer ) { if(const size_t finalSize = streamData.GetFinalSize()) { SetFirstPersonData(streamData.m_buffer, finalSize, rPlaybackInstanceData, rFirstPersonDataContainer); streamData.Reset(); } #ifndef _RELEASE else { CryFatalError("Can't extract incomplete Stream Data."); } #endif //_RELEASE }
void CScriptTable::DeleteThis() { if (m_nRef == DELETED_REF) { assert(0); CryFatalError( "Attempt to Release already released script table." ); } #ifdef DEBUG_LUA_STATE gAllScriptTables.erase(this); #endif if (m_nRef != NULL_REF) lua_unref(L, m_nRef); m_nRef = DELETED_REF; delete this; }
bool CMouse::Init() { CryLog("Initializing mouse"); if (!CreateDirectInputDevice(&c_dfDIMouse2, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND, 4096)) return false; // Set mouse axis mode. DIPROPDWORD dipdw = {{sizeof(DIPROPDWORD), sizeof(DIPROPHEADER), 0, DIPH_DEVICE}, DIPROPAXISMODE_REL}; HRESULT hr = GetDirectInputDevice()->SetProperty( DIPROP_AXISMODE,&dipdw.diph ); if (FAILED(hr)) { CryFatalError( "CMouse::Init SetProperty DIPROP_AXISMODE failed." ); return false; } m_deltas.zero(); m_oldDeltas.zero(); m_deltasInertia.zero(); m_mouseWheel = 0.0f; Acquire(); // key mapping Symbol[eKI_Mouse1-KI_MOUSE_BASE] = MapSymbol(DIMOFS_BUTTON0, eKI_Mouse1, "mouse1"); Symbol[eKI_Mouse2-KI_MOUSE_BASE] = MapSymbol(DIMOFS_BUTTON1, eKI_Mouse2, "mouse2"); Symbol[eKI_Mouse3-KI_MOUSE_BASE] = MapSymbol(DIMOFS_BUTTON2, eKI_Mouse3, "mouse3"); Symbol[eKI_Mouse4-KI_MOUSE_BASE] = MapSymbol(DIMOFS_BUTTON3, eKI_Mouse4, "mouse4"); Symbol[eKI_Mouse5-KI_MOUSE_BASE] = MapSymbol(DIMOFS_BUTTON4, eKI_Mouse5, "mouse5"); Symbol[eKI_Mouse6-KI_MOUSE_BASE] = MapSymbol(DIMOFS_BUTTON5, eKI_Mouse6, "mouse6"); Symbol[eKI_Mouse7-KI_MOUSE_BASE] = MapSymbol(DIMOFS_BUTTON6, eKI_Mouse7, "mouse7"); Symbol[eKI_Mouse8-KI_MOUSE_BASE] = MapSymbol(DIMOFS_BUTTON7, eKI_Mouse8, "mouse8"); Symbol[eKI_MouseWheelUp-KI_MOUSE_BASE] = MapSymbol(_DIMOFS_WHEEL_UP, eKI_MouseWheelUp, "mwheel_up"); Symbol[eKI_MouseWheelDown-KI_MOUSE_BASE] = MapSymbol(_DIMOFS_WHEEL_DOWN, eKI_MouseWheelDown, "mwheel_down"); Symbol[eKI_MouseX-KI_MOUSE_BASE] = MapSymbol(DIMOFS_X, eKI_MouseX, "maxis_x", SInputSymbol::RawAxis); Symbol[eKI_MouseY-KI_MOUSE_BASE] = MapSymbol(DIMOFS_Y, eKI_MouseY, "maxis_y", SInputSymbol::RawAxis); Symbol[eKI_MouseZ-KI_MOUSE_BASE] = MapSymbol(DIMOFS_Z, eKI_MouseZ, "maxis_z", SInputSymbol::RawAxis); return true; }
void CScriptTable::PushRef() { if (m_nRef != DELETED_REF && m_nRef != NULL_REF) lua_getref(L,m_nRef); else { lua_pushnil(L); if (m_nRef == DELETED_REF) { assert(0 && "Access to deleted script object" ); CryFatalError( "Access to deleted script object %x",(unsigned int)(UINT_PTR)this ); } else { assert(0 && "Pushing Nil table reference"); ScriptWarning( "Pushing Nil table reference" ); } } }
void CServerKillCamForwarder::DropOldestPacket() { if (m_history.Empty()) { CryFatalError("We're trying to drop a packet to make space for new data but there's nothing left in the buffer\n"); } BufferType::iterator itPacket=m_history.Begin(); IActor *pActor=*(IActor**)m_history.GetData(sizeof(IActor*)); CActor::KillCamFPData *pPacket=(CActor::KillCamFPData*)m_history.GetData(sizeof(CActor::KillCamFPData)); // If packet in queue to be forwarded, send immediately before dropping for (std::deque<SForwardingPacket>::iterator it=m_forwarding.begin(), end=m_forwarding.end(); it!=end; ++it) { SForwardingPacket &forward=*it; if (forward.iterator<=itPacket && forward.pActor==pActor && forward.packetID==pPacket->m_packetId) { CryLog("Server forwarder queue is overflowing! Forcing packet send to free space\n"); ForwardPacket(forward, pPacket); } } }
//------------------------------------------------------------------------ void CGameRulesHoldObjectiveBase::AddEntityId(int type, EntityId entityId, int index, bool isNewEntity, const CTimeValue &timeAdded) { if(index >= HOLD_OBJECTIVE_MAX_ENTITIES) { CryFatalError("Too Many Hold Objective Entities Active!"); } CryLog("CGameRulesHoldObjectiveBase::AddEntityId() received objective, eid=%i, index=%i, isNewEntity=%s, fTimeAdded=%lld, adding to pending queue", entityId, index, isNewEntity ? "true" : "false", timeAdded.GetMilliSecondsAsInt64()); SHoldEntityDetails *pDetails = &m_entities[index]; if (pDetails->m_id) { // We're overwriting another entity, disable the old one CleanUpEntity(pDetails); } // Can't actually activate the entity here since the entity may not be fully initialised yet (horrible ordering issue on game restart), // instead set it as pending and do the actual add in the ::Update(...) method pDetails->m_pendingId = entityId; pDetails->m_isNewEntity = isNewEntity; m_pendingTimeAdded = timeAdded; }
void CRecordingSystem::ClProcessKillCamData(IActor *pActor, const CActor::KillCamFPData &packet) { // Receiver gets a second to validate the expectations. static float timeToValidateUnexpectedData = 1.f; // Find the existing StreamData for this packet. SKillCamStreamData* pStreamData = m_streamer.GetExpectedStreamData(packet.m_victim); // If it arrived before the kill was relayed to the client, then create false expectations of this data and store it in anticipation of validation. if(!pStreamData) { CryLogAlways("Receiving unexpected packet data. This is most likely because the data is arriving before the kill has been requested. Creating false expectations."); SKillCamExpectedData falseExpectations(pActor->GetEntityId(), packet.m_victim, packet.m_bToEveryone); pStreamData = m_streamer.ExpectStreamData(falseExpectations, false); if(!pStreamData) { CryFatalError("CRecordingSystem::ClProcessKillCamData: Cannot find free slot to add new receive data from: Sender[%d] Victim[%d]", falseExpectations.m_sender, falseExpectations.m_victim); } PREFAST_ASSUME(pStreamData); //validated above pStreamData->SetValidationTimer(timeToValidateUnexpectedData); } else { // Update the timer if it's still not been validated and we receive a new packet... if(pStreamData->IsValidationTimerSet()) { pStreamData->SetValidationTimer(timeToValidateUnexpectedData); } } if(pStreamData) { // Process the Packet. CRecordingSystem::ProcessKillCamData(pActor, packet, *pStreamData, true); } }
/*static*/ bool CRecordingSystem::ProcessKillCamData(IActor *pActor, const CActor::KillCamFPData &packet, SKillCamStreamData& rStreamData, const bool bFatalOnForwardedPackets) { //TODO: Check if we need some handling as these aren't cleanly divisible const int packetSize=CActor::KillCamFPData::DATASIZE; const int receiveBufferPackets=sizeof(rStreamData.m_buffer)/packetSize; EntityId actorId=pActor->GetEntityId(); CRY_ASSERT_MESSAGE(actorId==rStreamData.m_expect.m_sender, "Wrong Sender!"); CRY_ASSERT_MESSAGE(packet.m_victim==rStreamData.m_expect.m_victim, "Wrong Victim!"); CRY_ASSERT_MESSAGE(packet.m_bToEveryone==rStreamData.m_expect.m_winningKill, "Wrong Winning Kill!"); int packetNum=packet.m_numPacket; if (packet.m_packetType==CClientKillCamSender::KCP_NEWTHIRDPERSON) { // Grow third person data from the top packetNum=receiveBufferPackets-1-packetNum; if (packet.m_bFinalPacket) rStreamData.m_packetTargetNum[1]=packet.m_numPacket+1; rStreamData.m_packetReceived[1]++; } else if (packet.m_packetType==CClientKillCamSender::KCP_NEWFIRSTPERSON) { if (packet.m_bFinalPacket) rStreamData.m_packetTargetNum[0]=packet.m_numPacket+1; rStreamData.m_packetReceived[0]++; } else if(packet.m_packetType == CClientKillCamSender::KCP_FORWARD) { #ifndef _RELEASE if(bFatalOnForwardedPackets) CryFatalError("Received a Forwarded packet! We aren't using these at the moment!"); #endif //_RELEASE return false; } else { #ifndef _RELEASE CryFatalError("Received a client packet that we can't deal with\n"); #endif //_RELEASE return false; } memcpy(&rStreamData.m_buffer[packetNum*packetSize], packet.m_data, packet.m_size); if( rStreamData.m_packetReceived[0] == rStreamData.m_packetTargetNum[0] && rStreamData.m_packetReceived[1] == rStreamData.m_packetTargetNum[1]) // Fully received a stream { int totalPackets = rStreamData.m_packetTargetNum[0] + rStreamData.m_packetTargetNum[1]; assert(totalPackets<=receiveBufferPackets); // Reconstruct third person buffer in correct order for (int i=0; i<rStreamData.m_packetTargetNum[1]; i++) { int srcIdx=receiveBufferPackets-1-i; int dstIdx=rStreamData.m_packetTargetNum[0]+i; memcpy(&rStreamData.m_buffer[dstIdx*packetSize], &rStreamData.m_buffer[srcIdx*packetSize], packetSize); } rStreamData.m_finalSize = totalPackets*packetSize; return true; } return false; }
EntityId CGameRulesRSSpawning::GetBestSpawnUsingWeighting( SUsefulSpawnData& spawnData, const Vec3 * pBestLocation ) { float fBestScore = FLT_MAX; EntityId bestSpawnerId = 0; const Vec3 idealLocation = *pBestLocation; TPositionList FriendlyPositions, EnemyPositions; TMultiplierList FriendlyScoreMultipliers; FriendlyPositions.reserve(spawnData.numActiveFriendlyPlayers); FriendlyScoreMultipliers.reserve(spawnData.numActiveFriendlyPlayers); EnemyPositions.reserve(spawnData.numActiveEnemyPlayers); UpdateFriendlyPlayerPositionsAndMultipliers(spawnData, FriendlyPositions, FriendlyScoreMultipliers); UpdateEnemyPlayerPositions(spawnData, EnemyPositions); SpawnLogAlways("[SPAWN] Ideal location calculated as (%.2f, %.2f, %.2f)", idealLocation.x, idealLocation.y, idealLocation.z); int iSpawnIndex = 0; #if MONITOR_BAD_SPAWNS m_DBG_spawnData.scoringResults.clear(); #endif EntityId lastSpawnId = 0; Vec3 lastSpawnPos(ZERO); { TPlayerDataMap::iterator it = m_playerValues.find(spawnData.playerId); if (it != m_playerValues.end()) { lastSpawnId = it->second.lastSpawnLocationId; if(lastSpawnId) { IEntity * pLastSpawnEnt = gEnv->pEntitySystem->GetEntity(lastSpawnId); lastSpawnPos = pLastSpawnEnt->GetWorldPos(); } } } EntityId lastPrecachedSpawnId = 0; Vec3 lastPrecachedSpawnPos(ZERO); if(spawnData.playerId==g_pGame->GetClientActorId()) { if(IEntity* pLastPrecachedSpawnEnt = gEnv->pEntitySystem->GetEntity(m_currentBestSpawnId)) { lastPrecachedSpawnId = m_currentBestSpawnId; lastPrecachedSpawnPos = pLastPrecachedSpawnEnt->GetWorldPos(); } } TSpawnLocations& spawnLocations = GetSpawnLocations(spawnData.playerId); #if !defined(_RELEASE) int nWrongTeamSpawns = 0, nUnsafeSpawns = 0; #endif bool bCheckLineOfSight = !gEnv->IsDedicated(); for (TSpawnLocations::const_iterator it=spawnLocations.begin(); it!=spawnLocations.end(); ++it) { SpawnLogAlways("[SPAWN] Spawn #%d", iSpawnIndex); EntityId spawnId(*it); int spawnTeam=GetSpawnLocationTeam(spawnId); if ((spawnTeam == 0) || (spawnTeam == spawnData.playerTeamId)) { const IEntity *pSpawn = gEnv->pEntitySystem->GetEntity(spawnId); Vec3 spawnPosition = pSpawn->GetPos(); const float fScoreFromEnemies = GetScoreFromProximityToEnemies(spawnData, EnemyPositions, spawnPosition); const float fScoreFromFriendlies = GetScoreFromProximityToFriendlies(spawnData, FriendlyPositions, FriendlyScoreMultipliers, spawnPosition); const float fScoreFromIdealPosn = GetScoreFromProximityToIdealLocation(spawnData, idealLocation, spawnPosition); const float fScoreFromExclusions = GetScoreFromProximityToExclusionZones(spawnData, spawnId); const float fScoreFromLineOfSight = bCheckLineOfSight ? GetScoreFromLineOfSight(spawnData, spawnId) : 0.f; float fScoreFromLastSpawn = 0.0f; if(lastSpawnId != 0) fScoreFromLastSpawn = GetScoreFromProximityToPreviousSpawn(lastSpawnPos, spawnPosition); float fScoreFromLastSelectedSpawn = 0.0f; if(lastPrecachedSpawnId) fScoreFromLastSelectedSpawn = GetScoreFromProximityToLastPrecachedSpawn(lastPrecachedSpawnPos, spawnPosition); const float fScore = fScoreFromEnemies + fScoreFromFriendlies + fScoreFromIdealPosn + fScoreFromExclusions + fScoreFromLineOfSight + fScoreFromLastSpawn; #if MONITOR_BAD_SPAWNS m_DBG_spawnData.scoringResults.push_back(SScoringResults(fScoreFromEnemies, fScoreFromFriendlies, fScoreFromIdealPosn, fScoreFromLineOfSight > 0, fScoreFromExclusions > 0)); #endif if(fScore < fBestScore) { if(IsSpawnLocationSafe(spawnData.playerId, pSpawn, 1.0f, false, 0.0f)) { SpawnLogAlways("[SPAWN] >> Total score %.6f, better than previous best of %.6f", fScore, fBestScore); bestSpawnerId = spawnId; fBestScore = fScore; #if MONITOR_BAD_SPAWNS m_DBG_spawnData.iSelectedSpawnIndex = iSpawnIndex; m_DBG_spawnData.selectedSpawn = spawnId; #endif } else { #if !defined(_RELEASE) nUnsafeSpawns++; #endif SpawnLogAlways("[SPAWN] >> Total score %.6f, better than %.6f but UNSAFE", fScore, fBestScore); } } else { SpawnLogAlways("[SPAWN] >> Total score %.6f, too high, not using", fScore); } } else { #if !defined(_RELEASE) nWrongTeamSpawns++; #endif } iSpawnIndex++; } #if !defined(_RELEASE) if(bestSpawnerId == 0) { IEntity * pPlayer = gEnv->pEntitySystem->GetEntity(spawnData.playerId); CryFatalError("ERROR: No spawner found. Should ALWAYS find a spawn.\n Trying to spawn player EID %d, name '%s'.\n Player is %s spawning.\n %" PRISIZE_T " spawns found for spawn type, %d wrong team, %d unsafe", spawnData.playerId, pPlayer->GetName(), IsPlayerInitialSpawning(spawnData.playerId) ? "initial" : "normal", spawnLocations.size(), nWrongTeamSpawns, nUnsafeSpawns); } #endif return bestSpawnerId; }
//------------------------------------------------------------------------ SCreateChannelResult CGameServerNub::CreateChannel(INetChannel *pChannel, const char *pRequest) { CRY_ASSERT(m_maxPlayers); CGameServerChannel *pNewChannel; if (!pRequest) { CRY_ASSERT(false); SCreateChannelResult res(eDC_GameError); return res; } SParsedConnectionInfo info = m_pGameContext->ParseConnectionInfo(pRequest); if (!info.allowConnect) { GameWarning( "Not allowed to connect to server: %s", info.errmsg.c_str() ); SCreateChannelResult res(info.cause); cry_strcpy(res.errorMsg, info.errmsg.c_str()); return res; } if (int(m_channels.size()) >= m_maxPlayers) { SCreateChannelResult res(eDC_ServerFull); cry_strcpy(res.errorMsg, string().Format("Disallowing more than %d players",m_maxPlayers).c_str()); return res; } if (info.isMigrating && CCryAction::GetCryAction()->IsGameSessionMigrating()) { pChannel->SetMigratingChannel(true); } pNewChannel = GetOnHoldChannelFor(pChannel); if (!pNewChannel) { pNewChannel = new CGameServerChannel(pChannel, m_pGameContext, this); if (pChannel->GetSession() != CrySessionInvalidHandle) { // There is a valid CrySessionHandle created by the lobby so use this as the channel id // as it contains information that can identify the connection in the lobby. pNewChannel->SetChannelId(pChannel->GetSession()); } else { // No valid CrySessionHandle so create an id here. pNewChannel->SetChannelId(++m_genId); } if (m_channels.find(pNewChannel->GetChannelId()) != m_channels.end()) { CryFatalError("CGameServerNub::CreateChannel: Trying to create channel with duplicate id %d", pNewChannel->GetChannelId()); } m_channels.insert(TServerChannelMap::value_type(pNewChannel->GetChannelId(), pNewChannel)); } else { pNewChannel->SetNetChannel(pChannel); #if !NEW_BANDWIDTH_MANAGEMENT pNewChannel->SetupNetChannel(pChannel); #endif // NEW_BANDWIDTH_MANAGEMENT } ICVar* pPass = gEnv->pConsole->GetCVar("sv_password"); if (pPass && gEnv->bMultiplayer) { pChannel->SetPassword(pPass->GetString()); } pChannel->SetNickname(info.playerName.c_str()); // Host migration if (info.isMigrating && CCryAction::GetCryAction()->IsGameSessionMigrating()) { // Enable the game rules to find the migrating player details by channel id IGameFramework *pGameFramework = gEnv->pGame->GetIGameFramework(); IGameRules *pGameRules = pGameFramework->GetIGameRulesSystem()->GetCurrentGameRules(); if(pGameRules) { EntityId playerID = pGameRules->SetChannelForMigratingPlayer(info.playerName.c_str(), pNewChannel->GetChannelId()); if (playerID) { CryLog("CGameServerNub::CreateChannel() assigning actor %d '%s' to channel %d", playerID, info.playerName.c_str(), pNewChannel->GetChannelId()); pNewChannel->SetPlayerId(playerID); } else { CryLog("CGameServerNub::CreateChannel() failed to assign actor '%s' to channel %d", info.playerName.c_str(), pNewChannel->GetChannelId()); } } else { CryLog("[host migration] terminating because game rules is NULL, game session migrating %d session 0x%08x", CCryAction::GetCryAction()->IsGameSessionMigrating(), pChannel->GetSession()); gEnv->pNetwork->TerminateHostMigration(pChannel->GetSession()); } } m_netchannels.insert(TNetServerChannelMap::value_type(pChannel, pNewChannel->GetChannelId())); return SCreateChannelResult(pNewChannel); }
EContextEstablishTaskResult OnStep(SContextEstablishState& state) { IActionMapManager *pActionMapMan = CCryAction::GetCryAction()->GetIActionMapManager(); CRY_ASSERT(pActionMapMan); IActionMap* pDefaultActionMap = NULL; IActionMap* pDebugActionMap = NULL; IActionMap* pPlayerActionMap = NULL; IActionMap* pPlayerGamemodeActionMap = NULL; const char* disableGamemodeActionMapName = "player_mp"; const char* gamemodeActionMapName = "player_sp"; if(gEnv->bMultiplayer) { disableGamemodeActionMapName = "player_sp"; gamemodeActionMapName = "player_mp"; } if (true) { IPlayerProfileManager* pPPMgr = CCryAction::GetCryAction()->GetIPlayerProfileManager(); if (pPPMgr) { int userCount = pPPMgr->GetUserCount(); IPlayerProfile* pProfile = NULL; const char* userId = "UNKNOWN"; if (userCount == 0) { if (gEnv->pSystem->IsDevMode()) { #ifndef _RELEASE //In devmode and not release get the default user if no users are signed in e.g. autotesting, map on the command line pProfile = pPPMgr->GetDefaultProfile(); if (pProfile) { userId = pProfile->GetUserId(); } #endif // #ifndef _RELEASE } else { CryFatalError("[PlayerProfiles] CGameContext::StartGame: No users logged in"); return eCETR_Failed; } } if (userCount > 0) { IPlayerProfileManager::SUserInfo info; pPPMgr->GetUserInfo(0, info); pProfile = pPPMgr->GetCurrentProfile(info.userId); userId = info.userId; } if (pProfile) { pDefaultActionMap = pProfile->GetActionMap("default"); pDebugActionMap = pProfile->GetActionMap("debug"); pPlayerActionMap = pProfile->GetActionMap("player"); if (pDefaultActionMap == 0 && pPlayerActionMap == 0) { CryFatalError("[PlayerProfiles] CGameContext::StartGame: User '%s' has no actionmap 'default'!", userId); return eCETR_Failed; } } else { CryFatalError("[PlayerProfiles] CGameContext::StartGame: User '%s' has no active profile!", userId); return eCETR_Failed; } } else { CryFatalError("[PlayerProfiles] CGameContext::StartGame: No player profile manager!"); return eCETR_Failed; } } if (pDefaultActionMap == 0 ) { // use action map without any profile stuff pActionMapMan->EnableActionMap( "default", true ); pDefaultActionMap = pActionMapMan->GetActionMap("default"); CRY_ASSERT_MESSAGE(pDefaultActionMap, "'default' action map not found!"); } if (pDebugActionMap == 0 ) { // use action map without any profile stuff pActionMapMan->EnableActionMap( "debug", true ); pDebugActionMap = pActionMapMan->GetActionMap("debug"); } if (pPlayerActionMap == 0) { pActionMapMan->EnableActionMap( "player", true ); pPlayerActionMap = pActionMapMan->GetActionMap("player"); } if (!pDefaultActionMap) return eCETR_Failed; EntityId actorId = GetListener(); if (!actorId) return eCETR_Wait; if(pDefaultActionMap) { pDefaultActionMap->SetActionListener( actorId ); } if(pDebugActionMap) { pDebugActionMap->SetActionListener( actorId ); } if(pPlayerActionMap) { pPlayerActionMap->SetActionListener( actorId ); } pActionMapMan->EnableActionMap(disableGamemodeActionMapName, false); pActionMapMan->EnableActionMap(gamemodeActionMapName, true); pPlayerGamemodeActionMap = pActionMapMan->GetActionMap(gamemodeActionMapName); if(pPlayerGamemodeActionMap) { pPlayerGamemodeActionMap->SetActionListener(actorId); } // TODO: callback to game code for game specific action maps { IActionMap* crysis2_common = pActionMapMan->GetActionMap("crysis2_common"); if (crysis2_common != NULL) crysis2_common->SetActionListener( actorId ); IActionMap* crysis2_suitmenu_opened = pActionMapMan->GetActionMap("crysis2_suitmenu_opened"); if (crysis2_suitmenu_opened != NULL) crysis2_suitmenu_opened->SetActionListener( actorId ); IActionMap* crysis2_suitmenu_closed = pActionMapMan->GetActionMap("crysis2_suitmenu_closed"); if (crysis2_suitmenu_closed != NULL) crysis2_suitmenu_closed->SetActionListener( actorId ); IActionMap* player_cine = pActionMapMan->GetActionMap("player_cine"); if (player_cine != NULL) player_cine->SetActionListener( actorId ); IActionMap* booss_duell = pActionMapMan->GetActionMap("boss_duell"); if (booss_duell != NULL) booss_duell->SetActionListener( actorId ); } CCryAction::GetCryAction()->GetIActionMapManager()->Enable(true); return eCETR_Ok; }
bool CAreaManager::QueryAudioAreas(Vec3 const& rPos, SAudioAreaInfo *pResults, size_t const nMaxResults, size_t& rNumResults) { rNumResults = 0; if (pResults != NULL) { // Make sure the area grid is recompiled, if needed, before accessing it UpdateDirtyAreas(); uint32 numAreas = 0; TAreaPointers const& rAreasAtPos(m_areaGrid.GetAreas(rPos)); TAreaPointers::const_iterator IterAreas(rAreasAtPos.begin()); TAreaPointers::const_iterator const IterAreasEnd(rAreasAtPos.end()); for (; IterAreas != IterAreasEnd; ++IterAreas) { CArea* const pArea = *IterAreas; #if defined(DEBUG_AREAMANAGER) if (!stl::find(m_apAreas, pArea)) { CryFatalError("<AreaManager>: area in entity-area-cache not found in overall areas list!"); } #endif // DEBUG_AREAMANAGER // check if Area is hidden IEntity const* const pAreaEntity = m_pEntitySystem->GetEntity(pArea->GetEntityID()); if (pAreaEntity && !pAreaEntity->IsHidden()) { size_t const nAttachedEntities = pArea->GetEntityAmount(); if (nAttachedEntities > 0) { for (size_t iEntity = 0; iEntity < nAttachedEntities; ++iEntity) { IEntity const* const pEntity = gEnv->pEntitySystem->GetEntity(pArea->GetEntityByIdx(iEntity)); if (pEntity != NULL) { IEntityAudioProxy const* const pAudioProxy = (IEntityAudioProxy*)pEntity->GetProxy(ENTITY_PROXY_AUDIO); if (pAudioProxy != NULL) { TAudioEnvironmentID const nEnvironmentID = pAudioProxy->GetEnvironmentID(); float const fEnvironmentFadeDistance = pAudioProxy->GetEnvironmentFadeDistance(); if (nEnvironmentID != INVALID_AUDIO_ENVIRONMENT_ID) { // This is optimized internally and might not recalculate but rather retrieve the cached data. bool const bIsPointWithin = (pArea->CalcPosType(INVALID_ENTITYID, rPos, false) == AREA_POS_TYPE_2DINSIDE_ZINSIDE); float fEnvironmentAmount = 0.0f; if (!bIsPointWithin && (fEnvironmentFadeDistance > 0.0f)) { Vec3 Closest3d(ZERO); float const fDistance = sqrt_tpl(pArea->CalcPointNearDistSq(INVALID_ENTITYID, rPos, Closest3d, false)); if (fDistance <= fEnvironmentFadeDistance) { fEnvironmentAmount = 1.0f - (fDistance/fEnvironmentFadeDistance); } } else { fEnvironmentAmount = 1.0f; } if (fEnvironmentAmount > 0.0f) { // still have room to put it in? if (rNumResults == nMaxResults) return false; // found area that should go into the results pResults[rNumResults].pArea = pArea; pResults[rNumResults].fEnvironmentAmount = fEnvironmentAmount; pResults[rNumResults].nEnvironmentID = nEnvironmentID; pResults[rNumResults].nEnvProvidingEntityID = pEntity->GetId(); ++rNumResults; } } } } } } } } return true; } return false; }
bool CAreaManager::QueryAreas(EntityId const nEntityID, Vec3 const& rPos, SAreaManagerResult *pResults, int nMaxResults, int& rNumResults) { rNumResults = 0; if (pResults) { // Make sure the area grid is recompiled, if needed, before accessing it UpdateDirtyAreas(); uint32 numAreas = 0; TAreaPointers const& rAreasAtPos(m_areaGrid.GetAreas(rPos)); TAreaPointers::const_iterator IterAreas(rAreasAtPos.begin()); TAreaPointers::const_iterator const IterAreasEnd(rAreasAtPos.end()); for (; IterAreas != IterAreasEnd; ++IterAreas) { CArea* const pArea = *IterAreas; #if defined(DEBUG_AREAMANAGER) if (!stl::find(m_apAreas, pArea)) { CryFatalError("<AreaManager>: area in entity-area-cache not found in overall areas list!"); } #endif // DEBUG_AREAMANAGER // check if Area is hidden IEntity const* const pAreaEntity = m_pEntitySystem->GetEntity(pArea->GetEntityID()); if (pAreaEntity && !pAreaEntity->IsHidden()) { Vec3 Closest3d(ZERO); float const fGreatestFadeDistance = pArea->GetGreatestFadeDistance(); // This is optimized internally and might not recalculate but rather retrieve the cached data. float const fDistanceSq = pArea->CalcPointNearDistSq(nEntityID, rPos, Closest3d, false); bool const bIsPointWithin = (pArea->CalcPosType(nEntityID, rPos, false) == AREA_POS_TYPE_2DINSIDE_ZINSIDE); bool const isNear = ((fDistanceSq > 0.0f) && (fDistanceSq < fGreatestFadeDistance*fGreatestFadeDistance)); if (isNear || bIsPointWithin) { // still have room to put it in? if (rNumResults == nMaxResults) return false; // found area that should go into the results pResults[rNumResults].pArea = pArea; pResults[rNumResults].fDistanceSq = fDistanceSq; pResults[rNumResults].vPosOnHull = Closest3d; pResults[rNumResults].bInside = bIsPointWithin; pResults[rNumResults].bNear = isNear; ++rNumResults; } } } return true; } return false; }
void CAreaManager::UpdateEntity(Vec3 const& rPos, IEntity const* const pEntity) { EntityId const nEntityID = pEntity->GetId(); SAreasCache* pAreaCache = GetAreaCache(nEntityID); // Create a new area cache if necessary. if (pAreaCache == NULL) { pAreaCache = MakeAreaCache(nEntityID); } assert(pAreaCache != NULL); // Audio listeners and moving entities affected by environment changes need to update more often // to ensure smooth fading. uint32 const nExtendedFlags = pEntity->GetFlagsExtended(); float const fPosDelta = ((nExtendedFlags & ENTITY_FLAG_EXTENDED_AUDIO_LISTENER) != 0) || ((nExtendedFlags & ENTITY_FLAG_EXTENDED_NEEDS_MOVEINSIDE) != 0) ? 0.01f : CVar::es_EntityUpdatePosDelta; if (pAreaCache != NULL && !rPos.IsEquivalent(pAreaCache->vLastUpdatePos, fPosDelta)) { pAreaCache->vLastUpdatePos = rPos; // First mark all cache entries that as if they are not in the grid. TAreaCacheVector::iterator Iter(pAreaCache->aoAreas.begin()); TAreaCacheVector::const_iterator IterEnd(pAreaCache->aoAreas.end()); for (; Iter != IterEnd; ++Iter) { SAreaCacheEntry& rAreaCacheEntry = (*Iter); CArea* const pArea = rAreaCacheEntry.pArea; #if defined(DEBUG_AREAMANAGER) if (!stl::find(m_apAreas, pArea)) { CryFatalError("<AreaManager>: area in entity-area-cache not found in overall areas list!"); } #endif // DEBUG_AREAMANAGER rAreaCacheEntry.bInGrid = false; // Now pre-calculate position data. pArea->InvalidateCachedAreaData(nEntityID); pArea->CalcPosType(nEntityID, rPos); } TAreaPointers const& rAreasAtPos(m_areaGrid.GetAreas(rPos)); TAreaPointers::const_iterator IterAreas(rAreasAtPos.begin()); TAreaPointers::const_iterator const IterAreasEnd(rAreasAtPos.end()); for (; IterAreas != IterAreasEnd; ++IterAreas) { // Mark cache entries as if they are in the grid. CArea* const pArea = *IterAreas; SAreaCacheEntry* pAreaCacheEntry = NULL; if (pAreaCache->GetCacheEntry(pArea, &pAreaCacheEntry)) { // cppcheck-suppress nullPointer pAreaCacheEntry->bInGrid = true; } else { // if they are not yet in the cache, add them pAreaCache->aoAreas.push_back(SAreaCacheEntry(pArea, false, false)); pArea->OnAddedToAreaCache(pEntity); } #if defined(DEBUG_AREAMANAGER) if (!stl::find(m_apAreas, pArea)) { CryFatalError("<AreaManager>: area in entity-area-cache not found in overall areas list!"); } #endif // DEBUG_AREAMANAGER } // Go through all cache entries and process the areas. Iter = pAreaCache->aoAreas.begin(); IterEnd = pAreaCache->aoAreas.end(); for (; Iter != IterEnd; ++Iter) { SAreaCacheEntry& rAreaCacheEntry = (*Iter); CArea* const pArea = rAreaCacheEntry.pArea; #if defined(DEBUG_AREAMANAGER) if (!stl::find(m_apAreas, pArea)) { CryFatalError("<AreaManager>: area in entity-area-cache not found in overall areas list!"); } #endif // DEBUG_AREAMANAGER // check if Area is hidden IEntity const* const pAreaEntity = m_pEntitySystem->GetEntity(pArea->GetEntityID()); bool bIsHidden = (pAreaEntity && pAreaEntity->IsHidden()); // area was just hidden if (bIsHidden && pArea->IsActive()) { pArea->LeaveArea(pEntity); pArea->LeaveNearArea(pEntity); rAreaCacheEntry.bNear = false; rAreaCacheEntry.bInside = false; pArea->SetActive(false); continue; } // area was just unhidden if (!bIsHidden && !pArea->IsActive()) { // ProcessArea will take care of properly setting cache entry data. rAreaCacheEntry.bNear = false; rAreaCacheEntry.bInside = false; pArea->SetActive(true); } // We process only for active areas in which grid we are. // Areas in our cache in which grid we are not get removed down below anyhow. if (pArea->IsActive()) { ProcessArea(pArea, rAreaCacheEntry, pAreaCache, rPos, pEntity); } } // Go through all areas again and send accumulated events. (needs to be done in a separate step) Iter = pAreaCache->aoAreas.begin(); for (; Iter != IterEnd; ++Iter) { SAreaCacheEntry& rAreaCacheEntry = (*Iter); CArea* const pArea = rAreaCacheEntry.pArea; #if defined(DEBUG_AREAMANAGER) if (!stl::find(m_apAreas, pArea)) { CryFatalError("<AreaManager>: area in entity-area-cache not found in overall areas list!"); } #endif // DEBUG_AREAMANAGER pArea->SendCachedEventsFor(nEntityID); } // Remove all entries in the cache which are no longer in the grid. if (!pAreaCache->aoAreas.empty()) { pAreaCache->aoAreas.erase(std::remove_if(pAreaCache->aoAreas.begin(), pAreaCache->aoAreas.end(), SIsNotInGrid(pEntity, m_apAreas, m_apAreas.size())), pAreaCache->aoAreas.end()); } if (pAreaCache->aoAreas.empty()) { DeleteAreaCache(nEntityID); } } }
bool CGameStartup::InitFramework(SSystemInitParams &startupParams) { #if !defined(_LIB) && !defined(PS3) m_frameworkDll = GetFrameworkDLL(startupParams.szBinariesDir); if (!m_frameworkDll) { // failed to open the framework dll CryFatalError("Failed to open the GameFramework DLL!"); return false; } IGameFramework::TEntryFunction CreateGameFramework = (IGameFramework::TEntryFunction)CryGetProcAddress(m_frameworkDll, DLL_INITFUNC_CREATEGAME ); if (!CreateGameFramework) { // the dll is not a framework dll CryFatalError("Specified GameFramework DLL is not valid!"); return false; } #endif //_LIB m_pFramework = CreateGameFramework(); if (!m_pFramework) { CryFatalError("Failed to create the GameFramework Interface!"); // failed to create the framework return false; } if (!startupParams.hWnd && !startupParams.bEditor) { m_initWindow = true; if (!InitWindow(startupParams)) { // failed to register window class CryFatalError("Failed to register CryENGINE window class!"); return false; } } #if defined(WIN32) && !defined(XENON) else if (startupParams.bBrowserMode) SubclassWindow((HWND)startupParams.hWnd, (WNDPROC)CGameStartup::WndProc); #endif // initialize the engine if (!m_pFramework->Init(startupParams)) { CryFatalError("Failed to initialize CryENGINE!"); return false; } ModuleInitISystem(m_pFramework->GetISystem(),"CryGame"); gEnv->pGameFramework = m_pFramework; return true; }
//------------------------------------------------------------------------ // returns true if entity is killed, false if it is not bool CGameRulesMPDamageHandling::SvOnHit( const HitInfo &hitInfo ) { const HitTypeInfo * pHitTypeInfo = m_pGameRules->GetHitTypeInfo(hitInfo.type); #if !defined(_RELEASE) if(!pHitTypeInfo) CryFatalError("By ::SvOnHit() all hit info should have a hit type that is valid and registered in the GameRules. This isn't true of type %d!", hitInfo.type); #endif SDamageHandling damageHandling(&hitInfo, 1.0f); float damage = hitInfo.damage; IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem(); CActor *pTargetActor = static_cast<CActor*>(pActorSystem->GetActor(hitInfo.targetId)); CActor *pShooterActor = static_cast<CActor*>(pActorSystem->GetActor(hitInfo.shooterId)); CPlayer* pShooterPlayer = (pShooterActor && pShooterActor->IsPlayer()) ? static_cast<CPlayer*>(pShooterActor) : NULL ; bool isPlayer = pTargetActor != NULL && pTargetActor->IsPlayer(); #ifndef _RELEASE //--- Fix to allow the damage handling to work for these entity classes in the same way as for Players static IEntityClass* sDamEntClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("DamageTestEnt"); isPlayer |= pTargetActor != NULL && pTargetActor->GetEntity()->GetClass() == sDamEntClass; #endif CPlayer* pPlayer = isPlayer ? static_cast<CPlayer*>(pTargetActor) : NULL; const bool isMelee = ((pHitTypeInfo->m_flags & CGameRules::EHitTypeFlag::IsMeleeAttack) != 0); const bool checkHeadshots = ((pHitTypeInfo->m_flags & CGameRules::EHitTypeFlag::IgnoreHeadshots) == 0); bool bIsHeadShot = false; if(pPlayer && hitInfo.partId >= 0 && checkHeadshots) { bIsHeadShot = pPlayer->IsHeadShot(hitInfo); if (!bIsHeadShot && g_pGameCVars->g_mpHeadshotsOnly) { damage = 0.f; } } //If the player has died more than kTimeToAllowKillsAfterDeath seconds ago, we disallow any damage they apply, unless the hit type is flagged as allowing it. static const float kTimeToAllowKillsAfterDeath = 0.05f; if(pTargetActor && pShooterPlayer && !hitInfo.hitViaProxy && ((pHitTypeInfo->m_flags & CGameRules::EHitTypeFlag::AllowPostDeathDamage) == 0) && pShooterActor->IsDead() && (gEnv->pTimer->GetFrameStartTime().GetSeconds() - pShooterPlayer->GetDeathTime()) > kTimeToAllowKillsAfterDeath) { damage = 0.0f; } IGameRulesStateModule *stateModule = m_pGameRules->GetStateModule(); IGameRulesRoundsModule* pRoundsModule = m_pGameRules->GetRoundsModule(); if ( (stateModule != NULL && (stateModule->GetGameState() == IGameRulesStateModule::EGRS_PostGame)) || (pRoundsModule!= NULL && !pRoundsModule->IsInProgress() )) { // No damage allowed once the game has ended, except in cases where it would cause graphical glitches if (hitInfo.type != CGameRules::EHitType::PunishFall) { damage = 0.0f; } } IEntity *pTarget = gEnv->pEntitySystem->GetEntity(hitInfo.targetId); #if defined(SERVER_CHECKS) if(damage != 0.0f) { int nNewCheckCounter = m_checkCounter + 1; if (CItem *pItem = static_cast<CItem *>(g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(hitInfo.weaponId))) { if(CWeapon * pWeapon = static_cast<CWeapon*>(pItem->GetIWeapon())) { int nFireModeFromShotId = GetFireModeFromShotId(hitInfo.shotId); static const int kCheckFreq = 7; if(pShooterActor && nNewCheckCounter == kCheckFreq) { float fDamageAtXMeters = 0.0f; float fDistance2D, fDistanceMax, fNetLagSeconds; CServerCheatMonitor::GetHitValidationInfo(*pShooterActor, hitInfo, fDistance2D, fDistanceMax, fNetLagSeconds); bool bDoDamageValidation = false; if(isMelee) { if(CMelee * pMelee = pWeapon->GetMelee()) { //This check can't be used for everything because the default firemode returns '0.f' for range and only CMelee extends it // the horizontal player speed is x 2.0f as the players could have potentially immediately turned and run away from each other float fMeleeRangeError = fDistance2D - (pMelee->GetRange() + (CServerCheatMonitor::kMaxHorizontalPlayerSpeed * fNetLagSeconds * 2.0f)); if(fMeleeRangeError > 0.1f) { g_pGame->GetAntiCheatManager()->FlagActivity(eCT_MeleeRange, pShooterActor->GetChannelId(), fMeleeRangeError); } fDamageAtXMeters = pMelee->GetDamageAmountAtXMeters(fDistance2D); bDoDamageValidation = true; } } else { ////////////////////////////////////////////////////////////////////// // Verify that the hit is from a valid shot DoShotValidation(hitInfo, pHitTypeInfo, pShooterActor); ////////////////////////////////////////////////////////////////////// CFireMode * pFireMode = static_cast<CFireMode*>(pWeapon->GetFireMode(nFireModeFromShotId)); if(pFireMode) { const SFireModeParams * pParams = pFireMode->GetShared(); char projectileClassName[128]; g_pGame->GetIGameFramework()->GetNetworkSafeClassName(projectileClassName, sizeof(projectileClassName), hitInfo.projectileClassId); IEntityClass * pProjectileClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(projectileClassName); if((pProjectileClass && (pProjectileClass == pParams->fireparams.ammo_type_class || pProjectileClass == pParams->plantparams.ammo_type_class))) { float fBulletSpeed = 100.f; const SAmmoParams * pAmmoParams = g_pGame->GetWeaponSystem()->GetAmmoParams(pFireMode->GetAmmoType()); if(pAmmoParams) { fBulletSpeed = pAmmoParams->speed; } //Might have been closer when the shot was fired const float fMaxTimeSinceShot = ((fDistanceMax / fBulletSpeed) * 2.0f) + fNetLagSeconds; //Should be less than this. Laaaaarge fudge factor float fDistance_Conservative = fDistance2D - (fMaxTimeSinceShot * CServerCheatMonitor::kMaxHorizontalPlayerSpeed); fDamageAtXMeters = pFireMode->GetDamageAmountAtXMeters(fDistance_Conservative); } } else if(pHitTypeInfo->m_flags & CGameRules::EHitTypeFlag::ValidationRequired) { CryStackStringT<char, 256> invalidFireModeMessage; invalidFireModeMessage.Format("Invalid fire mode, weapon: '%s', firemode: %d", pWeapon->GetEntity()->GetName(), nFireModeFromShotId); g_pGame->GetAntiCheatManager()->FlagActivity(eCT_ValidHitInfo, pShooterActor->GetChannelId(), invalidFireModeMessage.c_str()); } } float fDamageFromWeapon = hitInfo.damage; if(fDamageFromWeapon > fDamageAtXMeters && fDamageAtXMeters > 0.0f) { //Log the ratio of actual damage to expected damage, e.g. 1.2 x expected CryStackStringT<char, 256> excessiveDamageMessage; excessiveDamageMessage.Format("Weapon '%s', firemode %d", pWeapon->GetEntity()->GetName(), nFireModeFromShotId); g_pGame->GetAntiCheatManager()->FlagActivity(eCT_WeaponDamage, pShooterActor->GetChannelId(), fDamageFromWeapon / fDamageAtXMeters, excessiveDamageMessage.c_str()); } if(pTargetActor) { CServerCheatMonitor::ValidateTargetActorPositionAgainstHit(*pTargetActor, hitInfo, fNetLagSeconds); } nNewCheckCounter = 0; } else { nNewCheckCounter = kCheckFreq - 1; } } } m_checkCounter = nNewCheckCounter; } // Update the shotcounter for tracking headshots and traversal times if(pShooterPlayer && (pHitTypeInfo->m_flags & CGameRules::EHitTypeFlag::ValidationRequired)) { char netName[128]; g_pGame->GetIGameFramework()->GetNetworkSafeClassName(netName, sizeof(netName), hitInfo.projectileClassId); IEntityClass * pProjectileClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(netName); if (pProjectileClass) { CShotCounter* pShotCounter = pShooterPlayer->GetShotCounter(); pShotCounter->RecordHit(hitInfo, bIsHeadShot); } } #endif // SERVER_CHECKS IEntityClass* pTargetClass = pTarget ? pTarget->GetClass() : NULL; // Check for friendly fire if( bool bCheckFriendlyFire = ((hitInfo.targetId!=hitInfo.shooterId) && (hitInfo.type!=CGameRules::EHitType::EventDamage)) ) { if(IVehicle* pTargetVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(hitInfo.targetId)) { if(IActor* pDriverTargetVehicle = pTargetVehicle->GetDriver()) { // Vehicle driver shot own vehicle (same as shooting yourself), don't do friendly fire. bCheckFriendlyFire = pDriverTargetVehicle->GetEntityId()!=hitInfo.shooterId; } } if(bCheckFriendlyFire) { if (m_pGameRules->GetTeamCount() > 1) { int shooterTeamId = m_pGameRules->GetTeam(hitInfo.shooterId); int targetTeamId = m_pGameRules->GetTeam(hitInfo.targetId); if (shooterTeamId && (shooterTeamId == targetTeamId)) { damage = GetFriendlyFireDamage(damage, hitInfo, pTargetActor); } } } } if (damage <= 0.f) { // If the hit isn't doing anything bail, this means any hit that gets past here has damage associated with it and thus wants to // display a hit indicator return false; } if (pPlayer) { if(hitInfo.partId >= 0 && !isMelee) { damageHandling.damageMultiplier *= pPlayer->GetBodyDamageMultiplier(hitInfo); } if (isMelee) { damageHandling.damageMultiplier *= g_pGameCVars->pl_melee.damage_multiplier_mp; } } damage *= damageHandling.damageMultiplier; HitInfo hitInfoWithDamage = hitInfo; hitInfoWithDamage.damage = damage; if(pPlayer) { SActorStats* pStats = pPlayer->GetActorStats(); float actorHealth = pPlayer->GetHealth(); if(pStats) { #ifndef _RELEASE if (g_pGameCVars->g_LogDamage) { char weaponClassName[64], projectileClassName[64]; CryLog ("[DAMAGE] %s '%s' took %.3f '%s' damage (%.3f x %.3f) weapon=%s projectile=%s", pPlayer->GetEntity()->GetClass()->GetName(), pPlayer->GetEntity()->GetName(), damage, m_pGameRules->GetHitType(hitInfo.type), hitInfo.damage, damageHandling.damageMultiplier, g_pGame->GetIGameFramework()->GetNetworkSafeClassName(weaponClassName, sizeof(weaponClassName), hitInfo.weaponClassId) ? weaponClassName : "none", g_pGame->GetIGameFramework()->GetNetworkSafeClassName(projectileClassName, sizeof(projectileClassName), hitInfo.projectileClassId) ? projectileClassName : "none"); } #endif if(pStats->bStealthKilling && actorHealth <= damage) { if(pPlayer->GetStealthKill().GetTargetId() != hitInfoWithDamage.shooterId) { pPlayer->StoreDelayedKillingHitInfo(hitInfoWithDamage); } hitInfoWithDamage.damage = 0; } else if (pStats->bStealthKilled && hitInfoWithDamage.type != CGameRules::EHitType::StealthKill) { hitInfoWithDamage.damage = 0; } } } bool bKilled = SvOnHitScaled(hitInfoWithDamage); return bKilled; }
int CGameStartup::Run( const char * autoStartLevelName ) { #if defined(RELEASE_SERVER_SECURITY) CryLogAlways("Performing Validation Checks"); if (!PerformDedicatedInstallationSanityCheck()) { CryFatalError("Installation appears to be corrupt. Please check the log file for a list of problems."); } #endif gEnv->pConsole->ExecuteString( "exec autoexec.cfg" ); if (autoStartLevelName) { //load savegame if(CryStringUtils::stristr(autoStartLevelName, CRY_SAVEGAME_FILE_EXT) != 0 ) { CryFixedStringT<256> fileName (autoStartLevelName); // NOTE! two step trimming is intended! fileName.Trim(" "); // first: remove enclosing spaces (outside ") fileName.Trim("\""); // second: remove potential enclosing " gEnv->pGame->GetIGameFramework()->LoadGame(fileName.c_str()); } else //start specified level { CryFixedStringT<256> mapCmd ("map "); mapCmd+=autoStartLevelName; gEnv->pConsole->ExecuteString(mapCmd.c_str()); } } #ifdef WIN32 if (!(gEnv && gEnv->pSystem) || (!gEnv->IsEditor() && !gEnv->IsDedicated())) { ::ShowCursor(TRUE); // Make the cursor visible again (it was hidden in InitFramework() ) if (gEnv && gEnv->pSystem && gEnv->pSystem->GetIHardwareMouse()) gEnv->pSystem->GetIHardwareMouse()->DecrementCounter(); } AllowAccessibilityShortcutKeys(false); for(;;) { ISystem *pSystem = gEnv ? gEnv->pSystem : 0; if (!pSystem) { break; } if (pSystem->PumpWindowMessage(false) == -1) { break; } if (!Update(true, 0)) { // need to clean the message loop (WM_QUIT might cause problems in the case of a restart) // another message loop might have WM_QUIT already so we cannot rely only on this pSystem->PumpWindowMessage(true); break; } } #else // We should use bVisibleByDefault=false then... if (gEnv && gEnv->pHardwareMouse) gEnv->pHardwareMouse->DecrementCounter(); #if !defined(DURANGO) for(;;) { if (!Update(true, 0)) { break; } } #endif #endif //WIN32 return 0; }