void CGameServerChannel::OnDisconnect(EDisconnectionCause cause, const char *description)
{
	//CryLogAlways("CGameServerChannel::OnDisconnect(%d, '%s')", cause, description?description:"");
  CCryAction::GetCryAction()->OnActionEvent(SActionEvent(eAE_clientDisconnected,int(cause),description));

	IGameRules *pGameRules = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules();

	if (pGameRules && IsOnHold())
	{
		pGameRules->OnClientDisconnect(GetChannelId(), cause, description, false);
		Cleanup();

		return;
	}

	if (sv_timeout_disconnect && pGameRules && sv_timeout_disconnect->GetIVal()>0 && pGameRules->ShouldKeepClient(GetChannelId(), cause, description))
	{
		if (m_pServerNub->PutChannelOnHold(this))
		{
			pGameRules->OnClientDisconnect(GetChannelId(), cause, description, true);
			m_hasLoadedLevel=false;
			return;
		}
	}

	if (pGameRules)
		pGameRules->OnClientDisconnect(GetChannelId(), cause, description, false);
	Cleanup();
}
示例#2
0
void CGameStats::Connected()
{
	//should not be called
	if(gEnv->IsClient() && !gEnv->bServer)//pure clients
	{
		if(IGameRulesSystem* pGR = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem())
		{
			IGameRules *pR = pGR->GetCurrentGameRules();
			if(pR)
			{
				IEntityScriptProxy *pScriptProxy=static_cast<IEntityScriptProxy *>(pR->GetEntity()->GetProxy(ENTITY_PROXY_SCRIPT));
				if (pScriptProxy)
				{
					string gameState = pScriptProxy->GetState();
					if(gameState=="InGame")
					{
						m_playing=true;
						m_gameMode = pR->GetEntity()->GetClass()->GetName();
					}
				}		
			}		
		}
		if(m_statsTrack)
			m_statsTrack->Reset();
	}
}
	void OnVehicleEvent(EVehicleEvent event, const SVehicleEventParams& params)
	{
		if ( (event == eVE_Destroyed) || 
				 (event == eVE_PreVehicleDeletion) ||
				 (event == eVE_Hide) ) // Safer to ensure the listener is removed at this point
		{
			SetActive(false);
		}
		else if (event == eVE_VehicleDeleted) // This shouldn't be called due to above but just in case
		{
			SetActive(false);
		}
		else if (event == eVE_Collision) // Currently disabled in C2 code
		{
			ActivateOutput(&m_actInfo, EOP_Collided, true);
		}
		else if (event == eVE_Hit) // Needed to detect collision in C2 code since above is disabled
		{
			IGameRules* pGameRules = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem()->GetCurrentGameRules();
			if (pGameRules)
			{
				const int collisionHitType = pGameRules->GetHitTypeId("collision");

				if (params.iParam == collisionHitType)
				{
					ActivateOutput(&m_actInfo, EOP_Collided, true);
				}
			}
		}
	}
