void CBurnEffectManager::CreateBurnEffect(const EventPhysCollision& pCollision, CBurnEffectManager::SBurnPoint* pBurnPoint) { Vec3 surfaceNormal = pCollision.n; Vec3 hitDir(ZERO); if (pCollision.vloc[0].GetLengthSquared() > 1e-6f) { hitDir = pCollision.vloc[0].GetNormalized(); } Vec3 surfacePosition = pCollision.pt; Vec3 halfVector = (surfaceNormal + (-hitDir)).GetNormalized(); CItemParticleEffectCache& particleCache = g_pGame->GetGameSharedParametersStorage()->GetItemResourceCache().GetParticleEffectCache(); IParticleEffect* pParticleEffect = particleCache.GetCachedParticle(pBurnPoint->m_pBurnParams->m_effectName); if (pParticleEffect) { Matrix34 loc; loc.SetIdentity(); loc.SetTranslation(surfacePosition); loc.SetRotation33(OrthoNormalVector(surfaceNormal)); IParticleEmitter* pEffect = pParticleEffect->Spawn(false, loc); if(pEffect) { pEffect->AddRef(); pBurnPoint->m_effect = pEffect; const ParticleParams& particleParams = pParticleEffect->GetParticleParams(); pBurnPoint->m_attachType = particleParams.eAttachType; pBurnPoint->m_attachForm = particleParams.eAttachForm; } UpdateBurnEffect(pBurnPoint); } UpdateBurnEffect(pBurnPoint); }
//------------------------------------------------------------------------ void CCannonBall::HandleEvent(const SGameObjectEvent &event) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); BaseClass::HandleEvent(event); if (event.event == eGFE_OnCollision) { if (CheckAnyProjectileFlags(ePFlag_destroying)) return; EventPhysCollision *pCollision = reinterpret_cast<EventPhysCollision *>(event.ptr); if (!pCollision) return; float finalDamage = GetFinalDamage(pCollision->pt); if (finalDamage <= 0.0f) m_alive = false; IEntity *pTarget = pCollision->iForeignData[1]==PHYS_FOREIGN_ID_ENTITY ? (IEntity*)pCollision->pForeignData[1]:0; CGameRules *pGameRules = g_pGame->GetGameRules(); const int hitMatId = pCollision->idmat[1]; Vec3 hitDir(ZERO); if (pCollision->vloc[0].GetLengthSquared() > 1e-6f) { hitDir = pCollision->vloc[0].GetNormalized(); } const bool bProcessCollisionEvent = ProcessCollisionEvent(pTarget); if (bProcessCollisionEvent) { //================================= Process Hit ===================================== //Only process hits that have a target if(pTarget) { if(FilterFriendlyAIHit(pTarget) == false) { ProcessHit(*pGameRules, *pCollision, *pTarget, finalDamage, hitMatId, hitDir); } } //====================================~ Process Hit ====================================== //==================================== Notify AI ====================================== if (gEnv->pAISystem) { if (gEnv->pEntitySystem->GetEntity(m_ownerId)) { ISurfaceType *pSurfaceType = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceType(hitMatId); const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0; const float radius = pParams ? pParams->fImpactRadius : 2.5f; const float soundRadius = pParams ? pParams->fImpactSoundRadius : 20.0f; SAIStimulus stim(AISTIM_BULLET_HIT, 0, m_ownerId, pTarget ? pTarget->GetId() : 0, pCollision->pt, pCollision->vloc[0].GetNormalizedSafe(ZERO), radius); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus stimSound(AISTIM_SOUND, AISTIM_BULLET_HIT, m_ownerId, 0, pCollision->pt, ZERO, soundRadius); gEnv->pAISystem->RegisterStimulus(stim); } } //=========================================~ Notify AI =============================== } //========================================= Surface Pierceability ============================== if (pCollision->pEntity[0]->GetType() == PE_PARTICLE) { const SPierceabilityParams& pierceabilityParams = m_pAmmoParams->pierceabilityParams; //If collided water if( s_materialLookup.IsMaterial( pCollision->idmat[1], CProjectile::SMaterialLookUp::eType_Water ) ) { if(pierceabilityParams.DestroyOnWaterImpact()) { DestroyAtHitPosition(pCollision->pt); } else { EmitUnderwaterTracer(pCollision->pt, pCollision->pt + (pCollision->vloc[0].GetNormalizedSafe() * 100.0f)); } } else if (m_pAmmoParams->bounceableBullet == 0) { float bouncy, friction; uint32 pierceabilityMat; gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], bouncy, friction, pierceabilityMat); pierceabilityMat &= sf_pierceable_mask; const bool terrainHit = (pCollision->idCollider == -1); bool thouShallNotPass = terrainHit; if (!CheckAnyProjectileFlags(ePFlag_ownerIsPlayer)) thouShallNotPass = thouShallNotPass || pierceabilityParams.DestroyOnImpact(pierceabilityMat); if (!thouShallNotPass) HandlePierceableSurface(pCollision, pTarget, hitDir, bProcessCollisionEvent); const bool destroy = thouShallNotPass || ShouldDestroyCannonBall(); if (destroy) { DestroyAtHitPosition(pCollision->pt); } } } } }