예제 #1
0
bool CDialogActorContext::DoLookAt(IEntity *pEntity, IEntity *pLookAtEntity, bool& bReachedTarget)
{
	bReachedTarget = false;
	IAIObject* pAI = pEntity->GetAI();
	if (pAI == 0)
		return false;

	IAIActor* pAIActor = pAI->CastToIAIActor();
	if (!pAIActor)
	{
		return false;
	}

	if (pLookAtEntity == 0)
	{
		pAIActor->ResetLookAt();
		bReachedTarget = true;
		m_bLookAtNeedsReset = false;
	}
	else
	{
		IAIObject* pTargetAI = pLookAtEntity->GetAI();
		Vec3 pos = pTargetAI ? pTargetAI->GetPos() : pLookAtEntity->GetWorldPos();
		bReachedTarget = pAIActor->SetLookAtPointPos(pos, true);
		m_bLookAtNeedsReset = true;
	}

	return true;
}
예제 #2
0
//------------------------------------------------------------------------
int CScriptBind_Actor::Fall(IFunctionHandler *pH, Vec3 hitPos)
{
	CActor *pActor = GetActor(pH);
	if (!pActor)
		return pH->EndFunction();

	// [Mikko] 11.10.2007 - Moved the check here, since it was causing too much trouble in CActor.Fall().
	// The point of this filtering is to mostly mask out self-induced collision damage on friendly NPCs
	// which are playing special animations.
	if(!g_pGameCVars->g_enableFriendlyFallAndPlay)
	{
		if (IAnimatedCharacter* pAC = pActor->GetAnimatedCharacter())
		{
			if ((pAC->GetPhysicalColliderMode() == eColliderMode_NonPushable) ||
				(pAC->GetPhysicalColliderMode() == eColliderMode_PushesPlayersOnly))
			{
				// Only mask for player friendly NPCs.
				if (pActor->GetEntity() && pActor->GetEntity()->GetAI())
				{
					IAIObject* pAI = pActor->GetEntity()->GetAI();
					IAIActor* pAIActor = pAI->CastToIAIActor();
					if (pAIActor && pAIActor->GetParameters().m_nSpecies == 0)
					{
						return pH->EndFunction();
					}
				}
			}
		}
	}

	pActor->Fall(hitPos);

	return pH->EndFunction();
}
예제 #3
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;
}