示例#4
0
const char *CHUDTagNames::GetPlayerRank(EntityId uiEntityId)
{
	const char *szRank = NULL;

	IGameRules *pGameRules = g_pGame->GetGameRules();

	int iPlayerRank = 0;
	if(IScriptTable *pGameRulesTable=pGameRules->GetEntity()->GetScriptTable())
	{
		HSCRIPTFUNCTION pfnGetPlayerRank = NULL;
		if(pGameRulesTable->GetValue("GetPlayerRank",pfnGetPlayerRank) && pfnGetPlayerRank)
		{
			Script::CallReturn(gEnv->pScriptSystem,pfnGetPlayerRank,pGameRulesTable,ScriptHandle(uiEntityId),iPlayerRank);
			gEnv->pScriptSystem->ReleaseFunc(pfnGetPlayerRank);
		}
	}
  
	if(iPlayerRank)
	{
		static string strRank;
		static wstring wRank;
		strRank.Format("@ui_short_rank_%d",iPlayerRank);
		if(gEnv->pSystem->GetLocalizationManager()->LocalizeLabel(strRank,wRank))
		{
			ConvertWString(wRank,strRank);
		}
		szRank = strRank.c_str();
	}

	return szRank;
}
	void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
	{
		if (event == eFE_Activate && IsPortActive(pActInfo,0))
		{
			IActor* pActor = GetInputActor( pActInfo );
			if (!pActor || pActor!=gEnv->pGame->GetIGameFramework()->GetClientActor())  // to avoid some extra RMIs and object creation. Tho, this causes the node to not work properly if it is used with non players entities. (which was never intended anyway)
				return;

			IEntitySystem* pEntSys = gEnv->pEntitySystem;

			IInventory *pInventory = pActor->GetInventory();
			if (!pInventory)
				return;

			const string& itemClass = GetPortString(pActInfo, 1);
			const char* pItemClass = itemClass.c_str();
			IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(pItemClass);
			EntityId id = pInventory->GetItemByClass(pClass);

			if (id == 0 || GetPortBool(pActInfo, 3) == false)
			{
				if(gEnv->bServer)
				{
					gEnv->pGame->GetIGameFramework()->GetIItemSystem()->GiveItem( pActor, pItemClass , false, true, true );
				}
				else
				{
					// TODO: instant output activation, with delayed effective change in the inventory, it potentially could cause problems in rare situations
					pInventory->RMIReqToServer_AddItem( pItemClass );
				}
				ActivateOutput( pActInfo, 0, true );
			}
			else
			{
				// item already in inventory
				ActivateOutput(pActInfo, 0, false);
			}			
		}
		else if (event == eFE_PrecacheResources)
		{
			const string& itemClass = GetPortString(pActInfo, 1);

			if (!itemClass.empty())
			{
				IGameRules* pGameRules = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules();
				CRY_ASSERT_MESSAGE(pGameRules != NULL, "No game rules active, can not precache resources");
				if (pGameRules)
				{
					pGameRules->PrecacheLevelResource(itemClass.c_str(), eGameResourceType_Item);
				}
			}
		}
	}
