Пример #1
0
bool CDialogActorContext::ExecuteAI(int& goalPipeID, const char* signalText, IAISignalExtraData* pExtraData, bool bRegisterAsListener)
{
	IEntitySystem* pSystem = gEnv->pEntitySystem;
	IEntity* pEntity = pSystem->GetEntity(m_entityID);
	if (pEntity == 0)
		return false;

	IAIObject* pAI = pEntity->GetAI();
	if (pAI == 0)
		return false;

	unsigned short nType=pAI->GetAIType();
	if ( nType != AIOBJECT_ACTOR )
	{
		if ( nType == AIOBJECT_PLAYER )
		{
			goalPipeID = -1;

			// not needed for player 
			// pAI->SetSignal( 10, signalText, pEntity, NULL ); // 10 means this signal must be sent (but sent[!], not set)
			// even if the same signal is already present in the queue
			return true;
		}

		// invalid AIObject type
		return false;
	}

	IPipeUser* pPipeUser = pAI->CastToIPipeUser();
	if (pPipeUser)
	{
		if (goalPipeID > 0)
		{
			pPipeUser->RemoveSubPipe(goalPipeID, true);
			pPipeUser->UnRegisterGoalPipeListener( this, goalPipeID );
			goalPipeID = 0;
		}
	}

	goalPipeID = gEnv->pAISystem->AllocGoalPipeId();
	if (pExtraData == 0)
		pExtraData = gEnv->pAISystem->CreateSignalExtraData();
	pExtraData->iValue = goalPipeID;
	
	if (pPipeUser && bRegisterAsListener)
	{
		pPipeUser->RegisterGoalPipeListener( this, goalPipeID, "CDialogActorContext::ExecuteAI");
	}

	IAIActor* pAIActor = CastToIAIActorSafe(pAI);
	if(pAIActor)
		pAIActor->SetSignal( 10, signalText, pEntity, pExtraData ); // 10 means this signal must be sent (but sent[!], not set)
	// even if the same signal is already present in the queue
	return true;
}
//////////////////////////////////////////////////////////////////////////
// IsMountedWeaponUsableWithTarget
// A piece of game-code moved from CryAction when scriptbind_AI moved to the AI system
//////////////////////////////////////////////////////////////////////////
int CScriptBind_Game::IsMountedWeaponUsableWithTarget(IFunctionHandler *pH)
{
	int paramCount = pH->GetParamCount();
	if(paramCount<2)
	{
		GameWarning("%s: too few parameters.", __FUNCTION__);
		return pH->EndFunction();
	}

	GET_ENTITY(1);

	if(!pEntity)
	{
		GameWarning("%s: wrong entity id in parameter 1.", __FUNCTION__);
		return pH->EndFunction();
	}

	IAIObject* pAI = pEntity->GetAI();
	if (!pAI)
	{
		GameWarning("%s: Entity '%s' does not have AI.",__FUNCTION__,  pEntity->GetName());
		return pH->EndFunction();
	}

	EntityId itemEntityId;
	ScriptHandle hdl2;

	if(!pH->GetParam(2,hdl2))
	{
		GameWarning("%s: wrong parameter 2 format.", __FUNCTION__);
		return pH->EndFunction();
	}

	itemEntityId = (EntityId)hdl2.n;

	if (!itemEntityId)
	{
		GameWarning("%s: wrong entity id in parameter 2.", __FUNCTION__);
		return pH->EndFunction();
	}
	
	IGameFramework *pGameFramework = gEnv->pGame->GetIGameFramework();
	IItem* pItem = pGameFramework->GetIItemSystem()->GetItem(itemEntityId);
	if (!pItem)
	{
		//gEnv->pAISystem->Warning("<CScriptBind> ", "entity in parameter 2 is not an item/weapon");
		GameWarning("%s: entity in parameter 2 is not an item/weapon.", __FUNCTION__);
		return pH->EndFunction();
	}

	float minDist = 7;
	bool bSkipTargetCheck = false;
	Vec3 targetPos(ZERO);

	if(paramCount > 2)
	{
		for(int i=3;i <= paramCount ; i++)
		{
			if(pH->GetParamType(i) == svtBool)
				pH->GetParam(i,bSkipTargetCheck);
			else if(pH->GetParamType(i) == svtNumber)
				pH->GetParam(i,minDist);
			else if(pH->GetParamType(i) == svtObject)
				pH->GetParam(i,targetPos);
		}
	}

	IAIActor* pAIActor = CastToIAIActorSafe(pAI);
	if (!pAIActor)
	{
		GameWarning("%s: entity '%s' in parameter 1 is not an AI actor.", __FUNCTION__, pEntity->GetName());
		return pH->EndFunction();
	}


	IEntity* pItemEntity = pItem->GetEntity();
	if(!pItemEntity)
		return pH->EndFunction();


	if(!pItem->GetOwnerId())
	{
		// weapon is not used, check if it is on a vehicle
		IEntity* pParentEntity = pItemEntity->GetParent();
		if(pParentEntity)
		{
			IAIObject* pParentAI = pParentEntity->GetAI();
			if(pParentAI && pParentAI->GetAIType()==AIOBJECT_VEHICLE)
			{
				// (MATT) Feature was cut and code was tricky, hence ignore weapons in vehicles  {2008/02/15:11:08:51}
				return pH->EndFunction();
			}
		}
	}
	else if( pItem->GetOwnerId()!= pEntity->GetId()) // item is used by someone else?
		return pH->EndFunction(false);

	// check target
	if(bSkipTargetCheck)
		return pH->EndFunction(true);

	IAIObject* pTarget = pAIActor->GetAttentionTarget();
	if(targetPos.IsZero())
	{
		if(!pTarget)
			return pH->EndFunction();
		targetPos = pTarget->GetPos();
	}

	Vec3 targetDir(targetPos - pItemEntity->GetWorldPos());
	Vec3 targetDirXY(targetDir.x, targetDir.y, 0);

	float length2D = targetDirXY.GetLength();
	if(length2D < minDist || length2D<=0)
		return pH->EndFunction();

	targetDirXY /= length2D;//normalize

	IWeapon* pWeapon = pItem->GetIWeapon(); 
	bool vehicleGun = pWeapon && pWeapon->GetHostId();

	if (!vehicleGun)
	{
		Vec3 mountedAngleLimits(pItem->GetMountedAngleLimits());

		float yawRange = DEG2RAD(mountedAngleLimits.z);
		if(yawRange > 0 && yawRange < gf_PI)
		{
			float deltaYaw = pItem->GetMountedDir().Dot(targetDirXY);
			if(deltaYaw < cosf(yawRange))
				return pH->EndFunction(false);
		}

		float minPitch = DEG2RAD(mountedAngleLimits.x);
		float maxPitch = DEG2RAD(mountedAngleLimits.y);

		//maxPitch = (maxPitch - minPitch)/2;
		//minPitch = -maxPitch;

		float pitch = atanf(targetDir.z / length2D);

		if ( pitch < minPitch || pitch > maxPitch )
			return pH->EndFunction(false);
	}

	if(pTarget)
	{
		IEntity* pTargetEntity = pTarget->GetEntity();
		if(pTargetEntity)
		{
			// check target distance and where he's going
			IPhysicalEntity *phys = pTargetEntity->GetPhysics();
			if(phys)
			{
				pe_status_dynamics	dyn;
				phys->GetStatus(&dyn);
				Vec3 velocity ( dyn.v);
				velocity.z = 0;

				float speed = velocity.GetLength2D();
				if(speed>0)
				{
					//velocity /= speed;
					if(length2D< minDist * 0.75f && velocity.Dot(targetDirXY)<=0)
						return pH->EndFunction(false);
				}
			}
		}
	}
	return pH->EndFunction(true);

}
Пример #3
0
//------------------------------------------------------------------------
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);
						}
					}
				}
