BVB Source Codes

CRYENGINE Show FlowDialogNode.cpp Source code

Return Download CRYENGINE: download FlowDialogNode.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   FlowDialogNode.cpp
  5. //  Version:     v1.00
  6. //  Created:     14-07-2006 by AlexL
  7. //  Compilers:   Visual Studio.NET 2003
  8. //  Description:
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15. #include "CryActionCVars.h"
  16. #include "CryAction.h"
  17.  
  18. #include "../../DialogSystem/DialogQueuesManager.h"
  19. #include "../../DialogSystem/DialogSystem.h"
  20. #include "../../DialogSystem/DialogSession.h"
  21.  
  22. #include <CryFlowGraph/IFlowBaseNode.h>
  23.  
  24. //HD-Remark: This is the Flow node for the legacy dialog system
  25.  
  26. #define DIALOG_NODE_FINAL
  27. // #undef  DIALOG_NODE_FINAL
  28. //////////////////////////////////////////////////////////////////////////
  29.  
  30. class CFlowDialogNode : public CFlowBaseNode<eNCT_Instanced>, public IDialogSessionListener
  31. {
  32. public:
  33.         CFlowDialogNode(SActivationInfo* pActInfo)
  34.         {
  35.                 m_sessionID = 0;
  36.                 m_bIsPlaying = false;
  37.                 m_actInfo = *pActInfo;
  38.                 m_buffer = CDialogQueuesManager::NO_QUEUE;
  39.                 m_idForQueueManager = 0;
  40.                 m_bufferDelayLeft = 0;
  41.         }
  42.  
  43.         ~CFlowDialogNode()
  44.         {
  45.                 StopDialog();
  46.         }
  47.  
  48.         IFlowNodePtr Clone(SActivationInfo* pActInfo)
  49.         {
  50.                 return new CFlowDialogNode(pActInfo);
  51.         }
  52.  
  53.         virtual void GetMemoryUsage(ICrySizer* s) const
  54.         {
  55.                 s->Add(*this);
  56.         }
  57.  
  58.         virtual void Serialize(SActivationInfo* pActInfo, TSerialize ser)
  59.         {
  60.                 ser.Value("m_sessionID", m_sessionID);
  61.                 ser.Value("m_buffer", m_buffer);
  62.                 ser.Value("m_idForBufferMgr", m_idForQueueManager);
  63.                 ser.Value("m_bufferDelayLeft", m_bufferDelayLeft);
  64.                 if (ser.IsReading() && m_sessionID != 0)
  65.                 {
  66.                         CDialogSession* pSession = GetSession();
  67.                         assert(pSession != 0);
  68.                         if (pSession)
  69.                         {
  70.                                 pSession->AddListener(this);
  71.                         }
  72.                 }
  73.         }
  74.  
  75.         static const int MAX_ACTORS = 8;
  76.  
  77.         enum
  78.         {
  79.                 EIP_Play = 0,
  80.                 EIP_Stop,
  81.                 EIP_Dialog,
  82.                 EIP_StartLine,
  83.                 EIP_AIInterrupt,
  84.                 EIP_AwareDist,
  85.                 EIP_AwareAngle,
  86.                 EIP_AwareTimeOut,
  87.                 EIP_Flags,
  88.                 EIP_BufferId,
  89.                 EIP_BufferDelay,
  90.                 EIP_ActorFirst,
  91.                 EIP_ActorLast = EIP_ActorFirst + MAX_ACTORS - 1,
  92.         };
  93.  
  94.         enum
  95.         {
  96.                 EOP_Started = 0,
  97.                 EOP_DoneFinishedOrAborted,
  98.                 EOP_Finished,
  99.                 EOP_Aborted,
  100.                 EOP_PlayerAbort,
  101.                 EOP_AIAbort,
  102.                 EOP_ActorDied,
  103.                 EOP_LastLine,
  104.                 EOP_CurrentLine
  105.         };
  106.  
  107.         void GetConfiguration(SFlowNodeConfig& config)
  108.         {
  109.                 static const SInputPortConfig in_config[] = {
  110.                         InputPortConfig_Void("Play",             _HELP("Trigger to play the Dialog")),
  111.                         InputPortConfig_Void("Stop",             _HELP("Trigger to stop the Dialog")),
  112.                         InputPortConfig<string>("dialog_Dialog", _HELP("Dialog to play"),             _HELP("Dialog")),
  113.                         InputPortConfig<int>("StartLine",        0,                                   _HELP("Line to start Dialog from")),
  114.                         InputPortConfig<int>("AIInterrupt",      0,                                   _HELP("AI interrupt behaviour: Never, Alert, Combat"),                                                                                                                                0,  _UICONFIG("enum_int:Alert=0,Combat=1,Never=2")),
  115.                         InputPortConfig<float>("AwareDistance",  0.f,                                 _HELP("Max. Distance Player is considered as listening. 0.0 disables check.")),
  116.                         InputPortConfig<float>("AwareAngle",     0.f,                                 _HELP("Max. View Angle Player is considered as listening. 0.0 disables check")),
  117.                         InputPortConfig<float>("AwareTimeout",   3.0f,                                _HELP("TimeOut until non-aware Player aborts dialog. [Effective pnly if AwareDistance or AwareAngle != 0]")),
  118.                         InputPortConfig<int>("Flags",            0,                                   _HELP("Dialog Playback Flags"),                                                                                                                                                       0,  _UICONFIG("enum_int:None=0,FinishLineOnAbort=1")),
  119.                         InputPortConfig<int>("Buffer",           0,                                   _HELP("Only 1 dialog can be played at any time in each buffer."),                                                                                                                     0,  _UICONFIG("enum_global:dialogBuffers")),
  120.                         InputPortConfig<float>("BufferDelay",    0,                                   _HELP("How much aditional time (seconds) this dialog will wait after the previous dialog in its buffer is done. (not used if buffer=NoBuffer, or if the buffer was empty already)")),
  121.                         InputPortConfig<EntityId>("Actor1",      _HELP("Actor 1 [EntityID]"),         _HELP("Actor 1")),
  122.                         InputPortConfig<EntityId>("Actor2",      _HELP("Actor 2 [EntityID]"),         _HELP("Actor 2")),
  123.                         InputPortConfig<EntityId>("Actor3",      _HELP("Actor 3 [EntityID]"),         _HELP("Actor 3")),
  124.                         InputPortConfig<EntityId>("Actor4",      _HELP("Actor 4 [EntityID]"),         _HELP("Actor 4")),
  125.                         InputPortConfig<EntityId>("Actor5",      _HELP("Actor 5 [EntityID]"),         _HELP("Actor 5")),
  126.                         InputPortConfig<EntityId>("Actor6",      _HELP("Actor 6 [EntityID]"),         _HELP("Actor 6")),
  127.                         InputPortConfig<EntityId>("Actor7",      _HELP("Actor 7 [EntityID]"),         _HELP("Actor 7")),
  128.                         InputPortConfig<EntityId>("Actor8",      _HELP("Actor 8 [EntityID]"),         _HELP("Actor 8")),
  129.                         { 0 }
  130.                 };
  131.                 static const SOutputPortConfig out_config[] = {
  132.                         OutputPortConfig_Void("Started",     _HELP("Triggered when the Dialog started.")),
  133.                         OutputPortConfig_Void("DoneFOA",     _HELP("Triggered when the Dialog ended [Finished OR Aborted]."),                                         _HELP("Done")),
  134.                         OutputPortConfig_Void("Done",        _HELP("Triggered when the Dialog finished normally."),                                                   _HELP("Finished")),
  135.                         OutputPortConfig_Void("Aborted",     _HELP("Triggered when the Dialog was aborted.")),
  136.                         OutputPortConfig<int>("PlayerAbort", _HELP("Triggered when the Dialog was aborted because Player was not aware.\n1=OutOfRange\n2=OutOfView")),
  137.                         OutputPortConfig_Void("AIAbort",     _HELP("Triggered when the Dialog was aborted because AI got alerted.")),
  138.                         OutputPortConfig_Void("ActorDied",   _HELP("Triggered when the Dialog was aborted because an Actor died.")),
  139.                         OutputPortConfig<int>("LastLine",    _HELP("Last line when dialog was aborted.")),
  140.                         OutputPortConfig<int>("CurLine",     _HELP("Current line. Triggered whenever a line starts.")),
  141.                         { 0 }
  142.                 };
  143.                 config.sDescription = _HELP("Play a Dialog - WIP");
  144.                 config.pInputPorts = in_config;
  145.                 config.pOutputPorts = out_config;
  146.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  147.                 config.SetCategory(EFLN_ADVANCED);
  148.         }
  149.  
  150.         void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  151.         {
  152.                 switch (event)
  153.                 {
  154.                 case eFE_Initialize:
  155.                         break;
  156.                 case eFE_Activate:
  157.                         if (IsPortActive(pActInfo, EIP_Stop))
  158.                         {
  159.                                 bool bOk = StopDialog();
  160.                                 if (bOk)
  161.                                         ActivateOutput(pActInfo, EOP_DoneFinishedOrAborted, true);
  162.                         }
  163.                         if (IsPortActive(pActInfo, EIP_Play))
  164.                         {
  165.                                 bool bOk = StopDialog();
  166.                                 if (bOk)
  167.                                         ActivateOutput(pActInfo, EOP_DoneFinishedOrAborted, true);
  168.  
  169.                                 const string& dialogString = GetPortString(pActInfo, EIP_Dialog);
  170.                                 CDialogQueuesManager* pMgr = CCryAction::GetCryAction()->GetDialogSystem()->GetDialogQueueManager();
  171.                                 m_buffer = pMgr->BufferEnumToId(GetPortInt(pActInfo, EIP_BufferId)); // we get the buffer value at this time and use it from now on. If something changes the port value after that, we are not going to care! at all!
  172.                                 if (pMgr->IsBufferFree(m_buffer))
  173.                                 {
  174.                                         bOk = PlayDialog(pActInfo);
  175.                                         if (bOk)
  176.                                                 m_idForQueueManager = pMgr->Play(m_buffer, dialogString);
  177.                                 }
  178.                                 else
  179.                                 {
  180.                                         m_idForQueueManager = pMgr->Play(m_buffer, dialogString);
  181.                                         pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true);
  182.                                         m_bufferDelayLeft = GetPortFloat(pActInfo, EIP_BufferDelay);
  183.                                 }
  184.                         }
  185.                         break;
  186.  
  187.                 case eFE_Update:
  188.                         {
  189.                                 if (m_buffer == CDialogQueuesManager::NO_QUEUE) // if is updating, and yet nobuffer, only can be because it has been stopped abruptly
  190.                                 {
  191.                                         pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false);
  192.                                 }
  193.                                 else
  194.                                 {
  195.                                         if (CDialogSystem* pDS = CCryAction::GetCryAction()->GetDialogSystem())
  196.                                         {
  197.                                                 CDialogQueuesManager* pMgr = pDS->GetDialogQueueManager();
  198.  
  199.                                                 if (!pMgr->IsDialogWaiting(m_buffer, m_idForQueueManager))
  200.                                                 {
  201.                                                         if (m_bufferDelayLeft > 0)
  202.                                                                 m_bufferDelayLeft -= gEnv->pTimer->GetFrameTime();
  203.                                                         else
  204.                                                         {
  205.                                                                 pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false);
  206.                                                                 bool bOk = PlayDialog(pActInfo);
  207.                                                                 if (!bOk)
  208.                                                                         NotifyToBufferMgrDialogStopped();
  209.                                                         }
  210.                                                 }
  211.                                         }
  212.                                 }
  213.                                 break;
  214.                         }
  215.                 }
  216.         }
  217.  
  218. protected:
  219.  
  220.         void NotifyToBufferMgrDialogStopped()
  221.         {
  222.                 if (m_buffer != CDialogQueuesManager::NO_QUEUE)
  223.                 {
  224.                         if (CDialogSystem* pDS = CCryAction::GetCryAction()->GetDialogSystem())
  225.                         {
  226.                                 CDialogQueuesManager* pMgr = pDS->GetDialogQueueManager();
  227.                                 pMgr->NotifyDialogDone(m_buffer, m_idForQueueManager);
  228.                                 m_buffer = CDialogQueuesManager::NO_QUEUE;
  229.                         }
  230.                 }
  231.         }
  232.  
  233.         CDialogSession* GetSession()
  234.         {
  235.                 CDialogSystem* pDS = NULL;
  236.                 CCryAction* pCryAction = CCryAction::GetCryAction();
  237.                 if (pCryAction)
  238.                         pDS = pCryAction->GetDialogSystem();
  239.                 if (pDS)
  240.                         return pDS->GetSession(m_sessionID);
  241.                 return 0;
  242.         }
  243.  
  244.         bool StopDialog()
  245.         {
  246.                 NotifyToBufferMgrDialogStopped();
  247.                 m_bIsPlaying = false;
  248.                 CDialogSession* pSession = GetSession();
  249.                 if (pSession)
  250.                 {
  251.                         // we always remove first, so we don't get notified
  252.                         pSession->RemoveListener(this);
  253.  
  254.                         CDialogSystem* pDS = CCryAction::GetCryAction()->GetDialogSystem();
  255.                         if (pDS)
  256.                         {
  257.                                 pDS->DeleteSession(m_sessionID);
  258.                         }
  259.                         m_sessionID = 0;
  260.                         return true;
  261.                 }
  262.                 return false;
  263.         }
  264.  
  265.         bool PlayDialog(SActivationInfo* pActInfo)
  266.         {
  267.                 CDialogSystem* pDS = CCryAction::GetCryAction()->GetDialogSystem();
  268.                 if (!pDS)
  269.                         return true;
  270.                 const int fromLine = GetPortInt(pActInfo, EIP_StartLine);
  271.                 const string& scriptID = GetPortString(pActInfo, EIP_Dialog);
  272.                 m_sessionID = pDS->CreateSession(scriptID);
  273.                 if (m_sessionID == 0)
  274.                 {
  275.                         GameWarning("[flow] PlayDialog: Cannot create DialogSession with Script '%s'.", scriptID.c_str());
  276.                         return false;
  277.                 }
  278.  
  279.                 CDialogSession* pSession = GetSession();
  280.                 assert(pSession != 0);
  281.                 if (pSession == 0)
  282.                         return false;
  283.  
  284.                 // set actor flags (actually we could have flags per actor, but we use the same Flags for all of them)
  285.                 CDialogSession::TActorFlags actorFlags = CDialogSession::eDACF_Default;
  286.                 switch (GetPortInt(pActInfo, EIP_Flags))
  287.                 {
  288.                 case 1:
  289.                         actorFlags = CDialogSession::eDACF_NoAbortSound;
  290.                         break;
  291.                 default:
  292.                         break;
  293.                 }
  294.  
  295.                 // stage actors
  296.                 for (int i = 0; i < MAX_ACTORS; ++i)
  297.                 {
  298.                         EntityId id = GetPortEntityId(pActInfo, i + EIP_ActorFirst);
  299.                         if (id != 0)
  300.                         {
  301.                                 pSession->SetActor(static_cast<CDialogScript::TActorID>(i), id);
  302.                                 pSession->SetActorFlags(static_cast<CDialogScript::TActorID>(i), actorFlags);
  303.                         }
  304.                 }
  305.  
  306.                 pSession->SetAIBehaviourMode(CDialogSession::eDIB_InterruptNever);
  307.                 pSession->SetPlayerAwarenessDistance(GetPortFloat(pActInfo, EIP_AwareDist));
  308.                 pSession->SetPlayerAwarenessAngle(GetPortFloat(pActInfo, EIP_AwareAngle));
  309.                 pSession->SetPlayerAwarenessGraceTime(GetPortFloat(pActInfo, EIP_AwareTimeOut));
  310.  
  311.                 const int alertnessInterruptModeInput = GetPortInt(pActInfo, EIP_AIInterrupt);
  312.                 CDialogSession::AlertnessInterruptMode alertnessInterruptMode = CDialogSession::None;
  313.                 switch (alertnessInterruptModeInput)
  314.                 {
  315.                 case 0:
  316.                         alertnessInterruptMode = CDialogSession::Alert;
  317.                         break;
  318.                 case 1:
  319.                         alertnessInterruptMode = CDialogSession::Combat;
  320.                         break;
  321.                 case 2:
  322.                         alertnessInterruptMode = CDialogSession::None;
  323.                         break;
  324.                 default:
  325.                         assert(false);
  326.                         break;
  327.                 }
  328.                 pSession->SetAlertnessInterruptMode(alertnessInterruptMode);
  329.  
  330.                 // Validate the session
  331.                 if (pSession->Validate() == false)
  332.                 {
  333.                         CDialogScript::SActorSet currentSet = pSession->GetCurrentActorSet();
  334.                         CDialogScript::SActorSet reqSet = pSession->GetScript()->GetRequiredActorSet();
  335.                         GameWarning("[flow] PlayDialog: Session with Script '%s' cannot be validated: ", scriptID.c_str());
  336.                         for (int i = 0; i < CDialogScript::MAX_ACTORS; ++i)
  337.                         {
  338.                                 if (reqSet.HasActor(i) && !currentSet.HasActor(i))
  339.                                 {
  340.                                         GameWarning("[flow]  Actor %d is missing.", i + 1);
  341.                                 }
  342.                         }
  343.  
  344.                         pDS->DeleteSession(m_sessionID);
  345.                         m_sessionID = 0;
  346.                         return false;
  347.                 }
  348.  
  349.                 pSession->AddListener(this);
  350.  
  351.                 const bool bPlaying = pSession->Play(fromLine);
  352.                 if (!bPlaying)
  353.                 {
  354.                         pSession->RemoveListener(this);
  355.                         pDS->DeleteSession(m_sessionID);
  356.                         m_sessionID = 0;
  357.                 }
  358.  
  359.                 return m_sessionID != 0;
  360.         }
  361. protected:
  362.         // IDialogSessionListener
  363.         virtual void SessionEvent(CDialogSession* pSession, CDialogSession::EDialogSessionEvent event)
  364.         {
  365.                 if (pSession && pSession->GetSessionID() == m_sessionID)
  366.                 {
  367.                         switch (event)
  368.                         {
  369.                         case CDialogSession::eDSE_SessionStart:
  370.                                 ActivateOutput(&m_actInfo, EOP_Started, true);
  371.                                 m_bIsPlaying = true;
  372.                                 break;
  373.                         case CDialogSession::eDSE_Aborted:
  374.                                 {
  375.                                         const CDialogSession::EAbortReason reason = pSession->GetAbortReason();
  376.                                         const int curLine = pSession->GetCurrentLine();
  377.                                         StopDialog();
  378.                                         ActivateOutput(&m_actInfo, EOP_DoneFinishedOrAborted, true);
  379.                                         ActivateOutput(&m_actInfo, EOP_Aborted, true);
  380.                                         ActivateOutput(&m_actInfo, EOP_LastLine, curLine);
  381.  
  382.                                         if (reason == CDialogSession::eAR_AIAborted)
  383.                                                 ActivateOutput(&m_actInfo, EOP_AIAbort, true);
  384.                                         else if (reason == CDialogSession::eAR_PlayerOutOfRange)
  385.                                                 ActivateOutput(&m_actInfo, EOP_PlayerAbort, 1);
  386.                                         else if (reason == CDialogSession::eAR_PlayerOutOfView)
  387.                                                 ActivateOutput(&m_actInfo, EOP_PlayerAbort, 2);
  388.                                         else if (reason == CDialogSession::eAR_ActorDead)
  389.                                                 ActivateOutput(&m_actInfo, EOP_ActorDied, true);
  390.                                 }
  391.                                 break;
  392.                         case CDialogSession::eDSE_EndOfDialog:
  393.                                 StopDialog();
  394.                                 ActivateOutput(&m_actInfo, EOP_Finished, true);
  395.                                 ActivateOutput(&m_actInfo, EOP_DoneFinishedOrAborted, true);
  396.                                 break;
  397.                         case CDialogSession::eDSE_UserStopped:
  398.                                 StopDialog();
  399.                                 ActivateOutput(&m_actInfo, EOP_DoneFinishedOrAborted, true);
  400.                                 break;
  401.                         case CDialogSession::eDSE_SessionDeleted:
  402.                                 m_sessionID = 0;
  403.                                 m_bIsPlaying = false;
  404.                                 NotifyToBufferMgrDialogStopped();
  405.                                 break;
  406.                         case CDialogSession::eDSE_LineStarted:
  407.                                 ActivateOutput(&m_actInfo, EOP_CurrentLine, pSession->GetCurrentLine());
  408.                                 break;
  409.                         }
  410.                 }
  411.         }
  412.         // ~IDialogSessionListener
  413.  
  414. private:
  415.         SActivationInfo                 m_actInfo;
  416.         CDialogSystem::SessionID        m_sessionID;
  417.         CDialogQueuesManager::TDialogId m_idForQueueManager;
  418.         uint32                          m_buffer;
  419.         float                           m_bufferDelayLeft;
  420.         bool                            m_bIsPlaying;
  421. };
  422.  
  423. #ifdef DIALOG_NODE_FINAL
  424. REGISTER_FLOW_NODE("Dialog:PlayDialog", CFlowDialogNode);
  425. #endif
  426.  
downloadFlowDialogNode.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top