예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
파일: View.cpp 프로젝트: aronarts/FireNET
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!");
		}
	}
}
예제 #4
0
// ----------------------------------------------------------------------------
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);
}
예제 #5
0
파일: View.cpp 프로젝트: joewan/pycmake
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);
	}
}
예제 #6
0
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
}
예제 #7
0
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;
}
예제 #9
0
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));
}
예제 #10
0
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
}
예제 #11
0
/*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
}
예제 #12
0
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;
}
예제 #13
0
파일: Mouse.cpp 프로젝트: aronarts/FireNET
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;
}
예제 #14
0
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;
}
예제 #17
0
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);
	}
}
예제 #18
0
/*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);
}
예제 #21
0
	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;
	}
예제 #22
0
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;
}
예제 #23
0
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;
}
예제 #24
0
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);
		}
	}
}
예제 #25
0
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;
}
예제 #26
0
//------------------------------------------------------------------------
// 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;
}
예제 #27
0
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;
}