*/
			}
		}
	}

}
Пример #4
0
//------------------------------------------------------------------------
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);
		}
	}

}
Пример #5
0
//------------------------------------------------------------------------
void CProjectile::HandleEvent(const SGameObjectEvent &event)
{
	if(m_destroying)
		return;

	FUNCTION_PROFILER(GetISystem(), PROFILE_GAME);

	if(event.event == eGFE_OnCollision)
	{
		EventPhysCollision *pCollision = (EventPhysCollision *)event.ptr;

		if(pCollision == NULL)
			return;

		const SCollisionParams *pCollisionParams = m_pAmmoParams->pCollision;

		if(pCollisionParams)
		{
			if(pCollisionParams->pParticleEffect)
				pCollisionParams->pParticleEffect->Spawn(true, IParticleEffect::ParticleLoc(pCollision->pt, pCollision->n, pCollisionParams->scale));

			if(pCollisionParams->sound)
			{
				_smart_ptr<ISound> pSound = gEnv->pSoundSystem->CreateSound(pCollisionParams->sound, FLAG_SOUND_DEFAULT_3D);

				if(pSound)
				{
					pSound->SetSemantic(eSoundSemantic_Projectile);
					pSound->SetPosition(pCollision->pt);
					pSound->Play();
				}
			}
		}

		// add battledust for bulletimpact
		if(gEnv->bServer && g_pGame->GetGameRules())
		{
			if(CBattleDust *pBD = g_pGame->GetGameRules()->GetBattleDust())
			{
				pBD->RecordEvent(eBDET_ShotImpact, pCollision->pt, GetEntity()->GetClass());
			}
		}

		Ricochet(pCollision);

		//Update damage
		if((m_damageDropPerMeter>0.0001f)&&
				(((pCollision->pt-m_initial_pos).len2()>m_damageDropMinDisSqr)||m_firstDropApplied))
		{

			if(!m_firstDropApplied)
			{
				m_firstDropApplied = true;
				m_initial_pos = m_initial_pos + (m_initial_dir*(sqrt_fast_tpl(m_damageDropMinDisSqr)));
			}

			Vec3 vDiff = pCollision->pt - m_initial_pos;
			float dis  = vDiff.len();

			m_damage -= (int)(floor_tpl(m_damageDropPerMeter * dis));

			//Check m_damage is positive
			if(m_damage<MIN_DAMAGE)
				m_damage=MIN_DAMAGE;

			//Also modify initial position (the projectile could not be destroyed, cause of pirceability)
			m_initial_pos = pCollision->pt;
		}

		// Notify AI system about grenades.
		if(gEnv->pAISystem)
		{
			IAIObject *pAI = 0;

			if((pAI = GetEntity()->GetAI()) != NULL && pAI->GetAIType() == AIOBJECT_GRENADE)
			{
				// 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(ownerId);

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

				SAIStimulus stim(AISTIM_GRENADE, AIGRENADE_COLLISION, ownerId, GetEntityId(),
								 GetEntity()->GetWorldPos(), ZERO, 12.0f);
				gEnv->pAISystem->RegisterStimulus(stim);
			}
		}
	}
}