//------------------------------------------------------------------------ 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; } }