示例#6
0
void CGameStats::Report()
{
	if(!m_serverReport)
		return;

	int playerCount = m_playerMap.size();
	if (CGameServerNub * pServerNub = CCryAction::GetCryAction()->GetGameServerNub())
		playerCount = pServerNub->GetPlayerCount();

	//All server reporting is done here 
	m_serverReport->SetReportParams(playerCount,m_teamMap.size());
  m_serverReport->SetServerValue("gamemode",m_playing?"game":"pre-game");

	CryFixedStringT<32>  timeleft("-");
	if(IGameRulesSystem* pGR = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem())
	{
		IGameRules *pR = pGR->GetCurrentGameRules();
		if(pR && pR->IsTimeLimited() && m_playing)
		{
				timeleft.Format("%.0f",pR->GetRemainingGameTime());
		}
	}

	m_serverReport->SetServerValue("timeleft",timeleft);

	CryFixedStringT<256> tempStr;

	m_serverReport->SetServerValue("numplayers",tempStr.Format("%d",playerCount));
  
  int i=0;

	string mode;
  for(PlayerStatsMap::const_iterator it=m_playerMap.begin();it!=m_playerMap.end();++it)
	{
		static string value;
		m_serverReport->SetPlayerValue(i, "player", it->second.name);
		value.Format("%d",it->second.rank);
    m_serverReport->SetPlayerValue(i, "rank", value);
		value.Format("%d",it->second.team?it->second.team:(it->second.spectator?0:1));
    m_serverReport->SetPlayerValue(i, "team", value);
		for (std::map<string, int>::const_iterator sit=it->second.scores.begin(); sit!=it->second.scores.end(); ++sit)
			m_serverReport->SetPlayerValue(i, sit->first, tempStr.Format("%d",sit->second));
    ++i;
	}
	while (i < playerCount)
	{
		m_serverReport->SetPlayerValue(i, "player", "<connecting>");
		++i;
	}
}
//------------------------------------------------------------------------
void CGameServerNub::ResetOnHoldChannels()
{
	for (THoldChannelMap::iterator it=m_onhold.begin(); it!=m_onhold.end(); ++it)
	{
		IGameRules *pGameRules = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules();
		pGameRules->OnClientDisconnect(it->first,eDC_Timeout,"OnHold reseted",false);
		TServerChannelMap::iterator ch_it = m_channels.find(it->first);
		if(ch_it!=m_channels.end())
		{
			delete ch_it->second;
			m_channels.erase(ch_it);
		}
	}
	m_onhold.clear();
}
示例#8
0
//------------------------------------------------------------------------
void CVehicleDamages::ParseDamageMultipliers(TDamageMultipliers& multipliersByHitType, TDamageMultipliers& multipliersByProjectile, const CVehicleParams& table)
{
	CVehicleParams damageMultipliersTable = table.findChild("DamageMultipliers");
	if (!damageMultipliersTable)
		return;

	int i = 0;
	int c = damageMultipliersTable.getChildCount();
	
	IGameRules* pGR = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules();
	assert(pGR);

	for (; i < c; i++)
	{
		if (CVehicleParams multiplierTable = damageMultipliersTable.getChild(i))
		{
			string damageType = multiplierTable.getAttr("damageType");
			if (!damageType.empty())
			{
				int hitTypeId = 0;
				if(pGR && damageType != "default")
					hitTypeId = pGR->GetHitTypeId(damageType.c_str());

				assert(hitTypeId != 0 || damageType == "default");
				
				if(hitTypeId != 0 || damageType == "default")
				{
					GetAndInsertMultiplier( multipliersByHitType, multiplierTable, int(hitTypeId) );
				}
			}		

			string ammoType = multiplierTable.getAttr("ammoType");
		  if (!ammoType.empty())
			{
				int projectileType = 0;
				if(pGR && ammoType != "default")
				{
					uint16 classId(~uint16(0));

					if( ammoType == "default" || gEnv->pGame->GetIGameFramework()->GetNetworkSafeClassId(classId, ammoType.c_str()) )
					{
						GetAndInsertMultiplier( multipliersByProjectile, multiplierTable, int(classId) );
					}
				}
			}				
		}
	}
}
	void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo )
	{
		if (event == eFE_Activate && IsPortActive(pActInfo, EIP_Trigger))
		{
			IActor* pActor = GetInputActor( pActInfo );
			if (!pActor)
				return;

			IInventory *pInventory = pActor->GetInventory();
			if (!pInventory)
				return;

			const bool& addPack = GetPortBool(pActInfo, EIP_AddToggle);
			const string& packName = GetPortString(pActInfo, EIP_EquipmentPack);
			const bool& selectPrimary = GetPortBool(pActInfo, EIP_SelectPrimary);

			if (pActor->IsPlayer())
				pInventory->RMIReqToServer_AddEquipmentPack( packName.c_str(), addPack, selectPrimary );
			else
			{
				if (gEnv->bServer)
					CCryAction::GetCryAction()->GetIItemSystem()->GetIEquipmentManager()->GiveEquipmentPack( pActor, packName.c_str(), addPack, selectPrimary );
			}
				
			// TODO: instant output activation, with delayed effective change in the inventory, it potentially could cause problems in rare situations
			ActivateOutput(pActInfo, EOP_Done, true);
		}
		else if (event == eFE_PrecacheResources)
		{
			const string& packName = GetPortString(pActInfo, 1);

			if (!packName.empty())
			{
				IGameRules* pGameRules = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules();
				CRY_ASSERT_MESSAGE(pGameRules != NULL, "No game rules active, can not precache resources");
				if (pGameRules)
				{
					pGameRules->PrecacheLevelResource(packName.c_str(), eGameResourceType_Loadout);
				}
			}
		}
	}
