Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
//------------------------------------------------------------------------
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);
				}
			}
		}
	}
}