void CDialogActorContext::BeginSession() { DiaLOG::Log(DiaLOG::eAlways, "[DIALOG] CDialogActorContext::BeginSession: %s Now=%f 0x%p actorID=%d ", m_pSession->GetDebugName(), m_pSession->GetCurTime(), this, m_actorID); ResetState(); IEntitySystem* pES = gEnv->pEntitySystem; pES->AddEntityEventListener( m_entityID, ENTITY_EVENT_AI_DONE, this ); pES->AddEntityEventListener( m_entityID, ENTITY_EVENT_DONE, this ); pES->AddEntityEventListener( m_entityID, ENTITY_EVENT_RESET, this ); switch (GetAIBehaviourMode()) { case CDialogSession::eDIB_InterruptAlways: ExecuteAI( m_goalPipeID, "ACT_ANIM" ); break; case CDialogSession::eDIB_InterruptMedium: ExecuteAI( m_goalPipeID, "ACT_DIALOG" ); break; case CDialogSession::eDIB_InterruptNever: break; } m_bNeedsCancel = true; }
void ServerInstance::Update(int deltaMillis) { Instance::Update(deltaMillis); for (auto &pair : mObjects) { auto object = pair.second; auto npcComponent = object->FindComponent<NPCComponent>(); if (npcComponent) { // Update NPC AI npcComponent->ExecuteAI(this, deltaMillis); } } }
bool CDialogActorContext::DoAnimActionEP(IEntity* pEntity, const char* sAction) { IAIObject* pAI = pEntity->GetAI(); if (pAI == 0) return false; IPipeUser* pPipeUser = pAI->CastToIPipeUser(); if (!pPipeUser) { return false; } Vec3 pos = pEntity->GetWorldPos(); Vec3 dir = pAI->GetMoveDir(); // EP Direction is either lookat direction or forward direction CDialogScript::TActorID lookAt = m_pCurLine->m_lookatActor; if (lookAt != CDialogScript::NO_ACTOR_ID) { IEntity* pLookAtEntity = m_pSession->GetActorEntity(lookAt); if (pLookAtEntity != 0) { dir = pLookAtEntity->GetWorldPos(); dir -= pos; dir.z = 0; dir.NormalizeSafe(pAI->GetMoveDir()); } } pPipeUser->SetRefPointPos(pos, dir); static const Vec3 startRadius (0.1f,0.1f,0.1f); static const float dirTolerance = 5.f; static const float targetRadius = 0.05f; IAISignalExtraData* pData = gEnv->pAISystem->CreateSignalExtraData(); pData->iValue2 = m_bAnimUseAGSignal ? 1 : 0; pData->SetObjectName(sAction); pData->point = startRadius; pData->fValue = dirTolerance; pData->point2.x = targetRadius; const bool ok = ExecuteAI(m_exPosAnimPipeID, "ACT_ANIMEX", pData); return ok; }
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; }