//------------------------------------------------------------------------
void CGameRulesMPDamageHandling::SvOnExplosion(const ExplosionInfo &explosionInfo, const CGameRules::TExplosionAffectedEntities& affectedEntities)
{
	// SinglePlayer.lua 1721

	IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem();
	float totalDamage = 0.f;

	// calculate damage for each entity
	CGameRules::TExplosionAffectedEntities::const_iterator it = affectedEntities.begin();
	for (; it != affectedEntities.end(); ++it)
	{
		bool success = false;
		IEntity* entity = it->first;
		float obstruction = 1.0f - it->second;

		bool incone=true;
		if (explosionInfo.angle > 0 && explosionInfo.angle < 2*3.1415f)
		{
			Vec3 explosionEntityPos = entity->GetWorldPos();
			Vec3 entitypos = explosionEntityPos;
			float ha = explosionInfo.angle * 0.5f;
			Vec3 edir = entitypos - explosionInfo.pos;
			edir.normalize();
			float dot = 1;

			if (edir != Vec3(ZERO))
			{
				dot = edir.dot(explosionInfo.dir);
			}

			float angle = abs(acos_tpl(dot));
			if (angle > ha)
			{
				incone = false;
			}
		}

		if (incone && gEnv->bServer)
		{
			float damage = explosionInfo.damage;
			damage = floor_tpl(0.5f + CalcExplosionDamage(entity, explosionInfo, obstruction));	

			bool dead = false;

			HitInfo explHit;

			Vec3 dir = entity->GetWorldPos() - explosionInfo.pos;

			explHit.pos = explosionInfo.pos;
			explHit.radius = explosionInfo.radius;
			explHit.partId = -1;

			dir.Normalize();

			explHit.targetId = entity->GetId();
			explHit.weaponId = explosionInfo.weaponId;
			explHit.shooterId = explosionInfo.shooterId;
			explHit.projectileId = explosionInfo.projectileId;
			explHit.projectileClassId = explosionInfo.projectileClassId;

			uint16 weaponClass = ~uint16(0);
			const IEntity* pWeaponEntity = gEnv->pEntitySystem->GetEntity(explosionInfo.weaponId);
			if (pWeaponEntity)
			{
				g_pGame->GetIGameFramework()->GetNetworkSafeClassId(weaponClass, pWeaponEntity->GetClass()->GetName());
			}
			explHit.weaponClassId = weaponClass;

			explHit.material = 0;
			explHit.damage = damage;
			explHit.type = explosionInfo.type;
			explHit.hitViaProxy = explosionInfo.explosionViaProxy;

			explHit.dir = dir;
			explHit.normal = -dir; //set normal to reverse of  direction to avoid backface cull of damage

			if (explHit.damage > 0.0f || explosionInfo.damage == 0.f)
			{
				CActor* pActor = static_cast<CActor*>(pActorSystem->GetActor(entity->GetId()));

				if (pActor)
				{
					const float damageMultiplier = pActor->GetBodyExplosionDamageMultiplier(explHit);
					explHit.damage *= damageMultiplier; 

					// Protect players who are currently shielded
					if(pActor->IsPlayer() && static_cast<CPlayer*>(pActor)->ShouldFilterOutExplosion(explHit))
					{
						explHit.damage = 0.0f;
					}
				}
				else
				{
					CInteractiveObjectEx* pInteractiveObject = static_cast<CInteractiveObjectEx*>(g_pGame->GetIGameFramework()->QueryGameObjectExtension(entity->GetId(), "InteractiveObjectEx"));
					if(pInteractiveObject)
					{
						pInteractiveObject->OnExploded(explHit.pos);
					}
				}
			
				if(!explosionInfo.explosionViaProxy) 
				{
					if(pActor)
					{
						if(!pActor->IsFriendlyEntity(explHit.shooterId))
						{
							totalDamage += damage;
						}
					}
					else
					{
						IVehicle* pVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(entity->GetId());

						if(pVehicle)
						{
							IActor* pDriver = pVehicle->GetDriver();
							int seatNum = 0;
							int numSeats = pVehicle->GetSeatCount();

							while(!pDriver && seatNum < numSeats)
							{
								IVehicleSeat* pSeat = pVehicle->GetSeatById(seatNum++);

								EntityId passengerId = pSeat ? pSeat->GetPassenger(true) : 0;
								pDriver = pActorSystem->GetActor(passengerId);
							}

							if(pDriver)
							{
								CActor* pDriverActor = static_cast<CActor*>(pDriver);
								if(!pDriverActor->IsFriendlyEntity(explHit.shooterId))
								{
									totalDamage += damage;
								}
							}
						}
					}
				}
				
				m_pGameRules->ServerHit(explHit);
			}
		}
	}

	if (totalDamage > 0.f)
	{
		IGameRulesPlayerStatsModule*  pPlayStatsMod = m_pGameRules->GetPlayerStatsModule();

		if(pPlayStatsMod)
		{
			pPlayStatsMod->ProcessSuccessfulExplosion(explosionInfo.shooterId, totalDamage, explosionInfo.projectileClassId);
		}
	}
}
示例#2
0
void CHUDTagNames::Update()
{
	CActor *pClientActor = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetClientActor());
	CGameRules *pGameRules = g_pGame->GetGameRules();

	if(!pClientActor || !pGameRules || !gEnv->bMultiplayer)
		return;

	int iClientTeam = pGameRules->GetTeam(pClientActor->GetEntityId());

	// Skip enemies, they need to be added only when shot
	// (except in spectator mode when we display everyone)
	for(int iTeam = 0; iTeam < pGameRules->GetTeamCount() + 1; ++iTeam)
	{
		if((iTeam == iClientTeam) || (pClientActor->GetSpectatorMode() != CActor::eASM_None))
		{
			int iTeamPlayerCount = pGameRules->GetTeamPlayerCount(iTeam);
			for(int iPlayer=0; iPlayer<iTeamPlayerCount; iPlayer++)
			{
				IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pGameRules->GetTeamPlayer(iTeam,iPlayer));
				if(!pActor)
					continue;

				// Never display the local player
				if(pActor == pClientActor)
					continue;

				// never display other spectators
				if(static_cast<CActor*>(pActor)->GetSpectatorMode() != CActor::eASM_None)
					continue;

				// never display the name of the player we're spectating (it's shown separately with their current health)
				if(pClientActor->GetSpectatorMode() == CActor::eASM_Follow && pClientActor->GetSpectatorTarget() == pActor->GetEntityId())
					continue;

				DrawTagName(pActor);
			}
		}
	}

	IVehicleSystem *pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem();
	if(!pVehicleSystem)
		return;

	IVehicleIteratorPtr pVehicleIter = pVehicleSystem->CreateVehicleIterator();
	while(IVehicle *pVehicle=pVehicleIter->Next())
	{
		SVehicleStatus rVehicleStatus = pVehicle->GetStatus();
		if(0 == rVehicleStatus.passengerCount)
			continue;

		// Skip enemy vehicles, they need to be added only when shot (except in spectator mode...)
		bool bEnemyVehicle = true;
		for(int iSeatId=1; iSeatId<=pVehicle->GetLastSeatId(); iSeatId++)
		{
			IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(iSeatId);
			if(!pVehicleSeat)
				continue;

			EntityId uiEntityId = pVehicleSeat->GetPassenger();

			if(0 == iClientTeam)
			{
				if(uiEntityId && IsFriendlyToClient(uiEntityId))
				{
					bEnemyVehicle = false;
				}
			}
			else if(uiEntityId && pGameRules->GetTeam(uiEntityId) == iClientTeam)
			{
				bEnemyVehicle = false;
			}
		}
		if(bEnemyVehicle && (pClientActor->GetSpectatorMode() == CActor::eASM_None))	// again, draw enemies in spectator mode
			continue;

		DrawTagName(pVehicle);
	}

	// don't need to do any of this if we're in spectator mode - all player names will have been drawn above.
	if(pClientActor->GetSpectatorMode() == CActor::eASM_None)
	{
		for(TEnemyTagNamesList::iterator iter=m_enemyTagNamesList.begin(); iter!=m_enemyTagNamesList.end(); ++iter)
		{
			SEnemyTagName *pEnemyTagName = &(*iter);
			if(gEnv->pTimer->GetAsyncTime().GetSeconds() >= pEnemyTagName->fSpawnTime+((float) g_pGameCVars->hud_mpNamesDuration))
			{
				// Note: iter=my_list.erase(iter) may not be standard/safe
				TEnemyTagNamesList::iterator iterNext = iter;
				++iterNext;
				m_enemyTagNamesList.erase(iter);
				iter = iterNext;
			}
			else
			{
				IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEnemyTagName->uiEntityId);
				if(pActor)
					DrawTagName(pActor);

				IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(pEnemyTagName->uiEntityId);
				if(pVehicle)
					DrawTagName(pVehicle);
			}
		}
	}
}
	virtual void ProcessEvent( EFlowEvent event,SActivationInfo *pActInfo )
	{
		IVehicleSystem * pVehicleSystem = NULL;
		IVehicle * pVehicle = NULL;

		switch(event)
		{
		case eFE_Initialize:
			{
				pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false);
				break;
			}

		case eFE_Activate:
			{
				if (!pActInfo->pEntity)
					return;

				pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem();
				pVehicle = pVehicleSystem->GetVehicle(pActInfo->pEntity->GetId());

				if (!pVehicleSystem || !pVehicle)
					return;

				string givenString = GetPortString(pActInfo, IN_PARTS);
				currentParam = givenString.substr(0,givenString.find_first_of(":"));
				currentSetting = givenString.substr(givenString.find_first_of(":")+1,(givenString.length()-givenString.find_first_of(":")));

				column1 = 10.f;
				column2 = 100.f;

				if (IsPortActive(pActInfo,IN_SHOW))
					pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true);

				break;
			}

		case eFE_Update:
			{
				IRenderer * pRenderer = gEnv->pRenderer;

				pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem();
				pVehicle = pVehicleSystem->GetVehicle(pActInfo->pEntity->GetId());

				if(!pVehicleSystem || !pActInfo->pEntity || !pVehicle)
					return;

				pRenderer->Draw2dLabel(column1,10,GetPortFloat(pActInfo,IN_SIZE)+2.f,Col_Cyan,false,pActInfo->pEntity->GetName());

				if(currentParam=="Seats")
				{
					loops = 0;

					for(uint32 i=0;i<pVehicle->GetSeatCount();i++)
					{
						IVehicleSeat * currentSeat;

						if(currentSetting=="All")
						{
							currentSeat = pVehicle->GetSeatById(i+1);
						}
						else
						{
							currentSeat = pVehicle->GetSeatById(pVehicle->GetSeatId(currentSetting));
							i = pVehicle->GetSeatCount()-1;
						}

						loops += 1;

						// column 1
						string pMessage = ("%s:", currentSeat->GetSeatName());

						if (column2<pMessage.size()*8*GetPortFloat(pActInfo, IN_SIZE))
							column2=pMessage.size()*8*GetPortFloat(pActInfo, IN_SIZE);

						pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessage);

						// column 2
						if(currentSeat->GetPassenger(true))
						{
							pMessage = ("- %s", gEnv->pEntitySystem->GetEntity(currentSeat->GetPassenger(true))->GetName());
							pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessage);
						}
					}
				}

				else if(currentParam=="Wheels")
				{
					pRenderer->Draw2dLabel(column1,50.f,GetPortFloat(pActInfo,IN_SIZE)+1.f,Col_Red,false,"!");
				}

				else if(currentParam=="Weapons")
				{
					loops = 0;

					for(int i=0;i<pVehicle->GetWeaponCount();i++)
					{
						IItemSystem * pItemSystem = gEnv->pGame->GetIGameFramework()->GetIItemSystem();
						IWeapon * currentWeapon;
						EntityId currentEntityId;
						IItem * pItem;

						if(currentSetting=="All")
						{
							currentEntityId = pVehicle->GetWeaponId(i+1);
						}
						else
						{
							currentEntityId = gEnv->pEntitySystem->FindEntityByName(currentSetting)->GetId();
							i = pVehicle->GetWeaponCount()-1;
						}

						if(!pItemSystem->GetItem(currentEntityId))
							return;

						pItem = pItemSystem->GetItem(currentEntityId);
						currentWeapon = pItem->GetIWeapon();

						loops += 1;

						// column 1
						string pMessageName = string().Format("%s", gEnv->pEntitySystem->GetEntity(currentEntityId)->GetName());
						pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessageName);

						if (column2<pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE))
							column2=pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE);

						// column 2
						string pMessageValue = string().Format("seat: %s firemode: %i", pVehicle->GetWeaponParentSeat(currentEntityId)->GetSeatName(), currentWeapon->GetCurrentFireMode()).c_str();
						pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessageValue);
					}
				}

				else if(currentParam=="Components")
				{
					loops = 0;

					for(int i=0;i<pVehicle->GetComponentCount();i++)
					{
						IVehicleComponent * currentComponent;

						if(currentSetting=="All")
						{
							currentComponent = pVehicle->GetComponent(i);
						}
						else
						{
							currentComponent = pVehicle->GetComponent(currentSetting);
							i = pVehicle->GetComponentCount()-1;
						}

						loops += 1;

						ColorF labelColor;
						labelColor = ColorF(currentComponent->GetDamageRatio(),(1.f-currentComponent->GetDamageRatio()),0.f);

						// column 1
						string pMessageName = string().Format("%s", currentComponent->GetComponentName()).c_str();
						pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),labelColor,false,pMessageName);

						if (column2<pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE))
							column2=pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE);

						// column 2
						string pMessageValue = string().Format("%5.2f (%3.2f)", currentComponent->GetDamageRatio()*currentComponent->GetMaxDamage(), currentComponent->GetDamageRatio()).c_str();
						pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),labelColor,false,pMessageValue);
					}
				}

				else
				{
					pRenderer->Draw2dLabel(column1,50.f,GetPortFloat(pActInfo,IN_SIZE)+1.f,Col_Red,false,"no component selected!");
				}
				break;
			}
		}
	};
