コード例 #1
0
ファイル: Projectile.cpp プロジェクト: Hellraiser666/CryGame
//------------------------------------------------------------------------
void CProjectile::Launch(const Vec3 &pos, const Vec3 &dir, const Vec3 &velocity, float speedScale)
{
	m_destroying = false;

	GetGameObject()->EnablePhysicsEvent(true, eEPE_OnCollisionLogged);

	// Only for bullets
	m_hitPoints = m_pAmmoParams->hitPoints;
	m_hitListener = false;

	if(m_hitPoints>0)
	{
		//Only projectiles with hit points are hit listeners
		g_pGame->GetGameRules()->AddHitListener(this);
		m_hitListener = true;
		m_noBulletHits = m_pAmmoParams->noBulletHits;
	}

	Matrix34 worldTM=Matrix34(Matrix33::CreateRotationVDir(dir.GetNormalizedSafe()));
	worldTM.SetTranslation(pos);
	GetEntity()->SetWorldTM(worldTM);

	//Must set velocity after position, if not velocity could be reseted for PE_RIGID
	SetVelocity(pos, dir, velocity, speedScale);

	m_initial_pos = pos;
	m_initial_dir = dir;
	m_initial_vel = velocity;

	m_last = pos;

	// Attach effect when fired (not first update)
	if(m_trailEffectId<0)
		TrailEffect(true);

	IAIObject *pAI = 0;

	if((pAI = GetEntity()->GetAI()) != NULL && pAI->GetAIType() == AIOBJECT_GRENADE)
	{
		IEntity *pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId);
		pe_status_dynamics dyn;
		pe_status_dynamics dynProj;

		if(pOwnerEntity->GetPhysics()
				&& pOwnerEntity->GetPhysics()->GetStatus(&dyn)
				&& GetEntity()->GetPhysics()->GetStatus(&dynProj))
		{

//			Vec3 ownerVel(dyn.v);
			Vec3 grenadeDir(dynProj.v.GetNormalizedSafe());

			// Trigger the signal at the predicted landing position.
			Vec3 predictedPos = pos;
			float dummySpeed;

			if(GetWeapon())
				GetWeapon()->PredictProjectileHit(pOwnerEntity->GetPhysics(), pos, dir, velocity, speedScale * m_pAmmoParams->speed, predictedPos, dummySpeed);

			// Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc)
			EntityId ownerId = pOwnerEntity->GetId();
			IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId);

			if(pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId())
				ownerId = pActor->GetLinkedVehicle()->GetEntityId();

			SAIStimulus stim(AISTIM_GRENADE, AIGRENADE_THROWN, ownerId, GetEntityId(),
							 predictedPos, ZERO, 20.0f);
			gEnv->pAISystem->RegisterStimulus(stim);
		}
	}

}
コード例 #2
0
ファイル: Projectile.cpp プロジェクト: mrwonko/CrysisVR
//------------------------------------------------------------------------
void CProjectile::Launch(const Vec3 &pos, const Vec3 &dir, const Vec3 &velocity, float speedScale)
{
	Matrix34 worldTM=Matrix34(Matrix33::CreateRotationVDir(dir.GetNormalizedSafe()));
	worldTM.SetTranslation(pos);
	GetEntity()->SetWorldTM(worldTM);

	//Must set velocity after position, if not velocity could be reseted for PE_RIGID
	SetVelocity(pos, dir, velocity, speedScale);

	m_initial_pos = pos;
	m_initial_dir = dir;
	m_initial_vel = velocity;

	m_last = pos;

	// Attach effect when fired (not first update)
	if (m_trailEffectId<0)
		TrailEffect(true);

	IAIObject* pAI = 0;
	if ((pAI = GetEntity()->GetAI()) != NULL && pAI->GetAIType() == AIOBJECT_GRENADE)
	{
		IEntity *pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId);
		if (pOwnerEntity && pOwnerEntity->GetAI())
		{
			pe_status_dynamics dyn;
			pe_status_dynamics dynProj;
			if (pOwnerEntity->GetAI()->GetProxy() && pOwnerEntity->GetPhysics() 
				&& pOwnerEntity->GetPhysics()->GetStatus(&dyn) 
				&& GetEntity()->GetPhysics()->GetStatus(&dynProj))
			{
				
				Vec3 ownerVel( dyn.v);
				Vec3 grenadeDir(dynProj.v.GetNormalizedSafe());

				// Trigger the signal at the predicted landing position.
				Vec3 predictedPos = pos;
				float dummySpeed;
				if (GetWeapon())
					GetWeapon()->PredictProjectileHit(pOwnerEntity->GetPhysics(), pos, dir, velocity, speedScale * m_pAmmoParams->speed, predictedPos, dummySpeed);
/*				bool res = pOwnerEntity->GetAI()->GetProxy()->GetSecWeapon()->PredictProjectileHit(
					pOwnerEntity->GetPhysics(), GetEntity()->GetPos(), grenadeDir, ownerVel, 1, predictedPos, speed);*/

				gEnv->pAISystem->GrenadeEvent(predictedPos, 0.0f, AIGE_GRENADE_THROWN, GetEntity(), pOwnerEntity);

				// Inform the AI that sees the throw
/*				IAIObject* pOwnerAI = pOwnerEntity->GetAI();
				AutoAIObjectIter it(gEnv->pAISystem->GetFirstAIObjectInRange(IAISystem::OBJFILTER_TYPE, AIOBJECT_PUPPET, predictedPos, 20.0f, false));
				for(; it->GetObject(); it->Next())
				{
					IAIObject* pAI = it->GetObject();
					if (!pAI->IsEnabled()) continue;
					if (pOwnerAI && !pOwnerAI->IsHostile(pAI,false))
						continue;

					// Only sense grenades that are on front of the AI and visible when thrown.
					// Another signal is sent when the grenade hits the ground.
					Vec3 delta = GetEntity()->GetPos() - pAI->GetPos();	// grenade to AI
					float dist = delta.NormalizeSafe();
					const float thr = cosf(DEG2RAD(160.0f));
					if (delta.Dot(pAI->GetViewDir()) > thr)
					{
						ray_hit hit;
						static const int objTypes = ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid;
						static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any;
						int res = gEnv->pPhysicalWorld->RayWorldIntersection(pAI->GetPos(), delta*dist, objTypes, flags, &hit, 1);
						if (!res || hit.dist > dist*0.9f)
						{
							IAISignalExtraData* pEData = gEnv->pAISystem->CreateSignalExtraData();	// no leak - this will be deleted inside SendAnonymousSignal
							pEData->point = predictedPos;
							pEData->nID = pOwnerEntity->GetId();
							pEData->iValue = 1;
							gEnv->pAISystem->SendSignal(SIGNALFILTER_SENDER, 1, "OnGrenadeDanger", pAI, pEData);
						}
					}
				}
*/
			}
		}
	}

}
コード例 #3
0
ファイル: Bullet.cpp プロジェクト: Arnm7890/CryGame
//------------------------------------------------------------------------
void CBullet::HandleEvent(const SGameObjectEvent &event)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	CProjectile::HandleEvent(event);

	if (event.event == eGFE_OnCollision)
	{
		if (m_destroying)
			return;

		EventPhysCollision *pCollision = reinterpret_cast<EventPhysCollision *>(event.ptr);
		if (!pCollision)
			return;
        
		IEntity *pTarget = pCollision->iForeignData[1]==PHYS_FOREIGN_ID_ENTITY ? (IEntity*)pCollision->pForeignData[1]:0;

		//Only process hits that have a target
		if(pTarget)
		{
			Vec3 dir(0, 0, 0);
			if (pCollision->vloc[0].GetLengthSquared() > 1e-6f)
				dir = pCollision->vloc[0].GetNormalized();

			CGameRules *pGameRules = g_pGame->GetGameRules();

			IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerId);

			bool ok = true;

			if(!gEnv->bMultiplayer && pActor && pActor->IsPlayer())
			{
				IActor* pAITarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId());
				if(pAITarget && pTarget->GetAI() && pTarget->GetAI()->IsFriendly(pActor->GetEntity()->GetAI(), false))
				{
					pGameRules->SetEntityToIgnore(pTarget->GetId());
					ok = false;
				}
			}

			if(ok)
			{
				HitInfo hitInfo(m_ownerId, pTarget->GetId(), m_weaponId,
					(float)m_damage, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(pCollision->idmat[1]), pCollision->partid[1],
					m_hitTypeId, pCollision->pt, dir, pCollision->n);

				hitInfo.remote = IsRemote();
				hitInfo.projectileId = GetEntityId();
				hitInfo.bulletType = m_pAmmoParams->bulletType;

				pGameRules->ClientHit(hitInfo);

				// Notify AI
				if (gEnv->pAISystem && !gEnv->bMultiplayer)
				{
					static int htMelee = pGameRules->GetHitTypeId("melee");
					if (m_ownerId && m_hitTypeId != htMelee)
					{
						ISurfaceType *pSurfaceType = pGameRules->GetHitMaterial(hitInfo.material);
						const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0;
						const float radius = pParams ? pParams->fImpactRadius : 2.5f;
						const float soundRadius = pParams ? pParams->fImpactSoundRadius : 20.0f;
						
						// Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc)
						EntityId ownerId = m_ownerId;
						if (pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId())
							ownerId = pActor->GetLinkedVehicle()->GetEntityId();

						SAIStimulus stim(AISTIM_BULLET_HIT, 0, ownerId, 0, pCollision->pt, ZERO, radius);
						gEnv->pAISystem->RegisterStimulus(stim);

						SAIStimulus stimSound(AISTIM_SOUND, AISOUND_COLLISION_LOUD, ownerId, 0, pCollision->pt, ZERO, soundRadius, AISTIMPROC_FILTER_LINK_WITH_PREVIOUS);
						gEnv->pAISystem->RegisterStimulus(stimSound);

					}
				}

			}
		}
		else
		{
			// Notify AI
			// The above case only catches entity vs. entity hits, the AI is interested in all hits.
			if (gEnv->pAISystem && !gEnv->bMultiplayer)
			{
				CGameRules *pGameRules = g_pGame->GetGameRules();
				static int htMelee = pGameRules->GetHitTypeId("melee");
				if (m_ownerId && m_hitTypeId != htMelee)
				{
					int material = pGameRules->GetHitMaterialIdFromSurfaceId(pCollision->idmat[1]);
					ISurfaceType *pSurfaceType = pGameRules->GetHitMaterial(material);
					const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0;
					const float radius = pParams ? pParams->fImpactRadius : 2.5f;
					const float soundRadius = pParams ? pParams->fImpactSoundRadius : 20.0f;

					// Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc)
					EntityId ownerId = m_ownerId;
					IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerId);
					if (pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId())
						ownerId = pActor->GetLinkedVehicle()->GetEntityId();

					SAIStimulus stim(AISTIM_BULLET_HIT, 0, ownerId, 0, pCollision->pt, ZERO, radius);
					gEnv->pAISystem->RegisterStimulus(stim);

					SAIStimulus stimSound(AISTIM_SOUND, AISOUND_COLLISION_LOUD, ownerId, 0, pCollision->pt, ZERO, soundRadius, AISTIMPROC_FILTER_LINK_WITH_PREVIOUS);
					gEnv->pAISystem->RegisterStimulus(stimSound);

				}
			}
		}


		if (pCollision->pEntity[0]->GetType() == PE_PARTICLE)
		{
			float bouncy, friction;
			uint32	pierceabilityMat;
			gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], bouncy, friction, pierceabilityMat);
			pierceabilityMat&=sf_pierceable_mask;
			
			pe_params_particle params;
			if(pCollision->pEntity[0]->GetParams(&params)==0)
				SetDefaultParticleParams(&params);

			//Under water trail
			Vec3 pos=pCollision->pt;
			if ((pCollision->idmat[1] == CBullet::m_waterMaterialId) && 
					(pCollision->pEntity[1]!=gEnv->pPhysicalWorld->AddGlobalArea() || !gEnv->p3DEngine->GetVisAreaFromPos(pos)))
			{
				//Reduce drastically bullet velocity (to be able to see the trail effect)
				//pe_params_particle pparams;
				//if(m_pPhysicalEntity->GetParams(&pparams)==0)
					//SetDefaultParticleParams(&pparams);
				//pparams.velocity = 25.0f;

				//m_pPhysicalEntity->SetParams(&pparams);

				if(m_trailUnderWaterId<0)
				{
					//Check terrain/against water level
					float terrainHeight = gEnv->p3DEngine->GetTerrainElevation(pCollision->pt.x,pCollision->pt.y);
					float waterLevel = gEnv->p3DEngine->GetWaterLevel(&(pCollision->pt));
					if(waterLevel>terrainHeight)
					{
						TrailEffect(true,true);
						return;
					}
				}
			}

			if (pierceabilityMat<=params.iPierceability || pCollision->idCollider==-1) //Do not destroy if collides water
				Destroy();
		}
	}
}