Esempio n. 1
0
//------------------------------------------------------------------------
void CProjectile::Explode(bool destroy, bool impact, const Vec3 &pos, const Vec3 &normal, const Vec3 &vel, EntityId targetId)
{
	const SExplosionParams* pExplosionParams = m_pAmmoParams->pExplosion;
	if (pExplosionParams)
	{
		Vec3 dir(0,0,1);
		if (impact && vel.len2()>0)
			dir = vel.normalized();
		else if (normal.len2()>0)
			dir = -normal;

		m_hitPoints = 0;

		// marcok: using collision pos sometimes causes explosions to have no effect. Anton advised to use entity pos
		Vec3 epos = pos.len2()>0 ? (pos - dir * 0.2f) : GetEntity()->GetWorldPos();

		CGameRules *pGameRules = g_pGame->GetGameRules();
		float minRadius = pExplosionParams->minRadius;
		float maxRadius = pExplosionParams->maxRadius;
		if (m_pAmmoParams->pFlashbang)
		{
			minRadius = m_pAmmoParams->pFlashbang->maxRadius;
			maxRadius = m_pAmmoParams->pFlashbang->maxRadius;
		}

		ExplosionInfo explosionInfo(m_ownerId, GetEntityId(), m_damage, epos, dir, minRadius, maxRadius, pExplosionParams->minPhysRadius, pExplosionParams->maxPhysRadius, 0.0f, pExplosionParams->pressure, pExplosionParams->holeSize, pGameRules->GetHitTypeId(pExplosionParams->type.c_str()));
		if(m_pAmmoParams->pFlashbang)
			explosionInfo.SetEffect(pExplosionParams->effectName, pExplosionParams->effectScale, pExplosionParams->maxblurdist, m_pAmmoParams->pFlashbang->blindAmount, m_pAmmoParams->pFlashbang->flashbangBaseTime);
		else
			explosionInfo.SetEffect(pExplosionParams->effectName, pExplosionParams->effectScale, pExplosionParams->maxblurdist);
		explosionInfo.SetEffectClass(m_pAmmoParams->pEntityClass->GetName());

		if (impact)
			explosionInfo.SetImpact(normal, vel, targetId);

		if (gEnv->bServer)
		{
			pGameRules->ServerExplosion(explosionInfo);

			// add battle dust as well
			CBattleDust* pBD = pGameRules->GetBattleDust();
			if(pBD)
				pBD->RecordEvent(eBDET_Explosion, pos, GetEntity()->GetClass());
		}
	}

	if(!gEnv->bMultiplayer)
	{
		//Single player (AI related code)is processed here, CGameRules::ClientExplosion process the effect
		if (m_pAmmoParams->pFlashbang)
			FlashbangEffect(m_pAmmoParams->pFlashbang);
	}

	if (destroy)
		Destroy();
}
//------------------------------------------------------------------------
void CVehicleDamageBehaviorExplosion::OnDamageEvent(EVehicleDamageBehaviorEvent event, const SVehicleDamageBehaviorEventParams &behaviorParams)
{
	if (event == eVDBE_Repair)
	{
		return;
	}

	if (!m_exploded && behaviorParams.componentDamageRatio >= 1.0f)
	{
		CGameRules *pGameRules = g_pGame->GetGameRules();

		if (pGameRules && gEnv->bServer)
		{
			ExplosionInfo explosionInfo;
			explosionInfo.damage = m_damage;
			explosionInfo.damage += (behaviorParams.randomness) * Random(-0.25f, 0.25f) * m_damage;

			if (m_pHelper)
			{
				explosionInfo.pos = m_pHelper->GetWorldSpaceTranslation();
			}
			else if (behaviorParams.pVehicleComponent)
			{
				explosionInfo.pos = m_pVehicle->GetEntity()->GetWorldTM() * behaviorParams.pVehicleComponent->GetBounds().GetCenter();
			}
			else
			{
				explosionInfo.pos = m_pVehicle->GetEntity()->GetWorldTM().GetTranslation();
			}

			explosionInfo.radius = m_radius;
			explosionInfo.minRadius = m_minRadius;
			explosionInfo.physRadius = m_physRadius;
			explosionInfo.minPhysRadius = m_minPhysRadius;
			explosionInfo.shooterId = behaviorParams.shooterId;
			explosionInfo.weaponId = m_pVehicle->GetEntityId();
			explosionInfo.pressure = m_pressure;
			pGameRules->ServerExplosion(explosionInfo);

			if(CBattleDust *pBD = pGameRules->GetBattleDust())
			{
				pBD->RecordEvent(eBDET_VehicleExplosion, explosionInfo.pos, m_pVehicle->GetEntity()->GetClass());
			}
		}

		m_exploded = true;
	}
}