示例#4
0
void CHUDTagNames::DrawTagName(IVehicle *pVehicle)
{
	CRY_ASSERT(pVehicle);
	if(!pVehicle)
		return;

	CActor *pClientActor = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetClientActor());
	CGameRules *pGameRules = g_pGame->GetGameRules();
	int iClientTeam = pGameRules->GetTeam(pClientActor->GetEntityId());
	bool bThirdPerson = pClientActor->IsThirdPerson();

	bool bDrawSeatTagNames = false;
	if(pClientActor->GetSpectatorMode() == CActor::eASM_Follow)
	{
		IActor *pFollowedActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pClientActor->GetSpectatorTarget());
		if(pFollowedActor)
			bDrawSeatTagNames = (pVehicle == pFollowedActor->GetLinkedVehicle());
	}
	else
		bDrawSeatTagNames = (pVehicle == pClientActor->GetLinkedVehicle());

	if(bDrawSeatTagNames)
	{
		// When this is local player vehicle, we always display all passengers name above their head so that he can identify them

		for(int iSeatId=1; iSeatId<=pVehicle->GetLastSeatId(); iSeatId++)
		{
			IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(iSeatId);
			if(!pVehicleSeat)
				continue;

			IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pVehicleSeat->GetPassenger());
			if(!pActor || (pActor == pClientActor && !bThirdPerson))
				continue;

			DrawTagName(pActor,true);
		}

		return;
	}

	ColorF rgbTagName = COLOR_ENEMY;

	// Driver seat is always 1
	IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(1);
	if(!pVehicleSeat)
		return;

	IVehicleHelper *pVehicleHelper = pVehicleSeat->GetSitHelper();
	if(!pVehicleHelper)
		return;

	Vec3 vWorldPos = pVehicleHelper->GetWorldTM().GetTranslation();

	// Add some offset to be above the driver/pilot
	vWorldPos.z += 1.2f;

	AABB box; 
	pVehicle->GetEntity()->GetWorldBounds(box);

	bool bDrawOnTop = false;

	if(ProjectOnSphere(vWorldPos,box))
	{
		bDrawOnTop = true;
	}

	m_tagNamesVector.resize(0);

	for(int iSeatId=1; iSeatId<=pVehicle->GetLastSeatId(); iSeatId++)
	{
		IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(iSeatId);
		if(!pVehicleSeat)
			continue;

		EntityId uiEntityId = pVehicleSeat->GetPassenger();

		IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(uiEntityId);
		if(!pActor)
			continue;

		const char *szRank = GetPlayerRank(uiEntityId);

		IEntity *pEntity = pActor->GetEntity();
		if(!pEntity)
			continue;

		char szText[HUD_MAX_STRING_SIZE];
		if(szRank)
		{
			sprintf(szText,"%s %s",szRank,pEntity->GetName());
		}
		else
		{
			sprintf(szText,"%s",pEntity->GetName());
		}

		if(0 == iClientTeam)
		{
			if(uiEntityId && IsFriendlyToClient(uiEntityId))
			{
				rgbTagName = COLOR_FRIEND;
			}
		}
		else if(uiEntityId && pGameRules->GetTeam(uiEntityId) == iClientTeam)
		{
			rgbTagName = COLOR_FRIEND;
		}
		
		if(pActor->GetHealth() <= 0)
		{
			rgbTagName = COLOR_DEAD;
		}

		m_tagNamesVector.resize(m_tagNamesVector.size()+1);

		STagName *pTagName = &m_tagNamesVector[m_tagNamesVector.size()-1];

		pTagName->strName			= szText;
		pTagName->vWorld			= vWorldPos;
		pTagName->bDrawOnTop	= bDrawOnTop;
		pTagName->rgb					= rgbTagName;
	}

	DrawTagNames();
}