Ejemplo n.º 1
0
void CGameAIRecorder::AddRecordComment(EntityId requesterId, const char* szComment)
{
	assert(szComment && szComment[0]);
	assert(requesterId > 0);
	assert(gEnv->bServer);

	if (m_bIsRecording && szComment && szComment[0])
	{
		if (!gEnv->bServer)
		{
			CryLogAlways("[AI] Recorder comment requested on Client. Only the Server can do this!");
			return;
		}

		IEntity *pEntity = gEnv->pEntitySystem->GetEntity(requesterId);
		IAIObject *pAI = pEntity ? pEntity->GetAI() : NULL;
		if (!pAI)
		{
			CryLogAlways("[AI] Attempting to add recorder comment, but the requester does not have an AI!");
			return;
		}

		// Output to log
		CryLogAlways("[AI] --- RECORDER COMMENT ADDED ---");
		CryLogAlways("[AI] By: %s", pEntity->GetName());
		CryLogAlways("[AI] Comment: %s", szComment);

		// Add comment to stream
		RecordLuaComment(pAI, "Comment: %s", szComment);
	}
}
Ejemplo n.º 2
0
bool CCannonBall::FilterFriendlyAIHit(IEntity* pHitTarget)
{
	bool bResult = false;

	if (!gEnv->bMultiplayer && pHitTarget)
	{
		const bool bIsClient = (m_ownerId == g_pGame->GetIGameFramework()->GetClientActorId());
		IEntity* pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId);

		//Filter client hits against friendly AI
		if (pOwnerEntity && bIsClient)
		{
			IAIObject *pOwnerAI = pOwnerEntity->GetAI();
			IAIObject *pTargetAI = pHitTarget->GetAI();
			if (pOwnerAI && pTargetAI && !pTargetAI->IsHostile(pOwnerAI))
			{
				const bool bEnableFriendlyHit = g_pGameCVars->g_enableFriendlyPlayerHits != 0;
				if (!bEnableFriendlyHit)
				{
					g_pGame->GetGameRules()->SetEntityToIgnore(pHitTarget->GetId());
					bResult = true;
				}
			}
		}
	}

	return bResult;
}
Ejemplo n.º 3
0
EEntityType GetEntityType(EntityId id)
{
	int type = eET_Unknown;

	IEntitySystem *pEntitySystem = gEnv->pEntitySystem;
	if (pEntitySystem)
	{
		IEntity *pEntity = pEntitySystem->GetEntity(id);
		if (pEntity)
		{
			type = eET_Valid;

			IEntityClass *pClass = pEntity->GetClass();
			if (pClass)
			{
				const char* className = pClass->GetName();

				// Check AI
				if (pEntity->GetAI())
				{
					type |= eET_AI;
				}
				
				// Check actor
				IActorSystem *pActorSystem = gEnv->pGame->GetIGameFramework()->GetIActorSystem();
				if (pActorSystem)
				{
					IActor *pActor = pActorSystem->GetActor(id);
					if (pActor)
					{
						type |= eET_Actor;
					}
				}

				// Check vehicle
				IVehicleSystem *pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem();
				if (pVehicleSystem)
				{
					if (pVehicleSystem->IsVehicleClass(className))
					{
						type |= eET_Vehicle;
					}
				}

				// Check item
				IItemSystem *pItemSystem = gEnv->pGame->GetIGameFramework()->GetIItemSystem();
				if (pItemSystem)
				{
					if (pItemSystem->IsItemClass(className))
					{
						type |= eET_Item;
					}
				}
			}
		}
	}

	return (EEntityType)type;
}
Ejemplo n.º 4
0
void CPersistantDebug::AddEntityTag(const SEntityTagParams& params, const char *tagContext)
{
    // Create tag
    SEntityTag tag;
    tag.params = params;
    tag.params.column = max(1, tag.params.column);
    tag.params.visibleTime = max(0.f, tag.params.visibleTime);
    tag.params.fadeTime = max(0.f, tag.params.fadeTime);
    if (tagContext != NULL && *tagContext != '\0')
        tag.params.tagContext = tagContext;
    tag.totalTime = tag.params.visibleTime + tag.params.fadeTime;
    tag.totalFadeTime = tag.params.fadeTime;
    tag.vScreenPos.zero();

    SObj *obj = FindObj(params.entity);
    if (!obj)
    {
        // Create new object to push back
        SObj sobj;
        sobj.obj = eOT_EntityTag;
        sobj.entityId = params.entity;
        sobj.entityHeight = 0.f;
        sobj.timeRemaining = tag.totalTime;
        sobj.totalTime = tag.totalTime;
        sobj.columns.resize(params.column);
        AddToTagList(sobj.tags, tag);

        m_objects[entityTagsContext].push_back(sobj);
    }
    else
    {
        obj->timeRemaining = max(obj->timeRemaining, tag.totalTime);
        obj->totalTime = obj->timeRemaining;
        int size = max(int(obj->columns.size()), params.column);
        if (obj->columns.size() < size)
            obj->columns.resize(size);

        AddToTagList(obj->tags, tag);
    }

    if (m_pETLog->GetIVal() > 0)
    {
        IEntity *ent = gEnv->pEntitySystem->GetEntity(params.entity);
        if (ent)
        {
            CryLog("[Entity Tag] %s added tag: %s", ent->GetName(), params.text.c_str());

            if (m_pETLog->GetIVal() > 1)
            {
                char text[256];
                _snprintf(text, sizeof(text), "[Entity Tag] %s", params.text.c_str());
                gEnv->pAISystem->Record(ent->GetAI(), IAIRecordable::E_NONE, text);
            }
        }
    }
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
//------------------------------------------------------------------------
void CProjectile::InitWithAI()
{
	// register with ai if needed
	//FIXME
	//make AI ignore grenades thrown by AI; needs proper/readable grenade reaction
	if (m_pAmmoParams->aiType!=AIOBJECT_NONE)
	{
		bool	isFriendlyGrenade(true);
		IEntity *pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId);

		if (pOwnerEntity && pOwnerEntity->GetAI())
			isFriendlyGrenade = (pOwnerEntity->GetAI()->GetAIType() == AIOBJECT_ACTOR);

		if (!isFriendlyGrenade)
		{
			GetEntity()->RegisterInAISystem(AIObjectParams(m_pAmmoParams->aiType));
		}
	}
	GetGameObject()->SetAIActivation(eGOAIAM_Always);
}
Ejemplo n.º 7
0
//------------------------------------------------------------------------
int CScriptBind_Action::SetAimQueryMode(IFunctionHandler* pH, ScriptHandle entityId, int mode)
{
	IEntity* entity = gEnv->pEntitySystem->GetEntity(static_cast<EntityId>(entityId.n));
	IAIObject* ai = entity ? entity->GetAI() : NULL;
	CAIProxy* proxy = ai ? static_cast<CAIProxy*>(ai->GetProxy()) : NULL;

	if (proxy)
		proxy->SetAimQueryMode(static_cast<CAIProxy::AimQueryMode>(mode));

	return pH->EndFunction();
}
Ejemplo n.º 8
0
//------------------------------------------------------------------------
void CProjectile::SetParams(EntityId ownerId, EntityId hostId, EntityId weaponId, int damage, int hitTypeId, float damageDrop /*= 0.0f*/, float damageDropMinR /*=0.0f*/)
{
	m_ownerId = ownerId;
	m_weaponId = weaponId;
	m_hostId = hostId;
	m_damage = damage;
	m_hitTypeId = hitTypeId;
	m_damageDropPerMeter = damageDrop;
	m_damageDropMinDisSqr = damageDropMinR*damageDropMinR;

	if(m_hostId || m_ownerId)
	{
		IEntity *pSelfEntity = GetEntity();

		if(pSelfEntity)
			pSelfEntity->AddEntityLink("Shooter", m_ownerId);

		IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_hostId?m_hostId:m_ownerId);

		if(pEntity)
		{
			if(pSelfEntity)
			{
				//need to set AI species to the shooter - not to be scared of it's own rockets
				IAIObject *projectileAI = pSelfEntity->GetAI();
				IAIObject *shooterAI = pEntity->GetAI();

				if(projectileAI && shooterAI)
					projectileAI->SetFactionID(shooterAI->GetFactionID());
			}

			if(m_pPhysicalEntity && m_pPhysicalEntity->GetType()==PE_PARTICLE)
			{
				pe_params_particle pparams;
				pparams.pColliderToIgnore = pEntity->GetPhysics();

				m_pPhysicalEntity->SetParams(&pparams);
			}
		}
	}
}
CAIAwarenessToPlayerHelper::VisorIconColor CAIAwarenessToPlayerHelper::GetMarkerColorForAgent(const EntityId entityId) const
{
	CAIAwarenessToPlayerHelper::VisorIconColor defaultColor = Green;
	IEntity* entity = gEnv->pEntitySystem->GetEntity(entityId);
	const IAIObject* ai = entity ? entity->GetAI() : NULL;
	const IAIActor* aiActor = ai ? ai->CastToIAIActor() : NULL;
	IAIObject* playerAiObject = NULL;
	CActor* playerActor = static_cast<CActor*>(gEnv->pGame->GetIGameFramework()->GetClientActor());
	if (playerActor)
	{
		if (IEntity* playerEntity = playerActor->GetEntity())
		{
			playerAiObject = playerEntity->GetAI();
		}
	}
	if (!playerActor || !playerAiObject)
		return defaultColor;

	const bool playerIsCloaked = playerActor->IsCloaked();

	if (aiActor)
	{
		const int alertness = GetAlertnessAffectedByVisibility(*aiActor, *playerAiObject, playerIsCloaked);

		if (alertness == 0)
			return Green;
		else if (alertness == 1)
			return Orange;
		else
			return Red;
	}
	else
	{
		// Turrets are not AI actors so they are treated a bit differently
		// TODO: extend this to generic IAwarenessEntity. for now in C3 is fine as we dont want Towers to be show here.
		if (CTurret* turret = TurretHelpers::FindTurret(entityId))
		{
			if (IEntity* turretEntity = turret->GetEntity())
			{
				if (IAIObject* turretAI = turretEntity->GetAI())
				{
					const bool turretIsDeployed = (turret->GetStateId() == eTurretBehaviorState_Deployed);
					if (!playerIsCloaked && turretIsDeployed && turretAI->IsHostile(playerAiObject) && turret->IsVisionIdInVisionRange(playerAiObject->GetVisionID()))
						return Red;
					else
						return Green;
				}
			}
		}
	}

	return defaultColor;
}
Ejemplo n.º 10
0
// Description:
//
// Arguments:
//
// Return:
//
IAIObject const* CPersonalRangeSignaling::GetEntityAI(EntityId entityId) const
{
	IAIObject const* pAIObject = NULL;

	IEntity *pEntity = gEnv->pEntitySystem->GetEntity(entityId);
	if (pEntity)
	{
		pAIObject = pEntity->GetAI();
	}

	return pAIObject;
}
Ejemplo n.º 11
0
//------------------------------------------------------------------------
void CProjectile::SetParams(EntityId ownerId, EntityId hostId, EntityId weaponId, int fmId, int damage, int hitTypeId)
{
	m_ownerId = ownerId;
	m_weaponId = weaponId;
	m_fmId = fmId;
	m_hostId = hostId;
	m_damage = damage;
  m_hitTypeId = hitTypeId;

	if (m_hostId || m_ownerId)
	{
		IEntity* pSelfEntity = GetEntity();
		if (pSelfEntity)
			pSelfEntity->AddEntityLink("Shooter", m_ownerId);

		IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_hostId?m_hostId:m_ownerId);
		if (pEntity)
		{
			if (pSelfEntity)
			{
				//need to set AI species to the shooter - not to be scared of it's own rockets 
				IAIActor* pAIActor = CastToIAIActorSafe(pSelfEntity->GetAI());
				IAIActor* pShooterAIActor = CastToIAIActorSafe(pEntity->GetAI());
				if (pAIActor && pShooterAIActor)
				{
					AgentParameters ap = pAIActor->GetParameters();
					ap.m_nSpecies = pShooterAIActor->GetParameters().m_nSpecies;
					pAIActor->SetParameters(ap);
				}
			}
			if (m_pPhysicalEntity && m_pPhysicalEntity->GetType()==PE_PARTICLE)
			{
				pe_params_particle pparams;
				pparams.pColliderToIgnore = pEntity->GetPhysics();

				m_pPhysicalEntity->SetParams(&pparams);
			}
		}
	}
}
Ejemplo n.º 12
0
//------------------------------------------------------------------------
int CScriptBind_Action::HasAI(IFunctionHandler* pH, ScriptHandle entityId)
{
	bool bResult = false;

	const EntityId id = (EntityId)entityId.n;
	IEntity *pEntity = gEnv->pEntitySystem->GetEntity(id);
	if (pEntity)
	{
		bResult = (pEntity->GetAI() != 0);
	}

	return pH->EndFunction(bResult);
}
Ejemplo n.º 13
0
// Description:
//
// Arguments:
//
// Return:
//
void CPersonalSignalTimer::SendSignal()
{
  CRY_ASSERT( m_bInit == true );

  IEntity *pEntity = GetEntity();
  if (pEntity && gEnv->pAISystem)
  {
    IAISignalExtraData*   pData = gEnv->pAISystem->CreateSignalExtraData();
    pData->iValue = ++m_iSignalsSinceLastReset;
    pData->fValue = m_fTimerSinceLastReset;

    gEnv->pAISystem->SendSignal( SIGNALFILTER_SENDER, 1, m_sSignal, pEntity->GetAI(), pData );
  }
}
// Description:
//
// Arguments:
//
// Return:
//
float CAngleAlert::GetAngleTo( const Vec3& vPos ) const
{
    float fResult = 0.0f;
    IEntity* pEntity = m_pPersonal->GetEntity();
    CRY_ASSERT(pEntity);
    if (pEntity)
    {
        const Vec3&  vEntityPos = pEntity->GetPos();
        const Vec3&  vEntityDir = pEntity->GetAI()->GetViewDir();
        Vec3  vDiff = vPos - vEntityPos;
        vDiff.NormalizeSafe();
        fResult = acosf(vEntityDir.Dot(vDiff));
    }
    return fResult;
}
Ejemplo n.º 15
0
// Description:
//
// Arguments:
//
// Return:
//
void CPersonalSignalTimer::SetListener(bool bAdd)
{
	IEntity *pEntity = GetEntity();;
	if (pEntity)
	{
		IAIObject *pAIObject = pEntity->GetAI();
		if (pAIObject)
		{
			CAIProxy* pAIProxy = (CAIProxy*)pAIObject->GetProxy();
			if (pAIProxy)
			{
				if (bAdd)
					pAIProxy->AddListener(this);
				else
					pAIProxy->RemoveListener(this);
			}
		}
	}
}
Ejemplo n.º 16
0
uint8 CAutoAimManager::GetLocalPlayerFaction() const
{
	if (m_localPlayerFaction != IFactionMap::InvalidFactionID)
	{
		return m_localPlayerFaction;
	}
	else
	{
		IEntity* pLocalPlayerEntity = gEnv->pEntitySystem->GetEntity(g_pGame->GetIGameFramework()->GetClientActorId());
		if (pLocalPlayerEntity)
		{
			IAIObject* pAIObject = pLocalPlayerEntity->GetAI();
			if (pAIObject)
			{
				m_localPlayerFaction = pAIObject->GetFactionID();
			}
		}
	}

	return m_localPlayerFaction;
}
//////////////////////////////////////////////////////////////////////////
// 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);

}
Ejemplo n.º 18
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);
						}
					}
				}
