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