//------------------------------------------------------------------------
void CGameServerNub::RemoveOnHoldChannel(CGameServerChannel *pServerChannel, bool renewed)
{
	for (THoldChannelMap::iterator it=m_onhold.begin(); it!=m_onhold.end(); ++it)
	{
		if (it->second.channelId == pServerChannel->GetChannelId())
		{
			m_onhold.erase(it);
			if(!renewed)//let gamerules know we should get rid of it...
			{
				IGameRules *pGameRules = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules();
				pGameRules->OnClientDisconnect(pServerChannel->GetChannelId(),eDC_Timeout,"OnHold timed out",false);
			}				
			break;
		}
	}

	if(!renewed)
	{
		stl::member_find_and_erase(m_channels, pServerChannel->GetChannelId());

		delete pServerChannel;
	}	
}
void CVehicleDamageBehaviorBlowTire::DamagePlayers()
{
	// check for the nasty case when the player is shooting at the vehicle tires while prone 
	// under or behind the car, In that case the player should get killed by the vehicle, 
	// otherwise he gets stuck forever. Note that he should only get killed when the tier
	// is actually destroyed and not by collision resulting by the impulse added by just 
	// shooting at the tiers. Unfortunately using physics for doing this check is not reliable
	// enough so we have to check it explicitly
	
	IEntityPhysicalProxy *pPhysicsProxy = (IEntityPhysicalProxy*)m_pVehicle->GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS);
	if (!pPhysicsProxy)
		return;

	AABB bbox;
	pPhysicsProxy->GetWorldBounds( bbox );

	IPhysicalWorld *pWorld = gEnv->pSystem->GetIPhysicalWorld();
	IPhysicalEntity **ppColliders;
	// check entities in collision with the car
	int cnt = pWorld->GetEntitiesInBox( bbox.min,bbox.max, ppColliders,ent_living);
	for (int i = 0; i < cnt; i++)
	{

		IEntity *pEntity = gEnv->pEntitySystem->GetEntityFromPhysics( ppColliders[i] );
		if (!pEntity)
			continue;
		
		// skip the vehicle itself
		if (pEntity==m_pVehicle->GetEntity())
			continue;

		IPhysicalEntity *pPhysEnt = pEntity->GetPhysics();
		if (!pPhysEnt) 
			continue;

		IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId());            
		if(!pActor)
			continue;

		//Jan M.: the player is killed when he entered the vehicle while prone although he is still passenger!
		if(m_pVehicle == pActor->GetLinkedVehicle())
			continue;

		//the player must be prone under the vehicle
		IAnimatedCharacter * animatedCharacter=pActor->GetAnimatedCharacter();
		if (!animatedCharacter)
			continue;

		int stance = animatedCharacter->GetCurrentStance();
		if (stance!=STANCE_PRONE)
			continue;

		pe_player_dimensions dim;
		if (!pPhysEnt->GetParams(&dim))
			continue;
		// position returned is at entity's feet, add head position from physics
		Vec3 vPos1=pEntity->GetPos();
		vPos1.z = vPos1.z + dim.heightHead;

		float fZ=bbox.GetCenter().z;
		if (vPos1.z>fZ)
			continue; // not under the vehicle

		// at this point we have a collision with the car moving down and the guy prone under the car, it is safe
		// to assume he has been squished so let's kill him.
		if (gEnv->bServer && pActor->GetHealth()>0)
		{
			// adding a server hit to make it working in MP
			IGameRules *pGameRules = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem()->GetCurrentGameRules();
			if (pGameRules)
			{
				HitInfo hit;

				EntityId shooterId=m_pVehicle->GetEntityId();
				if (m_pVehicle->GetDriver())
					shooterId=m_pVehicle->GetDriver()->GetEntityId();					

				hit.targetId = pEntity->GetId();      
				hit.shooterId = shooterId;
				hit.weaponId = m_pVehicle->GetEntityId();
				hit.damage = 1000.f;
				hit.type = 0;
				hit.pos = pActor->GetEntity()->GetWorldPos();

				pGameRules->ServerHit(hit); 
			}  
		} 
	} //i
}
//------------------------------------------------------------------------
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);
}
void CDamageEffectController::Init(CActor* actor)
{
	if (CKVoltEffect::s_hashId == 0) //once initialised it can't be 0
	{
		CKVoltEffect::s_hashId = CreateHash("KVoltFX");
		CTinnitusEffect::s_hashId = CreateHash("TinnitusFx");
		CEntityTimerEffect::s_hashId = CreateHash("TimerFX");
	}

	IGameRules* pGameRules = g_pGame->GetGameRules();
	m_ownerActor = actor;

	const IItemParamsNode* actorParams = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActorParams(actor->GetEntityClassName());
	const IItemParamsNode* damageEffectParams = actorParams ? actorParams->GetChild("DamageEffectParams") : 0;

	if (damageEffectParams)
	{
		int numChildren = damageEffectParams->GetChildCount();
		int allowSerialise = 1;

		damageEffectParams->GetAttribute("allowSerialise", allowSerialise);
		m_allowSerialise = allowSerialise ? true : false;

		CRY_ASSERT_MESSAGE(numChildren <= MAX_NUM_DAMAGE_EFFECTS, "Too many damage effects found. Increase the MAX_NUM_DAMAGE_EFFECTS and size of activeEffects and effectsResetSwitch");

		for (int i = 0; i < numChildren; i++)
		{
			const IItemParamsNode* child = damageEffectParams->GetChild(i);
			const IItemParamsNode* effect = child->GetChild(0);

			const char* hittype = child->GetAttribute("hittype");
			const char* name = effect->GetName();

			m_associatedHitType[i] = pGameRules->GetHitTypeId(hittype);

			child->GetAttribute("minDamage", m_minDamage[i]);	
			
			uint64 hashcode = CreateHash(name);

			if (hashcode == CKVoltEffect::s_hashId)
			{
				m_effectList[i] = new CKVoltEffect();
			}
			else if (hashcode == CTinnitusEffect::s_hashId)
			{
				m_effectList[i] = new CTinnitusEffect();
			}
			else if (hashcode == CEntityTimerEffect::s_hashId)
			{
				m_effectList[i] = new CEntityTimerEffect();
			}
			else
			{
				GameWarning("INVALID DAMAGE EFFECT PARSED");
				m_associatedHitType[i] = -1;
			}
			
			if(m_effectList[i])
			{
				m_effectList[i]->Init(actor, effect);
			}
		}
	}
}
示例#14
0
void CUIHUD3D::SpawnHudEntities()
{
    RemoveHudEntities();

    if (gEnv->IsEditor() && gEnv->IsEditing())
        return;

    const char* hudprefab = NULL;
    IGameRules* pGameRules = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem()->GetCurrentGameRules();
    if (pGameRules)
    {
        IScriptTable* pTable = pGameRules->GetEntity()->GetScriptTable();
        if (pTable)
        {
            if (!pTable->GetValue("hud_prefab", hudprefab))
                hudprefab = NULL;
        }
    }
    hudprefab = hudprefab ? hudprefab : HUD3D_PREFAB_LIB;

    XmlNodeRef node = gEnv->pSystem->LoadXmlFromFile(hudprefab);
    if (node)
    {
        // get the prefab with the name defined in HUD3D_PREFAB_NAME
        XmlNodeRef prefab = NULL;
        for (int i = 0; i < node->getChildCount(); ++i)
        {
            const char* name = node->getChild(i)->getAttr("Name");
            if (name && strcmp(name, HUD3D_PREFAB_NAME) == 0)
            {
                prefab = node->getChild(i);
                prefab = prefab ? prefab->findChild("Objects") : XmlNodeRef();
                break;
            }
        }

        if (prefab)
        {
            // get the PIVOT entity and collect childs
            XmlNodeRef pivotNode = NULL;
            std::vector<XmlNodeRef> childs;
            const int count = prefab->getChildCount();
            childs.reserve(count-1);

            for (int i = 0; i < count; ++i)
            {
                const char* name = prefab->getChild(i)->getAttr("Name");
                if (strcmp("PIVOT", name) == 0)
                {
                    assert(pivotNode == NULL);
                    pivotNode = prefab->getChild(i);
                }
                else
                {
                    childs.push_back(prefab->getChild(i));
                }
            }

            if (pivotNode)
            {
                // spawn pivot entity
                IEntityClass* pEntClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass( pivotNode->getAttr("EntityClass") );
                if (pEntClass)
                {
                    SEntitySpawnParams params;
                    params.nFlags = ENTITY_FLAG_CLIENT_ONLY;
                    params.pClass = pEntClass;
                    m_pHUDRootEntity = gEnv->pEntitySystem->SpawnEntity(params);
                }

                if (!m_pHUDRootEntity) return;

                m_HUDRootEntityId = m_pHUDRootEntity->GetId();

                // spawn the childs and link to the pivot enity
                for (std::vector<XmlNodeRef>::iterator it = childs.begin(); it != childs.end(); ++it)
                {
                    XmlNodeRef child = *it;
                    pEntClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass( child->getAttr("EntityClass") );
                    if (pEntClass)
                    {
                        const char* material = child->getAttr("Material");
                        Vec3 pos;
                        Vec3 scale;
                        Quat rot;
                        child->getAttr("Pos", pos);
                        child->getAttr("Rotate", rot);
                        child->getAttr("Scale", scale);

                        SEntitySpawnParams params;
                        params.nFlags = ENTITY_FLAG_CLIENT_ONLY;
                        params.pClass = pEntClass;
                        params.vPosition = pos;
                        params.qRotation = rot;
                        params.vScale = scale;
                        IEntity* pEntity = gEnv->pEntitySystem->SpawnEntity(params);
                        if (pEntity)
                        {
                            IScriptTable* pScriptTable = pEntity->GetScriptTable();
                            if (pScriptTable)
                            {
                                SmartScriptTable probs;
                                pScriptTable->GetValue("Properties", probs);

                                XmlNodeRef properties = child->findChild("Properties");
                                if (probs && properties)
                                {
                                    for (int k = 0; k < properties->getNumAttributes(); ++k)
                                    {
                                        const char* sKey;
                                        const char* sVal;
                                        properties->getAttributeByIndex(k, &sKey, &sVal);
                                        probs->SetValue(sKey, sVal);
                                    }
                                }
                                Script::CallMethod(pScriptTable,"OnPropertyChange");
                            }

                            if (material)
                            {
                                IMaterial* pMat = gEnv->p3DEngine->GetMaterialManager()->LoadMaterial(material);
                                if (pMat)
                                    pEntity->SetMaterial(pMat);
                            }
                            m_pHUDRootEntity->AttachChild(pEntity);
                            m_HUDEnties.push_back( pEntity->GetId() );
                        }
                    }
                }
            }
        }
    }

    OnVisCVarChange( NULL );
}
示例#15
0
void CGameStats::StartGame(bool server)
{
	if(!server && gEnv->bServer)//we simply ignore client events on server
		return;

	if(IGameRulesSystem* pGR = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem())
	{
		IGameRules *pR = pGR->GetCurrentGameRules();
		if(pR)
		{
			IEntityScriptProxy *pScriptProxy=static_cast<IEntityScriptProxy *>(pR->GetEntity()->GetProxy(ENTITY_PROXY_SCRIPT));
			if (pScriptProxy)
			{
				string gameState = pScriptProxy->GetState();
				if(gameState=="InGame")
				{
					m_playing=true;
					m_gameMode = pR->GetEntity()->GetClass()->GetName();
				}
			}		
		}		
	}

	if(!m_statsTrack || !m_serverReport) 
		Init();
  
	if(m_serverReport)
	{
		ReportGame();
		m_serverReport->Update();
	}
	
	if(m_playing)
	{
		if (ILevelInfo* pLevelInfo = gEnv->pGame->GetIGameFramework()->GetILevelSystem()->GetCurrentLevel())
		{
			m_mapName = pLevelInfo->GetName();//we only need pure level name here
			const char* p = strrchr(m_mapName.c_str(),'/');
			if(p != 0 && strlen(p) > 1)
			{
				m_mapName = p + 1;
				char* pStr = const_cast<char*>(m_mapName.data());
				pStr[0] = toupper(m_mapName[0]);
				for(int i = 1; i < m_mapName.size(); ++i)
					pStr[i] = tolower(m_mapName[i]);
			}
		}
	}
	

	if(m_statsTrack && m_playing  && gEnv->bServer)
		m_statsTrack->StartGame();

	if(gEnv->bServer && m_playing)
	{
		m_roundStart = gEnv->pTimer->GetFrameStartTime();
		m_lastPosUpdate = 0.0f;
		ResetStats();
		m_roundStats->Start(m_mapName, m_roundStart);
	}
}