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