*/
			}
		}
	}

}
Ejemplo n.º 19
0
bool CDialogActorContext::Update(float dt)
{
	if (IsAborted())
		return true;

	// FIXME: this should never happen, as we should get a notification before.
	//        temp leave in for tracking down a bug [AlexL: 23/11/2006]
	IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_entityID);
	if (pEntity == 0)
	{
		m_pIActor = 0;
		GameWarning("[DIALOG] CDialogActorContext::Update: %s Actor=%d (EntityId=%d) no longer existent.",
			m_pSession->GetDebugName(), m_actorID, m_entityID);
		AbortContext(true, CDialogSession::eAR_EntityDestroyed);
		return true;
	}

	CDialogSession::AlertnessInterruptMode alertnessInterruptMode = m_pSession->GetAlertnessInterruptMode();
	if(alertnessInterruptMode != CDialogSession::None)
	{
		if(IAIObject* aiObject = pEntity->GetAI())
		{
			if(IAIActorProxy* aiActorProxy = aiObject->GetProxy())
			{
				if(aiActorProxy->GetAlertnessState() >= alertnessInterruptMode)
				{
					AbortContext(true, CDialogSession::eAR_AIAborted);
					return true;
				}
			}
		}
	}

	float now = m_pSession->GetCurTime();

	if (!CheckActorFlags(CDialogSession::eDACF_NoActorDeadAbort) && m_pIActor && m_pIActor->IsDead())
	{
		if (!IsAborted())
		{
			DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Actor=%d (EntityId=%d) has died. Aborting.",
				m_pSession->GetDebugName(), m_actorID, m_entityID);
			AbortContext(true, CDialogSession::eAR_ActorDead);
			return true;
		}
	}

	if (m_bIsLocalPlayer)
	{
		// when the local player is involved in the conversation do some special checks
		if (DoLocalPlayerChecks(dt) == false)
		{
			DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Abort from LocalPlayer.", m_pSession->GetDebugName());
			AbortContext(true, m_bIsAwareInRange == false ? CDialogSession::eAR_PlayerOutOfRange : CDialogSession::eAR_PlayerOutOfView);
			return true;
		}
	}

	if (m_bAbortFromAI)
	{
		m_bAbortFromAI = false;
		if (!IsAborted())
		{
			DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Abort from AI.", m_pSession->GetDebugName());
			AbortContext(true, CDialogSession::eAR_AIAborted);
			return true;
		}
	}

	if (SessionAllowsLookAt())
	{
		DoStickyLookAt();
	}

	int loop = 0;
	do 
	{
		// DiaLOG::Log("[DIALOG] DiaLOG::eAlways"CDialogActorContext::Update: %s now=%f actorId=%d loop=%d", m_pSession->GetDebugName(), now, m_actorID, loop);

		bool bAdvance = false;
		switch (m_phase)
		{
		case eDAC_Idle:
			break;

		case eDAC_NewLine:
			{
				m_bHasScheduled = false;
				m_lookAtTimeOut = LOOKAT_TIMEOUT;
				m_animTimeOut   = ANIM_TIMEOUT;
				m_soundTimeOut  = SOUND_TIMEOUT; // wait one second until sound is timed out
				m_bAnimScheduled = false;
				m_bAnimStarted   = false;
				m_bSoundScheduled = false;
				m_bSoundStarted   = false;
				m_soundLength   = 0.0f;

				if (m_pCurLine->m_flagResetLookAt)
				{
					m_stickyLookAtActorID = CDialogScript::NO_ACTOR_ID;
					m_lookAtActorID = CDialogScript::NO_ACTOR_ID;
				}
				// check if look-at sticky is set
				else if (m_pCurLine->m_lookatActor != CDialogScript::NO_ACTOR_ID)
				{
					if (m_pCurLine->m_flagLookAtSticky == false)
					{
						m_lookAtActorID = m_pCurLine->m_lookatActor;
						m_stickyLookAtActorID = CDialogScript::NO_ACTOR_ID;
					}
					else
					{
						m_stickyLookAtActorID = m_pCurLine->m_lookatActor;
						m_lookAtActorID = CDialogScript::NO_ACTOR_ID;
					}
				}

				bAdvance = true;

				// handle the first sticky look-at here
				if (SessionAllowsLookAt())
				{
					DoStickyLookAt();
				}









			}
			break;

		case eDAC_LookAt:
			{
				bool bWaitForLookAtFinish = true;
				bAdvance = true;
	
				if (SessionAllowsLookAt() == false)
				{
					break;
				}

				// Question: maybe do this although EP is requested
				if (bWaitForLookAtFinish && m_lookAtActorID != CDialogScript::NO_ACTOR_ID && m_pCurLine->m_flagAGEP == false) 
				{
					IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID);
					IEntity* pLookAtEntity = m_pSession->GetActorEntity(m_lookAtActorID);
					if (pActorEntity != 0)
					{
						m_lookAtTimeOut -= dt;
						bool bTargetReached;
						//bool bSuccess = DoLookAt(pActorEntity, pLookAtEntity, bTargetReached);
						DoLookAt(pActorEntity, pLookAtEntity, bTargetReached);
						//DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_LookAt %d",
						//	m_pSession->GetDebugName(), now, m_actorID, bTargetReached);

						if (/* bSuccess == false || */ bTargetReached || m_lookAtTimeOut<=0.0f)
						{
							DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_LookAt %s",
								m_pSession->GetDebugName(), now, m_actorID, bTargetReached ? "Target Reached" : "Timed Out");
							m_lookAtActorID = CDialogScript::NO_ACTOR_ID;
						}
						else
							bAdvance = false;
					}
				}
			}
			break;

		case eDAC_Anim:
			{
				bAdvance = true;
				if (SessionAllowsLookAt() && m_lookAtActorID != CDialogScript::NO_ACTOR_ID) // maybe: don't do this when EP is requested [&& m_pCurLine->m_flagAGEP == false]
				{
					IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID);
					IEntity* pLookAtEntity = m_pSession->GetActorEntity(m_lookAtActorID);
					if (pActorEntity != 0)
					{
						m_lookAtTimeOut -= dt;
						bool bTargetReached;
						//bool bSuccess = DoLookAt(pActorEntity, pLookAtEntity, bTargetReached);
						DoLookAt(pActorEntity, pLookAtEntity, bTargetReached);
						if (/* bSuccess == false || */ bTargetReached || m_lookAtTimeOut<=0.0f)
						{
							DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s now=%f actorID=%d phase=eDAC_Anim %s",
								m_pSession->GetDebugName(), now, m_actorID, bTargetReached ? "Target Reached" : "Timed Out");
							m_lookAtActorID = CDialogScript::NO_ACTOR_ID;
						}
						else
							bAdvance = false;
					}
				}
				const bool bHasAnim = !m_pCurLine->m_anim.empty();
				if (SessionAllowsAnim() && bHasAnim)
				{
					bAdvance = false;
					if (!m_bAnimScheduled)
					{
						m_bSoundStopsAnim = false; // whenever there is a new animation, no need for the still playing sound
						                           // to stop the animation
						m_bAnimStarted = false;
						m_bAnimScheduled = true;
						// schedule animation
						IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID);
						if (pActorEntity)
							DoAnimAction(pActorEntity, m_pCurLine->m_anim, m_pCurLine->m_flagAGSignal, m_pCurLine->m_flagAGEP);
						else
							bAdvance = true;
					}
					else
					{
						// we scheduled it already
						// wait until it starts or timeout
						m_animTimeOut-=dt;
						bAdvance = m_animTimeOut <= 0.0f || m_bAnimStarted;
						if (bAdvance)
						{
							DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_Anim %s",
								m_pSession->GetDebugName(), now, m_actorID, m_bAnimStarted ? "Anim Started" : "Anim Timed Out");
						}
					}
				}
			}
			break;

		case eDAC_ScheduleSoundPlay:
			{
				bAdvance = true;
				const bool bHasSound  = !m_pCurLine->m_sound.empty();
				if (bHasSound)
				{
					if (m_bSoundScheduled == false)
					{
						IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID);
						if (pActorEntity == 0)
							break;

						IEntityAudioProxy* pActorAudioProxy = m_pSession->GetEntityAudioProxy(pActorEntity);
						if (pActorAudioProxy == 0)
							break;

						REINST("play voice line");
						// start a new sound
						//int sFlags = CDialogActorContext::SOUND_FLAGS;
						//if (CDialogSystem::sLoadSoundSynchronously != 0)
						//	sFlags |= FLAG_SOUND_LOAD_SYNCHRONOUSLY;
						//
						//// if it's the local player make the sound relative to the entity
						//if (m_bIsLocalPlayer)
						//	sFlags |= FLAG_SOUND_RELATIVE;

						//const char* soundKey = GetSoundKey(m_pCurLine->m_sound);
						//ISound* pSound = 0;

						//pSound = gEnv->pAudioSystem->CreateSound(soundKey, sFlags);

						//DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContex::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay: Starting '%s' [key=%s]",
						//	m_pSession->GetDebugName(), now, m_actorID, m_pCurLine->m_sound.c_str(), soundKey);

						//if (!pSound) 
						//{
						//	GameWarning("[DIALOG] CDialogActorContext::Update: %s ActorID=%d: Cannot play sound '%s'",
						//		m_pSession->GetDebugName(), m_actorID, m_pCurLine->m_sound.c_str());
						//}

						//if (pSound)
						//{
						//	if (m_bSoundStopsAnim)
						//	{
						//		m_bSoundStopsAnim = false;
						//		if (m_pAGState != 0)
						//		{
						//			ResetAGState();
						//			DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay: Stopping old animation",
						//				m_pSession->GetDebugName(), now, m_actorID);
						//		}
						//	}
						//	StopSound(); // apparently, if we dont explicitely stop the sound, in rare cases it never stops. Im pretty sure that is an engine/fmod bug.
						//	             // stopping it this way may lead to some subtitles staying for an extra couple seconds on screen (this comes from another engine bug/problem related to an extra fade out time added to cover the dummy NAX soudns) 
						//	m_soundID = pSound->GetId();
						//	m_bSoundStarted = false;
						//	m_bSoundScheduled = true;
						//	// tell the animation whether to stop on sound stop
						//	m_bSoundStopsAnim = m_pCurLine->m_flagSoundStopsAnim;

						//	DiaLOG::Log(DiaLOG::eDebugA, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay: Reg as listener on 0x%p '%s'",
						//		m_pSession->GetDebugName(), now, m_actorID, pSound, pSound->GetName());

						//	pSound->SetSemantic(eSoundSemantic_Dialog);
						//	pSound->AddEventListener(this, "DialogActor"); // event listener will set m_soundLength
						//	// sound proxy uses head pos on dialog sounds
						//	const bool bResult = pActorAudioProxy->PlaySound(pSound, Vec3(ZERO), FORWARD_DIRECTION, 1.0f);

						//	if (bResult)
						//	{
						//		// Fetch some localization info for the sound
						//		ILocalizationManager* pLocMgr = gEnv->pSystem->GetLocalizationManager();
						//		if (pLocMgr && CDialogSystem::sWarnOnMissingLoc != 0)
						//		{
						//			SLocalizedInfoGame GameInfo;

						//			const bool bFound = pLocMgr->GetLocalizedInfoByKey(soundKey, GameInfo);
						//			if (!bFound)
						//			{
						//				GameWarning("[DIALOG] CDialogActorContext::Update: '%s' DialogScript '%s': Localized info for '%s' not found!", 
						//					m_pSession->GetDebugName(), m_pSession->GetScript()->GetID().c_str(), m_pCurLine->m_sound.c_str());
						//			}
						//		}

						//		bAdvance = false; // don't advance
						//	}
						//	else
						//	{
						//		GameWarning("[DIALOG] CDialogActorContext::Update: %s ActorID=%d: Cannot play sound '%s' [AudioProxy ignored playback]",
						//			m_pSession->GetDebugName(), m_actorID, m_pCurLine->m_sound.c_str());

						//		pSound->Stop(ESoundStopMode_AtOnce);
						//		m_soundID = INVALID_SOUNDID;
						//		pSound->RemoveEventListener(this);
						//		pSound = NULL;
						//	}
						//}
						//else
						//{
						//	GameWarning("[DIALOG] CDialogActorContext::Update: %s ActorID=%d: Cannot play sound '%s' [AudioProxy returns invalid sound]",
						//		m_pSession->GetDebugName(), m_actorID, m_pCurLine->m_sound.c_str());
						//}
					}
					else
					{
						// sound has been scheduled
						// wait for sound start or timeout
						m_soundTimeOut-=dt;
						const bool bTimedOut = m_soundTimeOut <= 0.0f;
						bAdvance = bTimedOut || m_bSoundStarted;
						if (bAdvance)
						{
							if (bTimedOut)
								StopSound(true); // unregister from sound as listener and free resource
							DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_ScheduleSoundPlay %s",
								m_pSession->GetDebugName(), now, m_actorID, m_bSoundStarted ? "Sound Started" : "Sound Timed Out");
						}
					}
				}
			}
			break;

		case eDAC_SoundFacial:
			{
				bAdvance = true;
				const bool bHasSound  = !m_pCurLine->m_sound.empty();
				const bool bHasFacial = !m_pCurLine->m_facial.empty() || m_pCurLine->m_flagResetFacial;
				if (bHasFacial)
				{
					IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID);
					if (pActorEntity)
						DoFacialExpression(pActorEntity, m_pCurLine->m_facial, m_pCurLine->m_facialWeight, m_pCurLine->m_facialFadeTime);
				}

				float delay = m_pCurLine->m_delay;
				if (bHasSound && m_bSoundStarted)
				{
					if (m_soundLength < 0.0f)
					{
						m_soundLength = Random(2.0f,6.0f);
						DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_SoundFacial Faking SoundTime to %f",
							m_pSession->GetDebugName(), now, m_actorID, m_soundLength);
					}

					DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Now=%f actorID=%d phase=eDAC_SoundFacial Delay=%f SoundTime=%f",
						m_pSession->GetDebugName(), now , m_actorID, delay, m_soundLength);
					delay += m_soundLength;
				}

				// schedule END
				if (delay < 0.0f)
					delay = 0.0f;
				m_pSession->ScheduleNextLine(delay+0.05f); // ~1 frame at 20 fps. we now stop the current line sound before going for next line. Sometimes, this stop call is right before the
																									 // sound has actually stopped in engine side. When that happens, the engine is adding ~2 seconds extra to the sound duration (because fade problems related to NAX header)
																									 // and that looks bad if subtitles are enabled. So we add this small delay here to try to minimize that situation.
																									 // this is part of the workaround for some dialogs apparently never finishing in the engine side (rare).
				m_bHasScheduled = true;
			}
			break;

		case eDAC_EndLine:
			bAdvance = true;
			if (m_bHasScheduled == false)
			{
				m_bHasScheduled = true;
				m_pSession->ScheduleNextLine(m_pCurLine->m_delay);
			}
			break;
		}

		if (bAdvance)
		{
			AdvancePhase();
			dt = 0.0f;
			++loop;
			assert (loop <= eDAC_EndLine+1);
			if (loop > eDAC_EndLine+1)
			{
				DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::Update: %s Actor=%d InternalLoopCount=%d. Final Exit!",
					m_pSession->GetDebugName(), m_actorID, loop);
			}
		}
		else
			break;
	}
	while (true);

	return true;
}
Ejemplo n.º 20
0
void CDialogActorContext::CancelCurrent(bool bResetStates)
{
	if (!m_bNeedsCancel)
		return;

	assert (m_bInCancel == false);
	if (m_bInCancel == true)
		return;
	m_bInCancel = true;

	// remove from AG
	if (m_pAGState != 0)
	{
		m_pAGState->RemoveListener(this);
		if (bResetStates)
		{
			ResetAGState();
		}
		m_pAGState = 0;
	}
	m_queryID = 0;
	m_bAnimStarted = false;

	// reset lookat
	IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_entityID);
	if (pEntity)
	{
		IAIObject* pAI = pEntity->GetAI();
		if (pAI)
		{
			IAIActor* pAIActor = pAI->CastToIAIActor();
			if (pAIActor)
			{
				if (m_bLookAtNeedsReset)
				{
					pAIActor->ResetLookAt();
					m_bLookAtNeedsReset = false;
				}
			
				IPipeUser* pPipeUser = pAI->CastToIPipeUser();
				if (pPipeUser)
				{
					if (m_goalPipeID > 0)
					{
						if (GetAIBehaviourMode() == CDialogSession::eDIB_InterruptMedium)
						{
							int dummyPipe = 0;
							ExecuteAI(dummyPipe, "ACT_DIALOG_OVER", 0, false);
						}
						pPipeUser->UnRegisterGoalPipeListener( this, m_goalPipeID );
						pPipeUser->RemoveSubPipe(m_goalPipeID, true);
						m_goalPipeID = 0;
					}
					if (m_exPosAnimPipeID > 0)
					{
						pPipeUser->UnRegisterGoalPipeListener( this, m_exPosAnimPipeID );
						pPipeUser->CancelSubPipe(m_exPosAnimPipeID);
						pPipeUser->RemoveSubPipe(m_exPosAnimPipeID, false);
						m_exPosAnimPipeID = 0;
					}
				}
			}
		}
	}

	// facial expression is always reset
	// if (bResetStates)
	{
		// Reset Facial Expression
		IEntity* pActorEntity = m_pSession->GetActorEntity(m_actorID);
		if (pActorEntity)
		{
			DoFacialExpression(pActorEntity, "", 1.0f, 0.0f);
		}
	}

	// should we stop the current sound?
	// we don't stop the sound if the actor aborts and has eDACF_NoAbortSound set.
	// if actor died (entity destroyed) though, sound is stopped anyway
	const bool bDontStopSound = (IsAborted() == false && CheckActorFlags(CDialogSession::eDACF_NoAbortSound))
		|| (IsAborted() 
		&& CheckActorFlags(CDialogSession::eDACF_NoAbortSound)
		&& GetAbortReason() != CDialogSession::eAR_ActorDead
		&& GetAbortReason() != CDialogSession::eAR_EntityDestroyed);

	if (bDontStopSound == false)
	{
		// stop sound (this also forces m_soundId to be INVALID_SOUNDID) and markes Context as non-playing!
		// e.g. IsStillPlaying will then return false
		// we explicitly stop the sound in the d'tor if we don't take this path here
		StopSound(); 
	}

	IEntitySystem* pES = gEnv->pEntitySystem;
	pES->RemoveEntityEventListener( m_entityID, ENTITY_EVENT_AI_DONE, this );
	pES->RemoveEntityEventListener( m_entityID, ENTITY_EVENT_DONE, this );
	pES->RemoveEntityEventListener( m_entityID, ENTITY_EVENT_RESET, this );

	m_phase = eDAC_Idle;

	m_bInCancel = false;
	m_bNeedsCancel = false;
}
Ejemplo n.º 21
0
//------------------------------------------------------------------------
void CGameRules::ClientExplosion(const ExplosionInfo &explosionInfo)
{
	// let 3D engine know about explosion (will create holes and remove vegetation)
	//if (explosionInfo.hole_size > 0.0f)
	//{
		//gEnv->p3DEngine->OnExplosion(explosionInfo.pos, explosionInfo.hole_size, true);
	//}

	TExplosionAffectedEntities affectedEntities;

	if (gEnv->bServer)
  {
		CullEntitiesInExplosion(explosionInfo);
		pe_explosion explosion;
		explosion.epicenter = explosionInfo.pos;
		explosion.rmin = explosionInfo.minRadius;
		explosion.rmax = explosionInfo.radius;
		if (explosion.rmax==0)
			explosion.rmax=0.0001f;
		explosion.r = explosion.rmin;
		explosion.impulsivePressureAtR = explosionInfo.pressure;
		explosion.epicenterImp = explosionInfo.pos;
		explosion.explDir = explosionInfo.dir;
		explosion.nGrow = 2;
		explosion.rminOcc = 0.07f;

		// we separate the calls to SimulateExplosion so that we can define different radii for AI and physics bodies
		explosion.holeSize = 0.0f;
		explosion.nOccRes = explosion.rmax>50.0f ? 0:32;
		gEnv->pPhysicalWorld->SimulateExplosion( &explosion, 0, 0, ent_living);

		CreateScriptExplosionInfo(m_scriptExplosionInfo, explosionInfo);
		UpdateAffectedEntitiesSet(affectedEntities, &explosion);

		// check vehicles
		IVehicleSystem *pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem();
		uint32 vcount = pVehicleSystem->GetVehicleCount();
		if (vcount > 0)
		{
			IVehicleIteratorPtr iter = g_pGame->GetIGameFramework()->GetIVehicleSystem()->CreateVehicleIterator();
			while (IVehicle* pVehicle = iter->Next())
			{
				if(IEntity *pEntity = pVehicle->GetEntity())
				{
					AABB aabb;
					pEntity->GetWorldBounds(aabb);
					IPhysicalEntity* pEnt = pEntity->GetPhysics();
					if (pEnt && aabb.GetDistanceSqr(explosionInfo.pos) <= explosionInfo.radius*explosionInfo.radius)
					{
						float affected = gEnv->pPhysicalWorld->CalculateExplosionExposure(&explosion, pEnt);
						AddOrUpdateAffectedEntity(affectedEntities, pEntity, affected);
					}
				}
			}
		}

		explosion.rmin = explosionInfo.minPhysRadius;
		explosion.rmax = explosionInfo.physRadius;
		if (explosion.rmax==0)
			explosion.rmax=0.0001f;
		explosion.r = explosion.rmin;
		explosion.holeSize = explosionInfo.hole_size;
		explosion.nOccRes = -1;	// makes second call re-use occlusion info
		gEnv->pPhysicalWorld->SimulateExplosion( &explosion, 0, 0, ent_rigid|ent_sleeping_rigid|ent_independent|ent_static );

		UpdateAffectedEntitiesSet(affectedEntities, &explosion);
		CommitAffectedEntitiesSet(m_scriptExplosionInfo, affectedEntities);

		float fSuitEnergyBeforeExplosion = 0.0f;
		float fHealthBeforeExplosion = 0.0f;
		IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();
		if(pClientActor)
		{
			fSuitEnergyBeforeExplosion = static_cast<CPlayer *>(pClientActor)->GetNanoSuit()->GetSuitEnergy();
			fHealthBeforeExplosion = pClientActor->GetHealth();
		}

		CallScript(m_serverStateScript, "OnExplosion", m_scriptExplosionInfo);    

		if(pClientActor)
		{
			float fDeltaSuitEnergy = fSuitEnergyBeforeExplosion - static_cast<CPlayer *>(pClientActor)->GetNanoSuit()->GetSuitEnergy();
			float fDeltaHealth = fHealthBeforeExplosion - pClientActor->GetHealth();

			if(fDeltaSuitEnergy >= 50.0f || fDeltaHealth >= 20.0f)
			{
				SAFE_SOUNDMOODS_FUNC(AddSoundMood(SOUNDMOOD_EXPLOSION,MIN(fDeltaSuitEnergy+fDeltaHealth,100.0f)));
			}
		}

		// call hit listeners if any
		if (m_hitListeners.empty() == false)
		{
			THitListenerVec::iterator iter = m_hitListeners.begin();
			while (iter != m_hitListeners.end())
			{
				(*iter)->OnServerExplosion(explosionInfo);
				++iter;
			}
		}
  }

	if (gEnv->bClient)
	{
		if (explosionInfo.pParticleEffect)
			explosionInfo.pParticleEffect->Spawn(true, IParticleEffect::ParticleLoc(explosionInfo.pos, explosionInfo.dir, explosionInfo.effect_scale));

		if (!gEnv->bServer)
		{
			CreateScriptExplosionInfo(m_scriptExplosionInfo, explosionInfo);
		}
		else
		{
			affectedEntities.clear();
			CommitAffectedEntitiesSet(m_scriptExplosionInfo, affectedEntities);
		}
		CallScript(m_clientStateScript, "OnExplosion", m_scriptExplosionInfo);

		// call hit listeners if any
		if (m_hitListeners.empty() == false)
		{
			THitListenerVec::iterator iter = m_hitListeners.begin();
			while (iter != m_hitListeners.end())
			{
				(*iter)->OnExplosion(explosionInfo);
				++iter;
			}
		}
	}

	ProcessClientExplosionScreenFX(explosionInfo);
	ProcessExplosionMaterialFX(explosionInfo);

	IEntity *pShooter =	m_pEntitySystem->GetEntity(explosionInfo.shooterId);
	if (gEnv->pAISystem && !gEnv->bMultiplayer)
	{
		IAIObject	*pShooterAI(pShooter!=NULL ? pShooter->GetAI() : NULL);
		gEnv->pAISystem->ExplosionEvent(explosionInfo.pos,explosionInfo.radius, pShooterAI);
	}

}
Ejemplo n.º 22
0
void CTacBullet::HandleEvent(const SGameObjectEvent &event)
{
	if (m_destroying)
		return;

	CProjectile::HandleEvent(event);

	if (event.event == eGFE_OnCollision)
	{
		EventPhysCollision *pCollision = reinterpret_cast<EventPhysCollision *>(event.ptr);
		if (!pCollision)
			return;

		IEntity *pTarget = pCollision->iForeignData[1]==PHYS_FOREIGN_ID_ENTITY ? (IEntity*)pCollision->pForeignData[1]:0;
		if (pTarget)
		{
			CGameRules *pGameRules = g_pGame->GetGameRules();

			EntityId targetId = pTarget->GetId();
			CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(targetId);
			
			if(pActor && pActor->CanSleep())
			{
				if(pActor->GetLinkedVehicle() && !gEnv->bMultiplayer)
				{
					SleepTargetInVehicle(m_ownerId,pActor);
				}
				else if(IEntity* pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId))
				{
					if (pTarget->GetAI() && !pTarget->GetAI()->IsFriendly(pOwnerEntity->GetAI(), false))
					{
						float sleepTime = 30.0f;
						if(m_pAmmoParams)
							sleepTime = m_pAmmoParams->sleepTime;
						SimpleHitInfo info(m_ownerId, targetId, m_weaponId, 1, sleepTime); // 0=tag,1=tac
						info.remote=IsRemote();

						pGameRules->ClientSimpleHit(info);
					}
				}
			}
			else
			{
				Vec3 dir(0, 0, 0);
				if (pCollision->vloc[0].GetLengthSquared() > 1e-6f)
					dir = pCollision->vloc[0].GetNormalized();

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

		}
		else 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);

			if (pierceabilityMat>params.iPierceability && pCollision->idCollider!=-1) 
				return;
		}

		Destroy();
	}
}
Ejemplo n.º 23
0
//---------------------------------------------------------------------------
void CVehicleWeapon::CheckForFriendlyAI(float frameTime)
{
	if (m_pVehicle)
	{
		if (CActor* pOwnerActor = GetOwnerActor())
		{
			if (pOwnerActor->IsPlayer() && !gEnv->bMultiplayer)
			{
				m_timeToUpdate -= frameTime;
				if (m_timeToUpdate > 0.f)
					return;

				m_timeToUpdate = 0.15f;

				if (IMovementController* pMC = pOwnerActor->GetMovementController())
				{
					SMovementState info;
					pMC->GetMovementState(info);

					LowerWeapon(false);

					// Try ray hit
					ray_hit rayhit;
					IPhysicalEntity* pSkipEnts[10];
					int nSkip = CSingle::GetSkipEntities(this, pSkipEnts, 10);	

					int intersect = gEnv->pPhysicalWorld->RayWorldIntersection(info.weaponPosition, info.aimDirection * 150.f, ent_all,
						rwi_stop_at_pierceable | rwi_colltype_any, &rayhit, 1, pSkipEnts, nSkip);

					if (intersect && rayhit.pCollider)
					{
						if (IEntity* pLookAtEntity = m_pEntitySystem->GetEntityFromPhysics(rayhit.pCollider))
						{
							if (EntityId lookAtEntityId = pLookAtEntity->GetId())
							{
								IAIObject* pLookAtAIObject = pLookAtEntity->GetAI();
								IEntity* pOwnerEntity = pOwnerActor->GetEntity();

								if (pOwnerEntity && pLookAtAIObject && (lookAtEntityId != GetEntityId()))
								{
									if (IVehicle* pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(lookAtEntityId))
									{
										if (pVehicle->HasFriendlyPassenger(pOwnerEntity))
										{
											LowerWeapon(true);
											StopFire();	// Just in case
										}
									}
									else 
									{
										if (pLookAtAIObject->IsFriendly(pOwnerEntity->GetAI(), false))
										{
											LowerWeapon(true);
											StopFire();	// Just in case
										}
									}
								}
								else
								{
									// Special case (Animated objects), check for script table value "bNoFriendlyFire"
									if (IScriptTable* pScriptTable = pLookAtEntity->GetScriptTable())
									{
										SmartScriptTable props;
										if (pScriptTable->GetValue("Properties", props))
										{
											int isFriendly;
											if (props->GetValue("bNoFriendlyFire", isFriendly) && (isFriendly != 0))
											{
												LowerWeapon(true);
												StopFire();	// Just in case
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
Ejemplo n.º 24
0
//------------------------------------------------------------------------
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();
		}
	}
}
void CVisibleObjectsHelper::CheckVisibilityToAI(const TActiveVisibleObjects &activeVisibleObjects, const Agent& agent) const
{
	assert(agent.IsValid());

	IScriptSystem *pSS = gEnv->pScriptSystem;
	assert(pSS);

	IEntity *pAIEntity = gEnv->pEntitySystem->GetEntity(agent.GetEntityID());

	TActiveVisibleObjects::const_iterator itObject = activeVisibleObjects.begin();
	TActiveVisibleObjects::const_iterator itObjectEnd = activeVisibleObjects.end();
	for (; itObject != itObjectEnd; ++itObject)
	{
		const SVisibleObject *visibleObject = (*itObject);
		assert(visibleObject);

		const bool bVisible = IsObjectVisible(agent, *visibleObject);
		if (bVisible)
		{
			// Callback function
			if (visibleObject->pFunc)
			{
				visibleObject->pFunc(agent, visibleObject->entityId, visibleObject->pFuncArg);
			}

			// Notify on seen
			if (pAIEntity != NULL && eVOR_FlagNotifyOnSeen == (visibleObject->rule & eVOR_FlagNotifyOnSeen))
			{
				IVisionMap& visionMap = *gEnv->pAISystem->GetVisionMap();
				const ObservableParams* pObservableParams = visionMap.GetObservableParams(visibleObject->visionId);

				if (pObservableParams != NULL)
				{
					IEntity* pTargetEntity = gEnv->pEntitySystem->GetEntity(pObservableParams->entityId);
					ITargetTrackManager *pTargetTrackManager = gEnv->pAISystem->GetTargetTrackManager();
					if (pTargetEntity != NULL && pTargetTrackManager != NULL)
					{
						const tAIObjectID aiOwnerId = pAIEntity->GetAIObjectID();
						const tAIObjectID aiTargetId = pTargetEntity->GetAIObjectID();

						TargetTrackHelpers::SStimulusEvent eventInfo;
						eventInfo.vPos = pTargetEntity->GetWorldPos();
						eventInfo.eStimulusType = TargetTrackHelpers::eEST_Visual;
						eventInfo.eTargetThreat = AITHREAT_INTERESTING;
						pTargetTrackManager->HandleStimulusEventForAgent(aiOwnerId, aiTargetId, "SeeThrownObject", eventInfo);

						IAIObject* pAIObjectSender = pAIEntity->GetAI();
						if (pAIObjectSender)
						{
							IAISignalExtraData *pSignalData = gEnv->pAISystem->CreateSignalExtraData();
							if (pSignalData)
							{
								pSignalData->nID = visibleObject->entityId;
							}
							gEnv->pAISystem->SendSignal(SIGNALFILTER_SENDER, 1, "OnSawObjectMove", pAIObjectSender, pSignalData);
						}
					}
				}
			}
		}
	}
}
Ejemplo n.º 26
0
//------------------------------------------------------------------------
void CMelee::Hit(const Vec3 &pt, const Vec3 &dir, const Vec3 &normal, IPhysicalEntity *pCollider, int partId, int ipart, int surfaceIdx, float damageScale, bool remote)
{
	// generate the damage
	IEntity *pTarget = gEnv->pEntitySystem->GetEntityFromPhysics(pCollider);
	// Report punch to AI system.
	// The AI notification must come before the game rules are
	// called so that the death handler in AIsystem understands that the hit
	// came from the player.
	bool ok = true;

	if(pTarget)
	{
		CActor *pActor = m_pWeapon->GetOwnerActor();

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

		if(ok)
		{
			CGameRules *pGameRules = g_pGame->GetGameRules();
			HitInfo info(m_pWeapon->GetOwnerId(), pTarget->GetId(), m_pWeapon->GetEntityId(),
						 m_pShared->meleeparams.damage * damageScale * m_meleeScale, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(surfaceIdx), partId,
						 pGameRules->GetHitTypeId(m_pShared->meleeparams.hit_type.c_str()), pt, dir, normal);
			info.remote = remote;
			pGameRules->ClientHit(info);
		}
	}

	// play effects
	if(ok)
	{
		if(IMaterialEffects *pMaterialEffects = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects())
		{
			TMFXEffectId effectId = pMaterialEffects->GetEffectId("melee", surfaceIdx);

			if (effectId != InvalidEffectId)
			{
				SMFXRunTimeEffectParams params;
				params.pos = pt;
				params.normal = -dir;
				params.playflags = MFX_PLAY_ALL | MFX_DISABLE_DELAY;
				params.soundSemantic = eSoundSemantic_Player_Foley;
				pMaterialEffects->ExecuteEffect(effectId, params);
			}
		}
	}

	ApplyCameraShake(true);
	m_pWeapon->PlayAction(m_pShared->meleeactions.hit.c_str());
}
Ejemplo n.º 27
0
uint8 CAutoAimManager::GetTargetFaction( IEntity& targetEntity ) const
{
	IAIObject* pAIObject = targetEntity.GetAI();
	return pAIObject ? pAIObject->GetFactionID() : IFactionMap::InvalidFactionID;
}
Ejemplo n.º 28
0
//------------------------------------------------------------------------
void CMelee::Hit(const Vec3 &pt, const Vec3 &dir, const Vec3 &normal, IPhysicalEntity *pCollider, int partId, int ipart, int surfaceIdx, float damageScale, bool remote)
{
	// generate the damage
	IEntity *pTarget = gEnv->pEntitySystem->GetEntityFromPhysics(pCollider);

	// Report punch to AI system.
	// The AI notification must come before the game rules are 
	// called so that the death handler in AIsystem understands that the hit
	// came from the player.
	CActor *pActor = m_pWeapon->GetOwnerActor();
	if (pActor && pActor->GetActorClass() == CPlayer::GetActorClassType())
	{
		CPlayer *pPlayer = (CPlayer *)pActor;
		if (pPlayer && pPlayer->GetNanoSuit())
		{
			if (pPlayer->GetEntity() && pPlayer->GetEntity()->GetAI())
			{
				SAIEVENT AIevent;
				AIevent.targetId = pTarget ? pTarget->GetId() : 0;
				// pPlayer->GetNanoSuit()->GetMode() == NANOMODE_STRENGTH
				pPlayer->GetEntity()->GetAI()->Event(AIEVENT_PLAYER_STUNT_PUNCH, &AIevent);
			}
		}
	}

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

		if(ok)
		{
			CGameRules *pGameRules = g_pGame->GetGameRules();

			HitInfo info(m_pWeapon->GetOwnerId(), pTarget->GetId(), m_pWeapon->GetEntityId(),
				m_meleeparams.damage*damageScale*m_meleeScale, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(surfaceIdx), partId,
				pGameRules->GetHitTypeId(m_meleeparams.hit_type.c_str()), pt, dir, normal);

			info.remote = remote;

			if (m_pWeapon->GetForcedHitMaterial() != -1)
				info.material=pGameRules->GetHitMaterialIdFromSurfaceId(m_pWeapon->GetForcedHitMaterial());

			pGameRules->ClientHit(info);
		}
	}

	// play effects
	if(ok)
	{
		IMaterialEffects* pMaterialEffects = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects();

		TMFXEffectId effectId = pMaterialEffects->GetEffectId("melee", surfaceIdx);
		if (effectId != InvalidEffectId)
		{
			SMFXRunTimeEffectParams params;
			params.pos = pt;
			params.playflags = MFX_PLAY_ALL | MFX_DISABLE_DELAY;
			params.soundSemantic = eSoundSemantic_Player_Foley;
			pMaterialEffects->ExecuteEffect(effectId, params);
		}
	}

	ApplyCameraShake(true);

	m_pWeapon->PlayAction(m_meleeactions.hit.c_str());
}
Ejemplo n.º 29
0
//
//-----------------------------------------------------------------------------------------------------------
// (MATT) Moved here from Scriptbind_AI when that was moved to the AI system {2008/02/15:15:23:16}
int CScriptBind_Action::RegisterWithAI(IFunctionHandler *pH)
{
	if (gEnv->bMultiplayer && !gEnv->bServer)
		return pH->EndFunction();

	int type;
	ScriptHandle hdl;

	if (!pH->GetParams(hdl, type))
		return pH->EndFunction();

	EntityId entityID = (EntityId)hdl.n;
	IEntity *pEntity = gEnv->pEntitySystem->GetEntity(entityID);

	if(!pEntity)
	{
		GameWarning("RegisterWithAI: Tried to set register with AI nonExisting entity with id [%d]. ", entityID);
		return pH->EndFunction();
	}

	// Apparently we can't assume that there is just one IGameObject to an entity, because we choose between (at least) Actor and Vehicle objects.
	// (MATT) Do we really need to check on the actor system here? {2008/02/15:18:38:34}
	IGameFramework *pGameFramework = gEnv->pGame->GetIGameFramework();
	IVehicleSystem*	pVSystem = pGameFramework->GetIVehicleSystem();
	IActorSystem*	pASystem = pGameFramework->GetIActorSystem();
	if(!pASystem)
	{
		GameWarning("RegisterWithAI: no ActorSystem for %s.", pEntity->GetName());
		return pH->EndFunction();
	}

	AIObjectParams params(type, 0, entityID);
	bool autoDisable(true);

	// For most types, we need to parse the tables
	// For others we leave them blank
	switch (type)
	{
	case AIOBJECT_ACTOR:
	case AIOBJECT_2D_FLY:
	case AIOBJECT_BOAT:
	case AIOBJECT_CAR:
	case AIOBJECT_HELICOPTER:
	
	case AIOBJECT_INFECTED:
	case AIOBJECT_ALIENTICK:
	
	case AIOBJECT_HELICOPTERCRYSIS2:
		if(gEnv->pAISystem && ! gEnv->pAISystem->ParseTables(3, true, pH, params, autoDisable))
			return pH->EndFunction();
	default:;
	}

	// Most types check these, so just get them in advance
	IActor*	pActor = pASystem->GetActor( pEntity->GetId() );

	IVehicle*	pVehicle = NULL;
	if( pVSystem )
		pVehicle = pVSystem->GetVehicle( pEntity->GetId() );

	// Set this if we've found something to create a proxy from
	IGameObject* pGameObject = NULL;

	switch(type)
	{
	case AIOBJECT_ACTOR:
	case AIOBJECT_2D_FLY:
	
	case AIOBJECT_INFECTED:
	case AIOBJECT_ALIENTICK:
	
		{
			// (MATT) The pActor/pVehicle test below - is it basically trying to distiguish between the two cases above? If so, separate them! {2008/02/15:19:38:08}
			if(!pActor)
			{
				GameWarning("RegisterWithAI: no Actor for %s.", pEntity->GetName());
				return pH->EndFunction(); 
			}
			pGameObject = pActor->GetGameObject();
		}
		break;
	case AIOBJECT_BOAT:
	case AIOBJECT_CAR:
		{
			if(!pVehicle)
			{
				GameWarning("RegisterWithAI: no Vehicle for %s (Id %i).", pEntity->GetName(), pEntity->GetId());
				return pH->EndFunction(); 
			}
			pGameObject = pVehicle->GetGameObject();
		}
		break;

	case AIOBJECT_HELICOPTER:
	case AIOBJECT_HELICOPTERCRYSIS2:
		{
			if(!pVehicle)
			{
				GameWarning("RegisterWithAI: no Vehicle for %s (Id %i).", pEntity->GetName(), pEntity->GetId());
				return pH->EndFunction(); 
			}
			pGameObject = pVehicle->GetGameObject();
			params.m_moveAbility.b3DMove = true;
		}
		break;
	case AIOBJECT_PLAYER:
		{
			if(IsDemoPlayback())
				return pH->EndFunction();

			SmartScriptTable pTable;

			if (pH->GetParamCount() > 2)
				pH->GetParam(3,pTable);
			else
				return pH->EndFunction();

			pGameObject = pActor->GetGameObject();

			pTable->GetValue("groupid",params.m_sParamStruct.m_nGroup);       

			const char* faction = 0;
			if (pTable->GetValue("esFaction", faction) && gEnv->pAISystem)
			{
				params.m_sParamStruct.factionID = gEnv->pAISystem->GetFactionMap().GetFactionID(faction);
				if (faction && *faction && (params.m_sParamStruct.factionID == IFactionMap::InvalidFactionID))
				{
					GameWarning("Unknown faction '%s' being set...", faction);
				}
			}
			else
			{
				// Márcio: backwards compatibility
				int species = -1;
				if (!pTable->GetValue("eiSpecies", species))
					pTable->GetValue("species", species);

				if (species > -1)
					params.m_sParamStruct.factionID = species;
			}

			pTable->GetValue("commrange",params.m_sParamStruct.m_fCommRange); //Luciano - added to use GROUPONLY signals

			SmartScriptTable pPerceptionTable;
			if(pTable->GetValue("Perception",pPerceptionTable))
			{
				pPerceptionTable->GetValue( "sightrange", params.m_sParamStruct.m_PerceptionParams.sightRange);
			}
		}
		break;
	case AIOBJECT_SNDSUPRESSOR:
		{
			// (MATT) This doesn't need a proxy? {2008/02/15:19:45:58}
			SmartScriptTable pTable;
			// Properties table
			if (pH->GetParamCount() > 2)
				pH->GetParam(3,pTable);
			else
				return pH->EndFunction();
			if (!pTable->GetValue("radius",params.m_moveAbility.pathRadius))
				params.m_moveAbility.pathRadius = 10.f;
			break;
		}
	case AIOBJECT_WAYPOINT:
		break;
		/*
		// this block is commented out since params.m_sParamStruct is currently ignored in pEntity->RegisterInAISystem()
		// instead of setting the group id here, it will be set from the script right after registering
		default:
		// try to get groupid settings for anchors
		params.m_sParamStruct.m_nGroup = -1;
		params.m_sParamStruct.m_nSpecies = -1;
		{
		SmartScriptTable pTable;
		if ( pH->GetParamCount() > 2 )
		pH->GetParam( 3, pTable );
		if ( *pTable )
		pTable->GetValue( "groupid", params.m_sParamStruct.m_nGroup );
		}
		break;
		*/
	}

	// Remove any existing AI object
	pEntity->RegisterInAISystem(AIObjectParams(0));
 
	// Register in AI to get a new AI object, deregistering the old one in the process
	pEntity->RegisterInAISystem(params);

	// (MATT) ? {2008/02/15:19:46:29}
	// AI object was not created (possibly AI System is disabled)
	if (IAIObject* aiObject = pEntity->GetAI())
	{
		if(type==AIOBJECT_SNDSUPRESSOR)
			aiObject->SetRadius(params.m_moveAbility.pathRadius);
		else if(type>=AIANCHOR_FIRST)	// if anchor - set radius
		{
			SmartScriptTable pTable;
			// Properties table
			if (pH->GetParamCount() > 2)
				pH->GetParam(3,pTable);
			else
				return pH->EndFunction();
			float radius(0.f);
			pTable->GetValue("radius",radius);
			int groupId = -1;
			pTable->GetValue("groupid", groupId);
			aiObject->SetGroupId(groupId);
			aiObject->SetRadius(radius);
		}

		if (IAIActorProxy* proxy = aiObject->GetProxy())
			proxy->UpdateMeAlways(!autoDisable);
	}

	return pH->EndFunction();
}
Ejemplo n.º 30
0
void CGameAIRecorder::AddRecordBookmark(EntityId requesterId)
{
	assert(requesterId > 0);
	assert(gEnv->bServer);

	if (m_bIsRecording)
	{
		if (!gEnv->bServer)
		{
			CryLogAlways("[AI] Recorder bookmark requested on Client. Only the Server can do this!");
			return;
		}

		IEntity *pEntity = gEnv->pEntitySystem->GetEntity(requesterId);
		IAIObject *pAI = pEntity ? pEntity->GetAI() : NULL;
		if (!pAI)
		{
			CryLogAlways("[AI] Attempting to add recorder bookmark, but the requester does not have an AI!");
			return;
		}

		static int g_iBookmarkCounter = 0;
		int iBookmark = ++g_iBookmarkCounter;

		// (Kevin) We need to unify the timestamp for this, which should be set when the Recorder itself starts.
		//	This way, all screenshots will match up with the recorder per date/time/build. Then we need to
		//	move these into subfolders that contain the date/time/build as the name. (10/08/2009)

		time_t ltime;
		time(&ltime);
		tm *pTm = localtime(&ltime);
		char szDate[128];
		strftime(szDate, 128, "Date(%d %b %Y) Time(%H %M %S)", pTm);

		// Get current version line
		const SFileVersion& fileVersion = gEnv->pSystem->GetFileVersion();

		const bool bTakeScreenshot = (requesterId == g_pGame->GetIGameFramework()->GetClientActorId());

		// Output to log
		CryLogAlways("[AI] --- RECORDER BOOKMARK ADDED ---");
		CryLogAlways("[AI] Id: %d", iBookmark);
		CryLogAlways("[AI] %s", szDate);
		CryLogAlways("[AI] By: %s", pEntity->GetName());

		if (!bTakeScreenshot)
		{
			CryLogAlways("[AI] No Screenshot was made for this bookmark, because requester is not the server!");
		}
		else
		{
			string sScreenShotFile;
			sScreenShotFile.Format("Recorder_Bookmark(%d) Build(%d) %s", iBookmark, fileVersion[0], szDate);

			const string sScreenShotPath = PathUtil::Make("Recordings", sScreenShotFile.c_str(), "jpg");

			// Take screenshot
			CryLogAlways("[AI] Screenshot: \'%s\'", sScreenShotPath.c_str());
			gEnv->pRenderer->ScreenShot(sScreenShotPath.c_str());

			OnAddBookmark(sScreenShotPath);
		}

		// Add bookmark to stream
		IAIRecordable::RecorderEventData data((float)iBookmark);
		pAI->RecordEvent(IAIRecordable::E_BOOKMARK, &data);
	}
}