BVB Source Codes

CRYENGINE Show BehaviorTreeNodes_Core.cpp Source code

Return Download CRYENGINE: download BehaviorTreeNodes_Core.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "BehaviorTreeNodes_Core.h"
  5.  
  6. #include <CryAISystem/BehaviorTree/Composite.h>
  7. #include <CryAISystem/BehaviorTree/Decorator.h>
  8. #include <CryAISystem/BehaviorTree/Action.h>
  9. #include <CryAISystem/BehaviorTree/SerializationSupport.h>
  10. #include <CrySystem/Timer.h>
  11. #include "BehaviorTreeManager.h"
  12. #include "BehaviorTreeGraft.h"
  13.  
  14. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  15.         #include <CrySerialization/Enum.h>
  16. #endif
  17.  
  18. namespace BehaviorTree
  19. {
  20. //////////////////////////////////////////////////////////////////////////
  21.  
  22. // Executes children one at a time in order.
  23. // Succeeds when all children succeeded.
  24. // Fails when a child failed.
  25. class Sequence : public CompositeWithChildLoader
  26. {
  27.         typedef CompositeWithChildLoader BaseClass;
  28.  
  29. public:
  30.         typedef uint8 IndexType;
  31.  
  32.         struct RuntimeData
  33.         {
  34.                 IndexType currentChildIndex;
  35.  
  36.                 RuntimeData()
  37.                         : currentChildIndex(0)
  38.                 {
  39.                 }
  40.         };
  41.  
  42.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  43.         {
  44.                 IF_UNLIKELY (BaseClass::LoadFromXml(xml, context) == LoadFailure)
  45.                         return LoadFailure;
  46.  
  47.                 const size_t maxChildCount = std::numeric_limits<IndexType>::max();
  48.                 IF_UNLIKELY ((size_t)xml->getChildCount() > maxChildCount)
  49.                 {
  50.                         ErrorReporter(*this, context).LogError("Too many children. Max %d children are supported.", maxChildCount);
  51.                         return LoadFailure;
  52.                 }
  53.  
  54.                 return LoadSuccess;
  55.         }
  56.  
  57. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  58.         virtual XmlNodeRef CreateXmlDescription() override
  59.         {
  60.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  61.                 xml->setTag("Sequence");
  62.                 return xml;
  63.         }
  64. #endif
  65.  
  66. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  67.         virtual void Serialize(Serialization::IArchive& archive) override
  68.         {
  69.                 BaseClass::Serialize(archive);
  70.  
  71.                 if (m_children.empty())
  72.                         archive.error(m_children, "Must contain a node");
  73.  
  74.                 if (m_children.size() == 1)
  75.                         archive.warning(m_children, "Sequence with only one node is superfluous");
  76.         }
  77. #endif
  78.  
  79.         virtual void OnInitialize(const UpdateContext& context) override
  80.         {
  81.         }
  82.  
  83. protected:
  84.         virtual Status Update(const UpdateContext& context) override
  85.         {
  86.                 FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  87.  
  88.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  89.  
  90.                 IndexType& currentChildIndex = runtimeData.currentChildIndex;
  91.  
  92.                 while (true)
  93.                 {
  94.                         assert(currentChildIndex < m_children.size());
  95.                         const Status s = m_children[currentChildIndex]->Tick(context);
  96.  
  97.                         if (s == Running || s == Failure)
  98.                         {
  99.                                 return s;
  100.                         }
  101.  
  102.                         if (++currentChildIndex == m_children.size())
  103.                         {
  104.                                 return Success;
  105.                         }
  106.                 }
  107.  
  108.                 assert(false);
  109.                 return Invalid;
  110.         }
  111.  
  112.         virtual void OnTerminate(const UpdateContext& context) override
  113.         {
  114.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  115.                 const IndexType currentChildIndex = runtimeData.currentChildIndex;
  116.  
  117.                 if (currentChildIndex < m_children.size())
  118.                 {
  119.                         m_children[currentChildIndex]->Terminate(context);
  120.                 }
  121.         }
  122.  
  123. private:
  124.         virtual void HandleEvent(const EventContext& context, const Event& event) override
  125.         {
  126.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  127.                 const IndexType currentChildIndex = runtimeData.currentChildIndex;
  128.                 if (currentChildIndex < m_children.size())
  129.                 {
  130.                         m_children[currentChildIndex]->SendEvent(context, event);
  131.                 }
  132.         }
  133. };
  134.  
  135. //////////////////////////////////////////////////////////////////////////
  136.  
  137. // Executes children one at a time in order.
  138. // Succeeds if child succeeds, otherwise tries next.
  139. // Fails when all children failed.
  140. class Selector : public CompositeWithChildLoader
  141. {
  142. public:
  143.         typedef uint8                    ChildIndexType;
  144.         typedef CompositeWithChildLoader BaseClass;
  145.  
  146.         struct RuntimeData
  147.         {
  148.                 ChildIndexType currentChildIndex;
  149.  
  150.                 RuntimeData()
  151.                         : currentChildIndex(0)
  152.                 {
  153.                 }
  154.         };
  155.  
  156. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  157.         virtual XmlNodeRef CreateXmlDescription() override
  158.         {
  159.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  160.                 xml->setTag("Selector");
  161.                 return xml;
  162.         }
  163. #endif
  164.  
  165. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  166.         virtual void Serialize(Serialization::IArchive& archive) override
  167.         {
  168.                 BaseClass::Serialize(archive);
  169.  
  170.                 if (m_children.empty())
  171.                         archive.error(m_children, "Must contain a node");
  172.  
  173.                 if (m_children.size() == 1)
  174.                         archive.warning(m_children, "Selector with only one node is superfluous");
  175.         }
  176. #endif
  177.  
  178. protected:
  179.         virtual void OnTerminate(const UpdateContext& context) override
  180.         {
  181.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  182.  
  183.                 if (runtimeData.currentChildIndex < m_children.size())
  184.                 {
  185.                         m_children[runtimeData.currentChildIndex]->Terminate(context);
  186.                 }
  187.         }
  188.  
  189.         virtual Status Update(const UpdateContext& context) override
  190.         {
  191.                 FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  192.  
  193.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  194.  
  195.                 ChildIndexType& currentChildIndex = runtimeData.currentChildIndex;
  196.  
  197.                 while (true)
  198.                 {
  199.                         const Status s = m_children[currentChildIndex]->Tick(context);
  200.  
  201.                         if (s == Success || s == Running)
  202.                         {
  203.                                 return s;
  204.                         }
  205.  
  206.                         if (++currentChildIndex == m_children.size())
  207.                         {
  208.                                 return Failure;
  209.                         }
  210.                 }
  211.  
  212.                 assert(false);
  213.                 return Invalid;
  214.         }
  215.  
  216. private:
  217.         virtual void HandleEvent(const EventContext& context, const Event& event) override
  218.         {
  219.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  220.  
  221.                 if (runtimeData.currentChildIndex < m_children.size())
  222.                 {
  223.                         m_children[runtimeData.currentChildIndex]->SendEvent(context, event);
  224.                 }
  225.         }
  226. };
  227.  
  228. //////////////////////////////////////////////////////////////////////////
  229.  
  230. // Composite node which executes it's children in parallel.
  231. // By default it returns Success when all children have succeeded
  232. // and Failure when any of any child has failed.
  233. // The behavior can be customized.
  234. class Parallel : public CompositeWithChildLoader
  235. {
  236. public:
  237.         typedef CompositeWithChildLoader BaseClass;
  238.  
  239.         struct RuntimeData
  240.         {
  241.                 uint32 runningChildren;     // Each bit is a child
  242.                 uint32 successCount;
  243.                 uint32 failureCount;
  244.  
  245.                 RuntimeData()
  246.                         : runningChildren(0)
  247.                         , successCount(0)
  248.                         , failureCount(0)
  249.                 {
  250.                 }
  251.         };
  252.  
  253.         Parallel()
  254.                 : m_successMode(SuccessMode_All)
  255.                 , m_failureMode(FailureMode_Any)
  256.         {
  257.         }
  258.  
  259.         virtual LoadResult LoadFromXml(const XmlNodeRef& node, const LoadContext& context) override
  260.         {
  261.                 IF_UNLIKELY (node->getChildCount() > 32)
  262.                 {
  263.                         ErrorReporter(*this, context).LogError("Too many children. Max 32 children allowed.");
  264.                         return LoadFailure;
  265.                 }
  266.  
  267.                 m_successMode = SuccessMode_All;
  268.                 m_failureMode = FailureMode_Any;
  269.  
  270.                 stack_string failureMode = node->getAttr("failureMode");
  271.                 if (!failureMode.empty())
  272.                 {
  273.                         if (!failureMode.compare("all"))
  274.                         {
  275.                                 m_failureMode = FailureMode_All;
  276.                         }
  277.                         else if (!failureMode.compare("any"))
  278.                         {
  279.                                 m_failureMode = FailureMode_Any;
  280.                         }
  281.                         else
  282.                         {
  283.                                 gEnv->pLog->LogError("Error in the %s behavior tree : the parallel node at %d has an invalid value for the attribute failureMode.", context.treeName, node->getLine());
  284.                         }
  285.                 }
  286.  
  287.                 stack_string successMode = node->getAttr("successMode");
  288.                 if (!successMode.empty())
  289.                 {
  290.                         if (!successMode.compare("any"))
  291.                         {
  292.                                 m_successMode = SuccessMode_Any;
  293.                         }
  294.                         else if (!successMode.compare("all"))
  295.                         {
  296.                                 m_successMode = SuccessMode_All;
  297.                         }
  298.                         else
  299.                         {
  300.                                 gEnv->pLog->LogError("Error in the %s behavior tree : the parallel node at %d has an invalid value for the attribute successMode.", context.treeName, node->getLine());
  301.                         }
  302.                 }
  303.  
  304.                 return CompositeWithChildLoader::LoadFromXml(node, context);
  305.         }
  306.  
  307. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  308.         virtual XmlNodeRef CreateXmlDescription() override
  309.         {
  310.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  311.  
  312.                 xml->setTag("Parallel");
  313.                 if (m_failureMode == FailureMode_All)
  314.                         xml->setAttr("failureMode", "all");
  315.                 if (m_successMode == SuccessMode_Any)
  316.                         xml->setAttr("successMode", "any");
  317.  
  318.                 return xml;
  319.         }
  320. #endif
  321.  
  322. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  323.         virtual void Serialize(Serialization::IArchive& archive) override
  324.         {
  325.                 archive(m_successMode, "successMode", "^Success Mode");
  326.                 archive(m_failureMode, "failureMode", "^Failure Mode");
  327.  
  328.                 BaseClass::Serialize(archive);
  329.  
  330.                 if (m_children.empty())
  331.                         archive.error(m_children, "Must contain a node");
  332.  
  333.                 if (m_children.size() == 1)
  334.                         archive.warning(m_children, "Parallel with only one node is superfluous");
  335.         }
  336. #endif
  337.  
  338.         virtual void OnInitialize(const UpdateContext& context) override
  339.         {
  340.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  341.  
  342.                 uint32 runningChildren = 0;
  343.                 for (size_t childIndex = 0, n = m_children.size(); childIndex < n; ++childIndex)
  344.                 {
  345.                         runningChildren |= 1 << childIndex;
  346.                 }
  347.  
  348.                 runtimeData.runningChildren = runningChildren;
  349.                 runtimeData.successCount = 0;
  350.                 runtimeData.failureCount = 0;
  351.         }
  352.  
  353.         virtual void OnTerminate(const UpdateContext& context) override
  354.         {
  355.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  356.  
  357.                 const uint32 runningChildren = runtimeData.runningChildren;
  358.                 for (size_t childIndex = 0, n = m_children.size(); childIndex < n; ++childIndex)
  359.                 {
  360.                         const bool childIsRunning = (runningChildren & (1 << childIndex)) != 0;
  361.                         if (childIsRunning)
  362.                         {
  363.                                 m_children[childIndex]->Terminate(context);
  364.                         }
  365.                 }
  366.         }
  367.  
  368.         virtual Status Update(const UpdateContext& context) override
  369.         {
  370.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  371.  
  372.                 uint32& runningChildren = runtimeData.runningChildren;
  373.                 uint32& successCount = runtimeData.successCount;
  374.                 uint32& failureCount = runtimeData.failureCount;
  375.  
  376.                 for (size_t childIndex = 0, n = m_children.size(); childIndex < n; ++childIndex)
  377.                 {
  378.                         const bool childIsRunning = (runningChildren & (1 << childIndex)) != 0;
  379.  
  380.                         if (childIsRunning)
  381.                         {
  382.                                 const Status s = m_children[childIndex]->Tick(context);
  383.  
  384.                                 if (s == Running)
  385.                                         continue;
  386.                                 else
  387.                                 {
  388.                                         if (s == Success)
  389.                                                 ++successCount;
  390.                                         else
  391.                                                 ++failureCount;
  392.  
  393.                                         // Mark child as not running
  394.                                         runningChildren = runningChildren & ~uint32(1u << childIndex);
  395.                                 }
  396.                         }
  397.                 }
  398.  
  399.                 if (m_successMode == SuccessMode_All)
  400.                 {
  401.                         if (successCount == m_children.size())
  402.                         {
  403.                                 return Success;
  404.                         }
  405.                 }
  406.                 else if (m_successMode == SuccessMode_Any)
  407.                 {
  408.                         if (successCount > 0)
  409.                         {
  410.                                 return Success;
  411.                         }
  412.                 }
  413.  
  414.                 if (m_failureMode == FailureMode_All)
  415.                 {
  416.                         if (failureCount == m_children.size())
  417.                         {
  418.                                 return Failure;
  419.                         }
  420.                 }
  421.                 else if (m_failureMode == FailureMode_Any)
  422.                 {
  423.                         if (failureCount > 0)
  424.                         {
  425.                                 return Failure;
  426.                         }
  427.                 }
  428.  
  429.                 return Running;
  430.         }
  431.  
  432.         enum SuccessMode
  433.         {
  434.                 SuccessMode_Any,
  435.                 SuccessMode_All,
  436.         };
  437.  
  438.         enum FailureMode
  439.         {
  440.                 FailureMode_Any,
  441.                 FailureMode_All,
  442.         };
  443.  
  444. private:
  445.         virtual void HandleEvent(const EventContext& context, const Event& event) override
  446.         {
  447.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  448.  
  449.                 const uint32 runningChildren = runtimeData.runningChildren;
  450.                 for (size_t childIndex = 0, n = m_children.size(); childIndex < n; ++childIndex)
  451.                 {
  452.                         const bool childIsRunning = (runningChildren & (1 << childIndex)) != 0;
  453.                         if (childIsRunning)
  454.                         {
  455.                                 m_children[childIndex]->SendEvent(context, event);
  456.                         }
  457.                 }
  458.         }
  459.  
  460.         SuccessMode m_successMode;
  461.         FailureMode m_failureMode;
  462. };
  463.  
  464. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  465. SERIALIZATION_ENUM_BEGIN_NESTED(Parallel, SuccessMode, "Success Mode")
  466. SERIALIZATION_ENUM(Parallel::SuccessMode_Any, "SuccessMode_Any", "Any")
  467. SERIALIZATION_ENUM(Parallel::SuccessMode_All, "SuccessMode_All", "All")
  468. SERIALIZATION_ENUM_END()
  469.  
  470. SERIALIZATION_ENUM_BEGIN_NESTED(Parallel, FailureMode, "Failure Mode")
  471. SERIALIZATION_ENUM(Parallel::FailureMode_Any, "FailureMode_Any", "Any")
  472. SERIALIZATION_ENUM(Parallel::FailureMode_All, "FailureMode_All", "All")
  473. SERIALIZATION_ENUM_END()
  474. #endif
  475.  
  476. //////////////////////////////////////////////////////////////////////////
  477.  
  478. // The loop fails when the child fails, otherwise the loop says it's running.
  479. //
  480. // If the child tick reports back that the child succeeded, the child will
  481. // immediately be ticked once more IF it was running _before_ the tick.
  482. // The effect of this is that if you have a child that runs over a period
  483. // of time, that child will be restarted immediately when it succeeds.
  484. // This behavior prevents the case where a non-instant loop's child could
  485. // mishandle an event if it was received during the window of time between
  486. // succeeding and being restarted by the loop node.
  487. //
  488. // However, if the child immediately succeeds, it will be ticked
  489. // only the next frame. Otherwise, it would get stuck in an infinite loop.
  490.  
  491. class Loop : public Decorator
  492. {
  493.         typedef Decorator BaseClass;
  494.  
  495. public:
  496.         struct RuntimeData
  497.         {
  498.                 uint8 amountOfTimesChildSucceeded;
  499.                 bool  childWasRunningLastTick;
  500.  
  501.                 RuntimeData()
  502.                         : amountOfTimesChildSucceeded(0)
  503.                         , childWasRunningLastTick(false)
  504.                 {
  505.                 }
  506.         };
  507.  
  508.         Loop()
  509.                 : m_desiredRepeatCount(0)
  510.         {
  511.         }
  512.  
  513.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  514.         {
  515.                 IF_UNLIKELY (BaseClass::LoadFromXml(xml, context) == LoadFailure)
  516.                         return LoadFailure;
  517.  
  518.                 m_desiredRepeatCount = 0;     // 0 means infinite
  519.                 xml->getAttr("count", m_desiredRepeatCount);
  520.  
  521.                 return LoadSuccess;
  522.         }
  523.  
  524. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  525.         virtual XmlNodeRef CreateXmlDescription() override
  526.         {
  527.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  528.                 xml->setTag("Loop");
  529.                 if (m_desiredRepeatCount)
  530.                         xml->setAttr("count", m_desiredRepeatCount);
  531.                 return xml;
  532.         }
  533. #endif
  534.  
  535. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  536.         virtual void Serialize(Serialization::IArchive& archive) override
  537.         {
  538.                 archive(m_desiredRepeatCount, "repeatCount", "Repeat count (0 means infinite)");
  539.                 BaseClass::Serialize(archive);
  540.         }
  541. #endif
  542.  
  543. protected:
  544.         virtual Status Update(const UpdateContext& context) override
  545.         {
  546.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  547.  
  548.                 Status childStatus = m_child->Tick(context);
  549.  
  550.                 if (childStatus == Success)
  551.                 {
  552.                         const bool finiteLoop = (m_desiredRepeatCount > 0);
  553.                         if (finiteLoop)
  554.                         {
  555.                                 if (runtimeData.amountOfTimesChildSucceeded + 1 >= m_desiredRepeatCount)
  556.                                 {
  557.                                         return Success;
  558.                                 }
  559.  
  560.                                 ++runtimeData.amountOfTimesChildSucceeded;
  561.                         }
  562.  
  563.                         if (runtimeData.childWasRunningLastTick)
  564.                         {
  565.                                 childStatus = m_child->Tick(context);
  566.                         }
  567.                 }
  568.  
  569.                 runtimeData.childWasRunningLastTick = (childStatus == Running);
  570.  
  571.                 if (childStatus == Failure)
  572.                 {
  573.                         return Failure;
  574.                 }
  575.  
  576.                 return Running;
  577.         }
  578.  
  579. private:
  580.         uint8 m_desiredRepeatCount;     // 0 means infinite
  581. };
  582.  
  583. //////////////////////////////////////////////////////////////////////////
  584.  
  585. // Similar to the loop. It will tick the child node and keep running
  586. // while it's running. If the child succeeds, this node succeeds.
  587. // If the child node fails we try again, a defined amount of times.
  588. // The only reason this is its own node and not a configuration of
  589. // the Loop node is because of readability. It became hard to read.
  590. class LoopUntilSuccess : public Decorator
  591. {
  592.         typedef Decorator BaseClass;
  593.  
  594. public:
  595.         struct RuntimeData
  596.         {
  597.                 uint8 failedAttemptCountSoFar;
  598.                 bool  childWasRunningLastTick;
  599.  
  600.                 RuntimeData()
  601.                         : failedAttemptCountSoFar(0)
  602.                         , childWasRunningLastTick(false)
  603.                 {
  604.                 }
  605.         };
  606.  
  607.         LoopUntilSuccess()
  608.                 : m_maxAttemptCount(0)
  609.         {
  610.         }
  611.  
  612.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  613.         {
  614.                 IF_UNLIKELY (BaseClass::LoadFromXml(xml, context) == LoadFailure)
  615.                         return LoadFailure;
  616.  
  617.                 m_maxAttemptCount = 0;     // 0 means infinite
  618.                 xml->getAttr("attemptCount", m_maxAttemptCount);
  619.  
  620.                 return LoadSuccess;
  621.         }
  622.  
  623. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  624.         virtual XmlNodeRef CreateXmlDescription() override
  625.         {
  626.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  627.  
  628.                 xml->setTag("LoopUntilSuccess");
  629.                 if (m_maxAttemptCount)
  630.                         xml->setAttr("attemptCount", m_maxAttemptCount);
  631.  
  632.                 return xml;
  633.         }
  634. #endif
  635.  
  636. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  637.         virtual void Serialize(Serialization::IArchive& archive) override
  638.         {
  639.                 archive(m_maxAttemptCount, "repeatCount", "Attempt count (0 means infinite)");
  640.                 BaseClass::Serialize(archive);
  641.         }
  642. #endif
  643.  
  644. protected:
  645.         virtual Status Update(const UpdateContext& context) override
  646.         {
  647.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  648.  
  649.                 Status childStatus = m_child->Tick(context);
  650.  
  651.                 if (childStatus == Failure)
  652.                 {
  653.                         const bool finiteLoop = (m_maxAttemptCount > 0);
  654.                         if (finiteLoop)
  655.                         {
  656.                                 if (runtimeData.failedAttemptCountSoFar + 1 >= m_maxAttemptCount)
  657.                                 {
  658.                                         return Failure;
  659.                                 }
  660.  
  661.                                 ++runtimeData.failedAttemptCountSoFar;
  662.                         }
  663.  
  664.                         if (runtimeData.childWasRunningLastTick)
  665.                         {
  666.                                 childStatus = m_child->Tick(context);
  667.                         }
  668.                 }
  669.  
  670.                 runtimeData.childWasRunningLastTick = (childStatus == Running);
  671.  
  672.                 if (childStatus == Success)
  673.                 {
  674.                         return Success;
  675.                 }
  676.  
  677.                 return Running;
  678.         }
  679.  
  680. private:
  681.         uint8 m_maxAttemptCount;     // 0 means infinite
  682. };
  683.  
  684. //////////////////////////////////////////////////////////////////////////
  685.  
  686. struct Case
  687. {
  688.         LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context)
  689.         {
  690.                 if (!xml->isTag("Case"))
  691.                 {
  692.                         gEnv->pLog->LogError("Priority node must only contain childs nodes of the type 'Case', and there is a child of the '%s' at line '%d'.", xml->getTag(), xml->getLine());
  693.                         return LoadFailure;
  694.                 }
  695.  
  696.                 string conditionString = xml->getAttr("condition");
  697.                 if (conditionString.empty())
  698.                         conditionString.Format("true");
  699.  
  700.                 condition.Reset(conditionString, context.variableDeclarations);
  701.                 if (!condition.Valid())
  702.                 {
  703.                         gEnv->pLog->LogError("Priority case condition '%s' couldn't be parsed.", conditionString.c_str());
  704.                         return LoadFailure;
  705.                 }
  706.  
  707. #ifdef USING_BEHAVIOR_TREE_EDITOR
  708.                 m_conditionString = conditionString;
  709. #endif
  710.  
  711.                 if (!xml->getChildCount() == 1)
  712.                 {
  713.                         gEnv->pLog->LogError("Priority case must have exactly one child.");
  714.                         return LoadFailure;
  715.                 }
  716.  
  717.                 XmlNodeRef childXml = xml->getChild(0);
  718.                 node = context.nodeFactory.CreateNodeFromXml(childXml, context);
  719.                 if (!node)
  720.                 {
  721.                         gEnv->pLog->LogError("Priority case failed to load child.");
  722.                         return LoadFailure;
  723.                 }
  724.  
  725.                 return LoadSuccess;
  726.         }
  727.  
  728. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  729.         XmlNodeRef CreateXmlDescription()
  730.         {
  731.                 XmlNodeRef xml = GetISystem()->CreateXmlNode("Case");
  732.  
  733.                 if (node)
  734.                 {
  735.                         xml->setAttr("condition", m_conditionString);
  736.                         xml->addChild(node->CreateXmlDescription());
  737.                 }
  738.  
  739.                 return xml;
  740.         }
  741. #endif
  742.  
  743. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  744.         void Serialize(Serialization::IArchive& archive)
  745.         {
  746.                 archive(m_conditionString, "condition", "^Condition");
  747.                 if (m_conditionString.empty())
  748.                         archive.error(m_conditionString, "Condition must be specified");
  749.  
  750.                 archive(node, "node", "+<>" NODE_COMBOBOX_FIXED_WIDTH ">");
  751.                 if (!node)
  752.                         archive.error(node, "Node must be specified");
  753.         }
  754. #endif
  755.  
  756. #ifdef USING_BEHAVIOR_TREE_EDITOR
  757.         string m_conditionString;
  758. #endif
  759.  
  760.         Variables::Expression condition;
  761.         INodePtr              node;
  762. };
  763.  
  764. class Priority : public Node
  765. {
  766.         typedef Node BaseClass;
  767.  
  768. private:
  769.         typedef std::vector<Case> Cases;
  770.         Cases m_cases;
  771.  
  772. public:
  773.         typedef uint8 CaseIndexType;
  774.  
  775.         struct RuntimeData
  776.         {
  777.                 CaseIndexType currentCaseIndex;
  778.  
  779.                 RuntimeData()
  780.                         : currentCaseIndex(0)
  781.                 {
  782.                 }
  783.         };
  784.  
  785.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  786.         {
  787.                 IF_UNLIKELY (BaseClass::LoadFromXml(xml, context) == LoadFailure)
  788.                         return LoadFailure;
  789.  
  790.                 const int childCount = xml->getChildCount();
  791.                 IF_UNLIKELY (childCount < 1)
  792.                 {
  793.                         ErrorReporter(*this, context).LogError("A priority node must have at least one case childs.");
  794.                         return LoadFailure;
  795.                 }
  796.  
  797.                 const size_t maxChildCount = std::numeric_limits<CaseIndexType>::max();
  798.                 IF_UNLIKELY ((size_t)childCount >= maxChildCount)
  799.                 {
  800.                         ErrorReporter(*this, context).LogError("Max %d children allowed.", maxChildCount);
  801.                         return LoadFailure;
  802.                 }
  803.  
  804.                 const int defaultChildIndex = childCount - 1;
  805.                 for (int i = 0; i < childCount; ++i)
  806.                 {
  807.                         Case priorityCase;
  808.                         XmlNodeRef caseXml = xml->getChild(i);
  809.  
  810.                         IF_UNLIKELY (priorityCase.LoadFromXml(caseXml, context) == LoadFailure)
  811.                         {
  812.                                 ErrorReporter(*this, context).LogError("Failed to load Case.");
  813.                                 return LoadFailure;
  814.                         }
  815.  
  816.                         m_cases.push_back(priorityCase);
  817.                 }
  818.  
  819.                 return LoadSuccess;
  820.         }
  821.  
  822. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  823.         virtual XmlNodeRef CreateXmlDescription() override
  824.         {
  825.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  826.  
  827.                 xml->setTag("Priority");
  828.  
  829.                 for (Cases::iterator caseIt = m_cases.begin(), end = m_cases.end(); caseIt != end; ++caseIt)
  830.                         xml->addChild(caseIt->CreateXmlDescription());
  831.  
  832.                 return xml;
  833.         }
  834. #endif
  835.  
  836. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  837.         virtual void Serialize(Serialization::IArchive& archive) override
  838.         {
  839.                 archive(m_cases, "cases", "^[<>]");
  840.  
  841.                 if (m_cases.empty())
  842.                         archive.error(m_cases, "Must contain a case");
  843.  
  844.                 if (m_cases.size() == 1)
  845.                         archive.warning(m_cases, "Priority with only one case is superfluous");
  846.  
  847.                 BaseClass::Serialize(archive);
  848.         }
  849. #endif
  850.  
  851. protected:
  852.         virtual void OnInitialize(const UpdateContext& context) override
  853.         {
  854.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  855.  
  856.                 // Set the current child index to be out of bounds to
  857.                 // force a re-evaluation.
  858.                 runtimeData.currentCaseIndex = static_cast<CaseIndexType>(m_cases.size());
  859.         }
  860.  
  861.         virtual void OnTerminate(const UpdateContext& context) override
  862.         {
  863.                 CaseIndexType& currentChildIndex = GetRuntimeData<RuntimeData>(context).currentCaseIndex;
  864.  
  865.                 if (currentChildIndex < m_cases.size())
  866.                 {
  867.                         m_cases[currentChildIndex].node->Terminate(context);
  868.                         currentChildIndex = static_cast<CaseIndexType>(m_cases.size());
  869.                 }
  870.         }
  871.  
  872.         virtual Status Update(const UpdateContext& context) override
  873.         {
  874.                 FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  875.  
  876.                 CaseIndexType& currentChildIndex = GetRuntimeData<RuntimeData>(context).currentCaseIndex;
  877.  
  878.                 if (context.variables.VariablesChangedSinceLastTick() || currentChildIndex >= m_cases.size())
  879.                 {
  880.                         CaseIndexType selectedChild = PickFirstChildWithSatisfiedCondition(context.variables.collection);
  881.                         if (selectedChild != currentChildIndex)
  882.                         {
  883.                                 if (currentChildIndex < m_cases.size())
  884.                                         m_cases[currentChildIndex].node->Terminate(context);
  885.  
  886.                                 currentChildIndex = selectedChild;
  887.                         }
  888.                 }
  889.  
  890.                 IF_UNLIKELY (currentChildIndex >= m_cases.size())
  891.                         return Failure;
  892.  
  893.                 return m_cases[currentChildIndex].node->Tick(context);
  894.         }
  895.  
  896. private:
  897.         virtual void HandleEvent(const EventContext& context, const Event& event) override
  898.         {
  899.                 const CaseIndexType& i = GetRuntimeData<RuntimeData>(context).currentCaseIndex;
  900.  
  901.                 if (i < m_cases.size())
  902.                         m_cases[i].node->SendEvent(context, event);
  903.         }
  904.  
  905.         CaseIndexType PickFirstChildWithSatisfiedCondition(Variables::Collection& variables)
  906.         {
  907.                 for (Cases::iterator caseIt = m_cases.begin(), end = m_cases.end(); caseIt != end; ++caseIt)
  908.                 {
  909.                         if (caseIt->condition.Evaluate(variables))
  910.                         {
  911.                                 return (CaseIndexType)std::distance(m_cases.begin(), caseIt);
  912.                         }
  913.                 }
  914.  
  915.                 return static_cast<CaseIndexType>(m_cases.size());
  916.         }
  917. };
  918.  
  919. //////////////////////////////////////////////////////////////////////////
  920.  
  921. #if defined(DEBUG_MODULAR_BEHAVIOR_TREE) || defined(USING_BEHAVIOR_TREE_EDITOR)
  922.         #define STORE_INFORMATION_FOR_STATE_MACHINE_NODE
  923. #endif
  924.  
  925. typedef byte StateIndex;
  926. static const StateIndex StateIndexInvalid = ((StateIndex) ~0);
  927.  
  928. struct Transition
  929. {
  930.         LoadResult LoadFromXml(const XmlNodeRef& transitionXml)
  931.         {
  932.                 destinationStateCRC32 = 0;
  933.                 destinationStateIndex = StateIndexInvalid;
  934. #ifdef STORE_INFORMATION_FOR_STATE_MACHINE_NODE
  935.                 xmlLine = transitionXml->getLine();
  936. #endif
  937.  
  938.                 string to = transitionXml->getAttr("to");
  939.                 if (to.empty())
  940.                 {
  941.                         gEnv->pLog->LogError("Transition is missing 'to' attribute.");
  942.                         return LoadFailure;
  943.                 }
  944.  
  945.                 destinationStateCRC32 = CCrc32::ComputeLowercase(to);
  946.  
  947. #ifdef STORE_INFORMATION_FOR_STATE_MACHINE_NODE
  948.                 destinationStateName = to;
  949. #endif
  950.  
  951.                 string onEvent = transitionXml->getAttr("onEvent");
  952.                 if (onEvent.empty())
  953.                 {
  954.                         gEnv->pLog->LogError("Transition is missing 'onEvent' attribute.");
  955.                         return LoadFailure;
  956.                 }
  957.  
  958.                 triggerEvent = Event(onEvent);
  959.  
  960. #ifdef STORE_INFORMATION_FOR_STATE_MACHINE_NODE
  961.                 triggerEventName = onEvent;
  962. #endif
  963.  
  964.                 return LoadSuccess;
  965.         }
  966.  
  967. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  968.         XmlNodeRef CreateXmlDescription() const
  969.         {
  970.                 XmlNodeRef xml = GetISystem()->CreateXmlNode("Transition");
  971.                 xml->setAttr("to", destinationStateName);
  972.                 xml->setAttr("onEvent", triggerEventName);
  973.                 return xml;
  974.         }
  975. #endif
  976.  
  977. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  978.         void Serialize(Serialization::IArchive& archive)
  979.         {
  980.                 archive(triggerEventName, "triggerEventName", "^>" STATE_TRANSITION_EVENT_FIXED_WIDTH ">Trigger event");
  981.                 if (triggerEventName.empty())
  982.                         archive.error(triggerEventName, "Must specify a trigger event");
  983.  
  984.                 archive(destinationStateName, "destinationState", "^Destination state");
  985.                 if (destinationStateName.empty())
  986.                         archive.error(destinationStateName, "Must specify a destination state");
  987.         }
  988. #endif
  989.  
  990. #ifdef STORE_INFORMATION_FOR_STATE_MACHINE_NODE
  991.         string destinationStateName;
  992.         string triggerEventName;
  993.         int    xmlLine;
  994. #endif
  995.  
  996.         uint32     destinationStateCRC32;
  997.         Event      triggerEvent;
  998.         StateIndex destinationStateIndex;
  999. };
  1000.  
  1001. typedef std::vector<Transition> Transitions;
  1002.  
  1003. struct State
  1004. {
  1005.         State()
  1006.                 : transitions()
  1007.                 , nameCRC32(0)
  1008. #ifdef STORE_INFORMATION_FOR_STATE_MACHINE_NODE
  1009.                 , name()
  1010. #endif
  1011. #ifdef DEBUG_MODULAR_BEHAVIOR_TREE
  1012.                 , xmlLine(0)
  1013. #endif
  1014.                 , node()
  1015.         {
  1016.         }
  1017.  
  1018.         LoadResult LoadFromXml(const XmlNodeRef& stateXml, const LoadContext& context)
  1019.         {
  1020.                 if (!stateXml->isTag("State"))
  1021.                 {
  1022.                         gEnv->pLog->LogError("StateMachine node must contain child nodes of the type 'State', and there is a child of the '%s' at line '%d'.", stateXml->getTag(), stateXml->getLine());
  1023.                         return LoadFailure;
  1024.                 }
  1025.  
  1026.                 const char* stateName;
  1027.                 if (stateXml->getAttr("name", &stateName))
  1028.                 {
  1029.                         nameCRC32 = CCrc32::ComputeLowercase(stateName);
  1030.  
  1031. #ifdef STORE_INFORMATION_FOR_STATE_MACHINE_NODE
  1032.                         name = stateName;
  1033. #endif
  1034.  
  1035. #ifdef DEBUG_MODULAR_BEHAVIOR_TREE
  1036.                         xmlLine = stateXml->getLine();
  1037. #endif  // DEBUG_MODULAR_BEHAVIOR_TREE
  1038.  
  1039.                 }
  1040.                 else
  1041.                 {
  1042.                         gEnv->pLog->LogError("A state node must contain a valid 'name' attribute. The state node at the line %d does not.", stateXml->getLine());
  1043.                         return LoadFailure;
  1044.                 }
  1045.  
  1046.                 const XmlNodeRef transitionsXml = stateXml->findChild("Transitions");
  1047.                 if (transitionsXml)
  1048.                 {
  1049.                         for (int i = 0; i < transitionsXml->getChildCount(); ++i)
  1050.                         {
  1051.                                 Transition transition;
  1052.                                 if (transition.LoadFromXml(transitionsXml->getChild(i)) == LoadFailure)
  1053.                                 {
  1054.                                         gEnv->pLog->LogError("Failed to load transition.");
  1055.                                         return LoadFailure;
  1056.                                 }
  1057.  
  1058.                                 transitions.push_back(transition);
  1059.                         }
  1060.                 }
  1061.  
  1062.                 const XmlNodeRef behaviorTreeXml = stateXml->findChild("BehaviorTree");
  1063.                 if (!behaviorTreeXml)
  1064.                 {
  1065. #ifdef STORE_INFORMATION_FOR_STATE_MACHINE_NODE
  1066.                         gEnv->pLog->LogError("A state node must contain a 'BehaviorTree' child. The state node '%s' at %d does not.", name.c_str(), stateXml->getLine());
  1067. #else
  1068.                         gEnv->pLog->LogError("A state node must contain a 'BehaviorTree' child. The state node at the line %d does not.", stateXml->getLine());
  1069. #endif
  1070.                         return LoadFailure;
  1071.                 }
  1072.  
  1073.                 if (behaviorTreeXml->getChildCount() != 1)
  1074.                 {
  1075.                         gEnv->pLog->LogError("A state node must contain a 'BehaviorTree' child, which in turn must have exactly one child.");
  1076.                         return LoadFailure;
  1077.                 }
  1078.  
  1079.                 node = context.nodeFactory.CreateNodeFromXml(behaviorTreeXml->getChild(0), context);
  1080.                 if (!node)
  1081.                 {
  1082.                         gEnv->pLog->LogError("State failed to load child.");
  1083.                         return LoadFailure;
  1084.                 }
  1085.  
  1086.                 return LoadSuccess;
  1087.         }
  1088.  
  1089. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  1090.         XmlNodeRef CreateXmlDescription()
  1091.         {
  1092.                 XmlNodeRef stateXml = GetISystem()->CreateXmlNode("State");
  1093.  
  1094.                 stateXml->setAttr("name", name);
  1095.  
  1096.                 if (transitions.size() > 0)
  1097.                 {
  1098.                         XmlNodeRef transitionXml = GetISystem()->CreateXmlNode("Transitions");
  1099.                         for (Transitions::iterator transitionIt = transitions.begin(), end = transitions.end(); transitionIt != end; ++transitionIt)
  1100.                                 transitionXml->addChild(transitionIt->CreateXmlDescription());
  1101.  
  1102.                         stateXml->addChild(transitionXml);
  1103.                 }
  1104.  
  1105.                 if (node)
  1106.                 {
  1107.                         XmlNodeRef behaviorXml = GetISystem()->CreateXmlNode("BehaviorTree");
  1108.                         behaviorXml->addChild(node->CreateXmlDescription());
  1109.                         stateXml->addChild(behaviorXml);
  1110.                 }
  1111.  
  1112.                 return stateXml;
  1113.         }
  1114. #endif
  1115.  
  1116. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  1117.         void Serialize(Serialization::IArchive& archive)
  1118.         {
  1119.         #ifdef DEBUG_MODULAR_BEHAVIOR_TREE
  1120.                 HandleXmlLineNumberSerialization(archive, xmlLine);
  1121.         #endif
  1122.  
  1123.                 archive(name, "name", "^State Name");
  1124.                 if (name.empty())
  1125.                         archive.error(name, "State name must be specified");
  1126.  
  1127.                 archive(transitions, "transitions", "+[<>]Transitions");
  1128.  
  1129.                 archive(node, "node", "+<>" NODE_COMBOBOX_FIXED_WIDTH ">");
  1130.                 if (!node)
  1131.                         archive.error(node, "Node must be specified");
  1132.         }
  1133. #endif
  1134.  
  1135.         const Transition* GetTransitionForEvent(const Event& event)
  1136.         {
  1137.                 Transitions::iterator it = transitions.begin();
  1138.                 Transitions::iterator end = transitions.end();
  1139.  
  1140.                 for (; it != end; ++it)
  1141.                 {
  1142.                         const Transition& transition = *it;
  1143.                         if (transition.triggerEvent == event)
  1144.                                 return &transition;
  1145.                 }
  1146.  
  1147.                 return NULL;
  1148.         }
  1149.  
  1150.         Transitions transitions;
  1151.         uint32      nameCRC32;
  1152.  
  1153. #ifdef STORE_INFORMATION_FOR_STATE_MACHINE_NODE
  1154.         string name;
  1155. #endif
  1156.  
  1157. #ifdef DEBUG_MODULAR_BEHAVIOR_TREE
  1158.         uint32 xmlLine;
  1159. #endif
  1160.  
  1161.         INodePtr node;
  1162. };
  1163.  
  1164. // A state machine is a composite node that holds one or more children.
  1165. // There is one selected child at any given time. Default is the first.
  1166. //
  1167. // A state machine's status is the same as that of it's currently
  1168. // selected child: running, succeeded or failed.
  1169. //
  1170. // One state can transition to another state on a specified event.
  1171. // The transition happens immediately in the sense of selection,
  1172. // but the new state is only updated the next time the state machine
  1173. // itself is being updated.
  1174. //
  1175. // Transitioning to the same state will cause the state to first be
  1176. // terminated and then initialized and updated.
  1177. class StateMachine : public Node
  1178. {
  1179.         typedef Node BaseClass;
  1180.  
  1181. public:
  1182.         typedef uint8 StateIndexType;
  1183.  
  1184.         struct RuntimeData
  1185.         {
  1186.                 StateIndexType currentStateIndex;
  1187.                 StateIndexType pendingStateIndex;
  1188.                 bool           transitionIsPending;
  1189.  
  1190.                 RuntimeData()
  1191.                         : currentStateIndex(0)
  1192.                         , pendingStateIndex(0)
  1193.                         , transitionIsPending(false)
  1194.                 {
  1195.                 }
  1196.         };
  1197.  
  1198.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  1199.         {
  1200.                 const size_t maxChildCount = std::numeric_limits<StateIndexType>::max();
  1201.  
  1202.                 IF_UNLIKELY ((size_t)xml->getChildCount() >= maxChildCount)
  1203.                 {
  1204.                         ErrorReporter(*this, context).LogError("Too many children. Max %d allowed.", maxChildCount);
  1205.                         return LoadFailure;
  1206.                 }
  1207.  
  1208.                 IF_UNLIKELY (xml->getChildCount() <= 0)
  1209.                 {
  1210.                         ErrorReporter(*this, context).LogError("A state machine node must contain at least one child state node.");
  1211.                         return LoadFailure;
  1212.                 }
  1213.  
  1214.                 for (int i = 0; i < xml->getChildCount(); ++i)
  1215.                 {
  1216.                         State state;
  1217.                         XmlNodeRef stateXml = xml->getChild(i);
  1218.  
  1219.                         if (state.LoadFromXml(stateXml, context) == LoadFailure)
  1220.                         {
  1221.                                 ErrorReporter(*this, context).LogError("Failed to load State.");
  1222.                                 return LoadFailure;
  1223.                         }
  1224.  
  1225.                         m_states.push_back(state);
  1226.                 }
  1227.  
  1228.                 return LinkAllTransitions();
  1229.         }
  1230.  
  1231. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  1232.         virtual XmlNodeRef CreateXmlDescription() override
  1233.         {
  1234.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  1235.  
  1236.                 xml->setTag("StateMachine");
  1237.  
  1238.                 for (States::iterator stateIt = m_states.begin(), end = m_states.end(); stateIt != end; ++stateIt)
  1239.                         xml->addChild(stateIt->CreateXmlDescription());
  1240.  
  1241.                 return xml;
  1242.         }
  1243. #endif
  1244.  
  1245. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  1246.         virtual void Serialize(Serialization::IArchive& archive) override
  1247.         {
  1248.                 archive(m_states, "states", "^[+<>]States");
  1249.  
  1250.                 if (m_states.empty())
  1251.                         archive.error(m_states, "Must contain a state.");
  1252.  
  1253.                 if (m_states.size() == 1)
  1254.                         archive.warning(m_states, "State machine with only one state is superfluous");
  1255.  
  1256.                 BaseClass::Serialize(archive);
  1257.         }
  1258. #endif
  1259.  
  1260. #if defined(STORE_INFORMATION_FOR_STATE_MACHINE_NODE) && defined(USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT)
  1261.         virtual void GetCustomDebugText(const UpdateContext& updateContext, stack_string& debugText) const
  1262.         {
  1263.                 const RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(updateContext);
  1264.                 if (runtimeData.currentStateIndex < m_states.size())
  1265.                         debugText += m_states[runtimeData.currentStateIndex].name.c_str();
  1266.         }
  1267. #endif
  1268.  
  1269. protected:
  1270.         virtual void OnInitialize(const UpdateContext& context) override
  1271.         {
  1272.                 assert(m_states.size() > 0);
  1273.  
  1274.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1275.                 runtimeData.currentStateIndex = 0;
  1276.                 runtimeData.pendingStateIndex = 0;
  1277.                 runtimeData.transitionIsPending = false;
  1278.         }
  1279.  
  1280.         virtual void OnTerminate(const UpdateContext& context) override
  1281.         {
  1282.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1283.  
  1284.                 if (runtimeData.currentStateIndex < m_states.size())
  1285.                         m_states[runtimeData.currentStateIndex].node->Terminate(context);
  1286.         }
  1287.  
  1288.         virtual Status Update(const UpdateContext& context) override
  1289.         {
  1290.                 FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  1291.  
  1292.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1293.  
  1294.                 if (runtimeData.transitionIsPending)
  1295.                 {
  1296.                         runtimeData.transitionIsPending = false;
  1297.                         m_states[runtimeData.currentStateIndex].node->Terminate(context);
  1298.                         runtimeData.currentStateIndex = runtimeData.pendingStateIndex;
  1299.                 }
  1300.  
  1301.                 return m_states[runtimeData.currentStateIndex].node->Tick(context);
  1302.         }
  1303.  
  1304. private:
  1305.         virtual void HandleEvent(const EventContext& context, const Event& event) override
  1306.         {
  1307.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1308.  
  1309.                 StateIndexType& pendingStateIndex = runtimeData.pendingStateIndex;
  1310.  
  1311.                 if (pendingStateIndex >= m_states.size())
  1312.                         return;
  1313.  
  1314.                 const Transition* transition = m_states[pendingStateIndex].GetTransitionForEvent(event);
  1315.                 if (transition)
  1316.                 {
  1317.                         assert(transition->destinationStateIndex != StateIndexInvalid);
  1318.                         pendingStateIndex = transition->destinationStateIndex;
  1319.                         runtimeData.transitionIsPending = true;
  1320.                 }
  1321.  
  1322.                 m_states[runtimeData.currentStateIndex].node->SendEvent(context, event);
  1323.         }
  1324.  
  1325.         LoadResult LinkAllTransitions()
  1326.         {
  1327.                 for (States::iterator stateIt = m_states.begin(), end = m_states.end(); stateIt != end; ++stateIt)
  1328.                 {
  1329.                         State& state = *stateIt;
  1330.  
  1331.                         for (Transitions::iterator transitionIt = state.transitions.begin(), end = state.transitions.end(); transitionIt != end; ++transitionIt)
  1332.                         {
  1333.                                 Transition& transition = *transitionIt;
  1334.  
  1335.                                 StateIndex stateIndex = GetIndexOfState(transition.destinationStateCRC32);
  1336.                                 if (stateIndex == StateIndexInvalid)
  1337.                                 {
  1338. #ifdef STORE_INFORMATION_FOR_STATE_MACHINE_NODE
  1339.                                         gEnv->pLog->LogError("Cannot transition to unknown state '%s' at line %d.", transition.destinationStateName, transition.xmlLine);
  1340. #endif
  1341.                                         return LoadFailure;
  1342.                                 }
  1343.  
  1344.                                 transition.destinationStateIndex = stateIndex;
  1345.                         }
  1346.                 }
  1347.  
  1348.                 return LoadSuccess;
  1349.         }
  1350.  
  1351.         StateIndex GetIndexOfState(uint32 stateNameLowerCaseCRC32)
  1352.         {
  1353.                 size_t index, size = m_states.size();
  1354.                 assert(size < ((1 << (sizeof(StateIndex) * 8)) - 1));               // -1 because StateIndexInvalid is reserved.
  1355.                 for (index = 0; index < size; index++)
  1356.                 {
  1357.                         if (m_states[index].nameCRC32 == stateNameLowerCaseCRC32)
  1358.                                 return static_cast<StateIndex>(index);
  1359.                 }
  1360.  
  1361.                 return StateIndexInvalid;
  1362.         }
  1363.  
  1364.         typedef std::vector<State> States;
  1365.         States m_states;
  1366. };
  1367.  
  1368. //////////////////////////////////////////////////////////////////////////
  1369.  
  1370. // Send an event to this behavior tree. In reality, the event will be
  1371. // queued and dispatched at a later time, often the next frame.
  1372. class SendEvent : public Action
  1373. {
  1374.         typedef Action BaseClass;
  1375.  
  1376. public:
  1377.         struct RuntimeData
  1378.         {
  1379.         };
  1380.  
  1381.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  1382.         {
  1383.                 IF_UNLIKELY (BaseClass::LoadFromXml(xml, context) == LoadFailure)
  1384.                         return LoadFailure;
  1385.  
  1386.                 const stack_string eventName = xml->getAttr("name");
  1387.                 IF_UNLIKELY (eventName.empty())
  1388.                 {
  1389.                         ErrorReporter(*this, context).LogError("Could not find the 'name' attribute.");
  1390.                         return LoadFailure;
  1391.                 }
  1392.  
  1393.                 m_eventToSend = Event(eventName);
  1394.  
  1395.                 return LoadSuccess;
  1396.         }
  1397.  
  1398. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  1399.         virtual XmlNodeRef CreateXmlDescription() override
  1400.         {
  1401.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  1402.                 xml->setTag("SendEvent");
  1403.                 xml->setAttr("name", m_eventToSend.GetName());
  1404.                 return xml;
  1405.         }
  1406. #endif
  1407.  
  1408. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  1409.         virtual void Serialize(Serialization::IArchive& archive) override
  1410.         {
  1411.                 archive(m_eventToSend, "event", "^");
  1412.                 if (strlen(m_eventToSend.GetName()) == 0)
  1413.                         archive.error(m_eventToSend, "Event must be specified");
  1414.                 BaseClass::Serialize(archive);
  1415.         }
  1416. #endif
  1417.  
  1418. protected:
  1419.         virtual void OnInitialize(const UpdateContext& context) override
  1420.         {
  1421.                 gAIEnv.pBehaviorTreeManager->HandleEvent(context.entityId, m_eventToSend);
  1422.         }
  1423.  
  1424.         virtual Status Update(const UpdateContext& context) override
  1425.         {
  1426.                 return Success;
  1427.         }
  1428.  
  1429. private:
  1430.         Event m_eventToSend;
  1431. };
  1432.  
  1433. //////////////////////////////////////////////////////////////////////////
  1434.  
  1435. // Same as SendEvent with the exception that this node never finishes.
  1436. // Usually used for transitions in state machines etc.
  1437. class SendTransitionEvent : public SendEvent
  1438. {
  1439.         typedef SendEvent BaseClass;
  1440.  
  1441. public:
  1442.         virtual Status Update(const UpdateContext& context) override
  1443.         {
  1444.                 return Running;
  1445.         }
  1446.  
  1447. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  1448.         virtual XmlNodeRef CreateXmlDescription() override
  1449.         {
  1450.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  1451.                 xml->setTag("SendTransitionEvent");
  1452.                 return xml;
  1453.         }
  1454. #endif
  1455.  
  1456. };
  1457.  
  1458. //////////////////////////////////////////////////////////////////////////
  1459.  
  1460. #if defined(USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT) || defined(USING_BEHAVIOR_TREE_EDITOR)
  1461.         #define STORE_CONDITION_STRING
  1462. #endif
  1463.  
  1464. class IfCondition : public Decorator
  1465. {
  1466. public:
  1467.         typedef Decorator BaseClass;
  1468.  
  1469.         struct RuntimeData
  1470.         {
  1471.                 bool gateIsOpen;
  1472.  
  1473.                 RuntimeData()
  1474.                         : gateIsOpen(false)
  1475.                 {
  1476.                 }
  1477.         };
  1478.  
  1479.         IfCondition()
  1480.                 : m_valueToCheck(false)
  1481.         {
  1482.         }
  1483.  
  1484.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  1485.         {
  1486.                 const stack_string conditionString = xml->getAttr("condition");
  1487.                 if (conditionString.empty())
  1488.                 {
  1489.                         ErrorReporter(*this, context).LogError("Attribute 'condition' is missing or empty.");
  1490.                         return LoadFailure;
  1491.                 }
  1492.  
  1493. #ifdef STORE_CONDITION_STRING
  1494.                 m_conditionString = conditionString.c_str();
  1495. #endif
  1496.  
  1497.                 m_valueToCheck = true;
  1498.                 if (xml->getAttr("equalTo", m_valueToCheck))
  1499.                 {
  1500.                         ErrorReporter(*this, context).LogWarning("Deprecated attribute 'equalTo' was used. Please change the expression.");
  1501.                 }
  1502.  
  1503.                 m_condition = Variables::Expression(conditionString, context.variableDeclarations);
  1504.                 if (!m_condition.Valid())
  1505.                 {
  1506.                         ErrorReporter(*this, context).LogError("Failed to parse condition '%s'.", conditionString.c_str());
  1507.                         return LoadFailure;
  1508.                 }
  1509.  
  1510.                 return LoadChildFromXml(xml, context);
  1511.         }
  1512.  
  1513. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  1514.         virtual XmlNodeRef CreateXmlDescription() override
  1515.         {
  1516.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  1517.                 xml->setTag("IfCondition");
  1518.                 xml->setAttr("condition", m_conditionString);
  1519.                 return xml;
  1520.         }
  1521. #endif
  1522.  
  1523. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  1524.         virtual void Serialize(Serialization::IArchive& archive) override
  1525.         {
  1526.                 archive(m_conditionString, "condition", "^Condition");
  1527.                 if (m_conditionString.empty())
  1528.                         archive.error(m_conditionString, "Condition must be specified");
  1529.  
  1530.                 BaseClass::Serialize(archive);
  1531.         }
  1532. #endif
  1533.  
  1534. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  1535.         virtual void GetCustomDebugText(const UpdateContext& updateContext, stack_string& debugText) const
  1536.         {
  1537.                 debugText.Format("(%s) == %s", m_conditionString.c_str(), m_valueToCheck ? "true" : "false");
  1538.         }
  1539. #endif
  1540.  
  1541. protected:
  1542.         virtual void OnInitialize(const UpdateContext& context) override
  1543.         {
  1544.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1545.  
  1546.                 runtimeData.gateIsOpen = false;
  1547.  
  1548.                 if (m_condition.Evaluate(context.variables.collection) == m_valueToCheck)
  1549.                 {
  1550.                         runtimeData.gateIsOpen = true;
  1551.                 }
  1552.         }
  1553.  
  1554.         virtual Status Update(const UpdateContext& context) override
  1555.         {
  1556.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1557.  
  1558.                 if (runtimeData.gateIsOpen)
  1559.                         return BaseClass::Update(context);
  1560.                 else
  1561.                         return Failure;
  1562.         }
  1563.  
  1564. private:
  1565. #ifdef STORE_CONDITION_STRING
  1566.         string m_conditionString;
  1567. #endif
  1568.         Variables::Expression m_condition;
  1569.         bool m_valueToCheck;
  1570. };
  1571.  
  1572. //////////////////////////////////////////////////////////////////////////
  1573.  
  1574. class AssertCondition : public Action
  1575. {
  1576.         typedef Action BaseClass;
  1577.  
  1578. public:
  1579.         struct RuntimeData
  1580.         {
  1581.         };
  1582.  
  1583.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  1584.         {
  1585.                 IF_UNLIKELY (BaseClass::LoadFromXml(xml, context) == LoadFailure)
  1586.                         return LoadFailure;
  1587.  
  1588.                 const stack_string conditionString = xml->getAttr("condition");
  1589.                 if (conditionString.empty())
  1590.                 {
  1591.                         ErrorReporter(*this, context).LogError("Missing or invalid 'condition' attribute.");
  1592.                         return LoadFailure;
  1593.                 }
  1594.  
  1595. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  1596.                 m_conditionString = conditionString.c_str();
  1597. #endif
  1598.  
  1599.                 m_condition = Variables::Expression(conditionString, context.variableDeclarations);
  1600.                 if (!m_condition.Valid())
  1601.                 {
  1602.                         ErrorReporter(*this, context).LogError("Failed to parse condition '%s'.", conditionString.c_str());
  1603.                         return LoadFailure;
  1604.                 }
  1605.  
  1606.                 return LoadSuccess;
  1607.         }
  1608.  
  1609. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  1610.         virtual XmlNodeRef CreateXmlDescription() override
  1611.         {
  1612.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  1613.                 xml->setTag("AssertCondition");
  1614.                 xml->setAttr("condition", m_conditionString);
  1615.                 return xml;
  1616.         }
  1617. #endif
  1618.  
  1619. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  1620.         virtual void Serialize(Serialization::IArchive& archive) override
  1621.         {
  1622.                 archive(m_conditionString, "condition", "^Condition");
  1623.                 if (m_conditionString.empty())
  1624.                         archive.error(m_conditionString, "Condition must be specified");
  1625.  
  1626.                 BaseClass::Serialize(archive);
  1627.         }
  1628. #endif
  1629.  
  1630. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  1631.         virtual void GetCustomDebugText(const UpdateContext& updateContext, stack_string& debugText) const
  1632.         {
  1633.                 debugText.Format("%s", m_conditionString.c_str());
  1634.         }
  1635. #endif
  1636.  
  1637. protected:
  1638.         virtual Status Update(const UpdateContext& context) override
  1639.         {
  1640.                 if (m_condition.Evaluate(context.variables.collection))
  1641.                 {
  1642.                         return Success;
  1643.                 }
  1644.  
  1645.                 return Failure;
  1646.         }
  1647.  
  1648. private:
  1649. #ifdef STORE_CONDITION_STRING
  1650.         string m_conditionString;
  1651. #endif
  1652.         Variables::Expression m_condition;
  1653. };
  1654.  
  1655. //////////////////////////////////////////////////////////////////////////
  1656.  
  1657. class MonitorCondition : public Action
  1658. {
  1659.         typedef Action BaseClass;
  1660.  
  1661. public:
  1662.         struct RuntimeData
  1663.         {
  1664.         };
  1665.  
  1666.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  1667.         {
  1668.                 IF_UNLIKELY (BaseClass::LoadFromXml(xml, context) == LoadFailure)
  1669.                         return LoadFailure;
  1670.  
  1671.                 const stack_string conditionString = xml->getAttr("condition");
  1672.                 if (conditionString.empty())
  1673.                 {
  1674.                         ErrorReporter(*this, context).LogError("Expected 'condition' attribute.");
  1675.                         return LoadFailure;
  1676.                 }
  1677.  
  1678.                 m_condition = Variables::Expression(conditionString, context.variableDeclarations);
  1679.                 IF_UNLIKELY (!m_condition.Valid())
  1680.                 {
  1681.                         ErrorReporter(*this, context).LogError("Couldn't get behavior variables.");
  1682.                         return LoadFailure;
  1683.                 }
  1684.  
  1685. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  1686.                 m_conditionString = conditionString.c_str();
  1687. #endif
  1688.  
  1689.                 return LoadSuccess;
  1690.         }
  1691.  
  1692. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  1693.         virtual void GetCustomDebugText(const UpdateContext& updateContext, stack_string& debugText) const override
  1694.         {
  1695.                 debugText.Format("(%s)", m_conditionString.c_str());
  1696.         }
  1697. #endif
  1698.  
  1699.         virtual Status Update(const UpdateContext& context) override
  1700.         {
  1701.                 FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  1702.  
  1703.                 if (m_condition.Evaluate(context.variables.collection))
  1704.                 {
  1705.                         return Success;
  1706.                 }
  1707.  
  1708.                 return Running;
  1709.         }
  1710.  
  1711. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  1712.         virtual XmlNodeRef CreateXmlDescription() override
  1713.         {
  1714.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  1715.                 xml->setTag("MonitorCondition");
  1716.                 xml->setAttr("condition", m_conditionString);
  1717.                 return xml;
  1718.         }
  1719. #endif
  1720.  
  1721. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  1722.         virtual void Serialize(Serialization::IArchive& archive) override
  1723.         {
  1724.                 archive(m_conditionString, "condition", "^Condition");
  1725.                 if (m_conditionString.empty())
  1726.                         archive.error(m_conditionString, "Condition must be specified");
  1727.  
  1728.                 BaseClass::Serialize(archive);
  1729.         }
  1730. #endif
  1731.  
  1732. private:
  1733. #ifdef STORE_CONDITION_STRING
  1734.         string m_conditionString;
  1735. #endif
  1736.         Variables::Expression m_condition;
  1737. };
  1738.  
  1739. //////////////////////////////////////////////////////////////////////////
  1740.  
  1741. // A gate that opens in relation of the defined random chance
  1742. //
  1743.  
  1744. class RandomGate : public Decorator
  1745. {
  1746. public:
  1747.         typedef Decorator BaseClass;
  1748.  
  1749.         struct RuntimeData
  1750.         {
  1751.                 bool gateIsOpen;
  1752.  
  1753.                 RuntimeData()
  1754.                         : gateIsOpen(false)
  1755.                 {
  1756.                 }
  1757.         };
  1758.  
  1759.         RandomGate()
  1760.                 : m_opensWithChance(.0f)
  1761.         {
  1762.         }
  1763.  
  1764.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  1765.         {
  1766.                 if (!xml->getAttr("opensWithChance", m_opensWithChance))
  1767.                 {
  1768.                         gEnv->pLog->LogError("RandomGate expected the 'opensWithChance' attribute at line %d.", xml->getLine());
  1769.                         return LoadFailure;
  1770.                 }
  1771.  
  1772.                 m_opensWithChance = clamp_tpl(m_opensWithChance, .0f, 1.0f);
  1773.  
  1774.                 return LoadChildFromXml(xml, context);
  1775.         }
  1776.  
  1777. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  1778.         virtual XmlNodeRef CreateXmlDescription() override
  1779.         {
  1780.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  1781.                 xml->setTag("RandomGate");
  1782.                 xml->setAttr("opensWithChance", m_opensWithChance);
  1783.                 return xml;
  1784.         }
  1785. #endif
  1786.  
  1787. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  1788.         virtual void Serialize(Serialization::IArchive& archive) override
  1789.         {
  1790.                 archive(m_opensWithChance, "opensWithChance", "^Chance to open");
  1791.                 BaseClass::Serialize(archive);
  1792.         }
  1793. #endif
  1794.  
  1795. protected:
  1796.         virtual void OnInitialize(const UpdateContext& context) override
  1797.         {
  1798.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1799.  
  1800.                 runtimeData.gateIsOpen = false;
  1801.  
  1802.                 const float randomValue = cry_random(0.0f, 1.0f);
  1803.                 if (randomValue <= m_opensWithChance)
  1804.                         runtimeData.gateIsOpen = true;
  1805.         }
  1806.  
  1807.         virtual Status Update(const UpdateContext& context) override
  1808.         {
  1809.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1810.  
  1811.                 if (runtimeData.gateIsOpen)
  1812.                         return BaseClass::Update(context);
  1813.                 else
  1814.                         return Failure;
  1815.         }
  1816.  
  1817. private:
  1818.         float m_opensWithChance;
  1819. };
  1820.  
  1821. //////////////////////////////////////////////////////////////////////////
  1822.  
  1823. // Returns failure after X seconds
  1824. class Timeout : public Action
  1825. {
  1826.         typedef Action BaseClass;
  1827.  
  1828. public:
  1829.         struct RuntimeData
  1830.         {
  1831.                 Timer timer;
  1832.         };
  1833.  
  1834.         Timeout()
  1835.                 : m_duration(0.0f)
  1836.         {
  1837.         }
  1838.  
  1839.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  1840.         {
  1841.                 if (Action::LoadFromXml(xml, context) == LoadFailure)
  1842.                 {
  1843.                         // TODO: Report error
  1844.                         return LoadFailure;
  1845.                 }
  1846.  
  1847.                 if (!xml->getAttr("duration", m_duration))
  1848.                 {
  1849.                         // TODO: Report error
  1850.                         return LoadFailure;
  1851.                 }
  1852.  
  1853.                 return LoadSuccess;
  1854.         }
  1855.  
  1856. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  1857.         virtual XmlNodeRef CreateXmlDescription() override
  1858.         {
  1859.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  1860.                 xml->setTag("Timeout");
  1861.                 xml->setAttr("duration", m_duration);
  1862.                 return xml;
  1863.         }
  1864. #endif
  1865.  
  1866. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  1867.         virtual void Serialize(Serialization::IArchive& archive) override
  1868.         {
  1869.                 archive(m_duration, "duration", "^Duration");
  1870.                 BaseClass::Serialize(archive);
  1871.         }
  1872. #endif
  1873.  
  1874.         virtual void OnInitialize(const UpdateContext& context) override
  1875.         {
  1876.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1877.                 runtimeData.timer.Reset(m_duration);
  1878.         }
  1879.  
  1880.         virtual Status Update(const UpdateContext& context) override
  1881.         {
  1882.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1883.                 return runtimeData.timer.Elapsed() ? Failure : Running;
  1884.         }
  1885.  
  1886. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  1887.         virtual void GetCustomDebugText(const UpdateContext& updateContext, stack_string& debugText) const
  1888.         {
  1889.                 const RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(updateContext);
  1890.                 debugText.Format("%0.1f (%0.1f)", runtimeData.timer.GetSecondsLeft(), m_duration);
  1891.         }
  1892. #endif
  1893.  
  1894. private:
  1895.         float m_duration;
  1896. };
  1897.  
  1898. //////////////////////////////////////////////////////////////////////////
  1899.  
  1900. // Returns success after X seconds
  1901. class Wait : public Action
  1902. {
  1903.         typedef Action BaseClass;
  1904.  
  1905. public:
  1906.         struct RuntimeData
  1907.         {
  1908.                 Timer timer;
  1909.         };
  1910.  
  1911.         Wait()
  1912.                 : m_duration(0.0f)
  1913.                 , m_variation(0.0f)
  1914.         {
  1915.         }
  1916.  
  1917.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context)
  1918.         {
  1919.                 if (Action::LoadFromXml(xml, context) == LoadFailure)
  1920.                 {
  1921.                         // TODO: Report error
  1922.                         return LoadFailure;
  1923.                 }
  1924.  
  1925.                 if (!xml->getAttr("duration", m_duration))
  1926.                 {
  1927.                         // TODO: Report error
  1928.                         return LoadFailure;
  1929.                 }
  1930.  
  1931.                 xml->getAttr("variation", m_variation);
  1932.  
  1933.                 return LoadSuccess;
  1934.         }
  1935.  
  1936. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  1937.         virtual XmlNodeRef CreateXmlDescription() override
  1938.         {
  1939.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  1940.                 xml->setTag("Wait");
  1941.                 xml->setAttr("duration", m_duration);
  1942.                 xml->setAttr("variation", m_variation);
  1943.                 return xml;
  1944.         }
  1945. #endif
  1946.  
  1947. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  1948.         virtual void Serialize(Serialization::IArchive& archive) override
  1949.         {
  1950.                 archive(m_duration, "duration", "^<Duration");
  1951.                 archive(m_variation, "variation", "^<Variation");
  1952.                 BaseClass::Serialize(archive);
  1953.         }
  1954. #endif
  1955.  
  1956.         virtual void OnInitialize(const UpdateContext& context)
  1957.         {
  1958.                 if (m_duration >= 0.0f)
  1959.                 {
  1960.                         RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1961.                         runtimeData.timer.Reset(m_duration, m_variation);
  1962.                 }
  1963.         }
  1964.  
  1965.         virtual Status Update(const UpdateContext& context)
  1966.         {
  1967.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  1968.                 return runtimeData.timer.Elapsed() ? Success : Running;
  1969.         }
  1970.  
  1971. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  1972.         virtual void GetCustomDebugText(const UpdateContext& updateContext, stack_string& debugText) const
  1973.         {
  1974.                 const RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(updateContext);
  1975.                 debugText.Format("%0.1f (%0.1f)", runtimeData.timer.GetSecondsLeft(), m_duration);
  1976.         }
  1977. #endif
  1978.  
  1979. private:
  1980.         float m_duration;
  1981.         float m_variation;
  1982. };
  1983.  
  1984. //////////////////////////////////////////////////////////////////////////
  1985.  
  1986. // Wait for a specified behavior tree event and then succeed or fail
  1987. // depending how the node is configured.
  1988. class WaitForEvent : public Action
  1989. {
  1990.         typedef Action BaseClass;
  1991.  
  1992. public:
  1993.         struct RuntimeData
  1994.         {
  1995.                 bool eventReceieved;
  1996.  
  1997.                 RuntimeData()
  1998.                         : eventReceieved(false)
  1999.                 {
  2000.                 }
  2001.         };
  2002.  
  2003.         WaitForEvent()
  2004.                 : m_statusToReturn(Success)
  2005.         {
  2006.         }
  2007.  
  2008.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  2009.         {
  2010.                 IF_UNLIKELY (BaseClass::LoadFromXml(xml, context) == LoadFailure)
  2011.                         return LoadFailure;
  2012.  
  2013.                 const stack_string eventName = xml->getAttr("name");
  2014.                 IF_UNLIKELY (eventName.empty())
  2015.                 {
  2016.                         gEnv->pLog->LogError("WaitForEvent could not find the 'name' attribute at line %d.", xml->getLine());
  2017.                         return LoadFailure;
  2018.                 }
  2019.  
  2020.                 m_eventToWaitFor = Event(eventName);
  2021.  
  2022.                 const stack_string resultString = xml->getAttr("result");
  2023.                 if (!resultString.empty())
  2024.                 {
  2025.                         if (resultString == "Success")
  2026.                                 m_statusToReturn = Success;
  2027.                         else if (resultString == "Failure")
  2028.                                 m_statusToReturn = Failure;
  2029.                         else
  2030.                         {
  2031.                                 ErrorReporter(*this, context).LogError("Invalid 'result' attribute. Expected 'Success' or 'Failure'.");
  2032.                                 return LoadFailure;
  2033.                         }
  2034.                 }
  2035.  
  2036.                 return LoadSuccess;
  2037.         }
  2038.  
  2039. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  2040.         virtual XmlNodeRef CreateXmlDescription() override
  2041.         {
  2042.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  2043.                 xml->setTag("WaitForEvent");
  2044.                 xml->setAttr("name", m_eventToWaitFor.GetName());
  2045.                 return xml;
  2046.         }
  2047. #endif
  2048.  
  2049. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  2050.         virtual void Serialize(Serialization::IArchive& archive) override
  2051.         {
  2052.                 archive(m_eventToWaitFor, "event", "^");
  2053.                 if (strlen(m_eventToWaitFor.GetName()) == 0)
  2054.                         archive.error(m_eventToWaitFor, "Event must be specified");
  2055.                 BaseClass::Serialize(archive);
  2056.         }
  2057. #endif
  2058.  
  2059.         virtual void HandleEvent(const EventContext& context, const Event& event) override
  2060.         {
  2061.                 if (m_eventToWaitFor == event)
  2062.                 {
  2063.                         RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  2064.                         runtimeData.eventReceieved = true;
  2065.                 }
  2066.         }
  2067.  
  2068. #if defined(USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT) && defined(USING_BEHAVIOR_TREE_EVENT_DEBUGGING)
  2069.         virtual void GetCustomDebugText(const UpdateContext& updateContext, stack_string& debugText) const override
  2070.         {
  2071.                 debugText = m_eventToWaitFor.GetName();
  2072.         }
  2073. #endif
  2074.  
  2075. protected:
  2076.         virtual Status Update(const UpdateContext& context) override
  2077.         {
  2078.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  2079.  
  2080.                 if (runtimeData.eventReceieved)
  2081.                         return m_statusToReturn;
  2082.                 else
  2083.                         return Running;
  2084.         }
  2085.  
  2086. private:
  2087.         Event  m_eventToWaitFor;
  2088.         Status m_statusToReturn;
  2089. };
  2090.  
  2091. //////////////////////////////////////////////////////////////////////////
  2092.  
  2093. class IfTime : public Decorator
  2094. {
  2095. public:
  2096.         typedef Decorator BaseClass;
  2097.  
  2098.         struct RuntimeData
  2099.         {
  2100.                 bool gateIsOpen;
  2101.  
  2102.                 RuntimeData()
  2103.                         : gateIsOpen(false)
  2104.                 {
  2105.                 }
  2106.         };
  2107.  
  2108.         enum CompareOp
  2109.         {
  2110.                 MoreThan,
  2111.                 LessThan,
  2112.         };
  2113.  
  2114.         IfTime()
  2115.                 : m_timeThreshold(0.0f)
  2116.                 , m_compareOp(MoreThan)
  2117.                 , m_openGateIfTimestampWasNeverSet(false)
  2118.         {
  2119.         }
  2120.  
  2121.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  2122.         {
  2123.                 const char* timestampName = xml->getAttr("since");
  2124.                 if (!timestampName)
  2125.                 {
  2126.                         gEnv->pLog->LogError("%s: Missing attribute 'since' on line %d.", context.treeName, xml->getLine());
  2127.                         return LoadFailure;
  2128.                 }
  2129.  
  2130. #ifdef USING_BEHAVIOR_TREE_EDITOR
  2131.                 m_timeStampName = timestampName;
  2132. #endif
  2133.  
  2134.                 if (xml->getAttr("isMoreThan", m_timeThreshold))
  2135.                 {
  2136.                         m_compareOp = MoreThan;
  2137.                 }
  2138.                 else if (xml->getAttr("isLessThan", m_timeThreshold))
  2139.                 {
  2140.                         m_compareOp = LessThan;
  2141.                 }
  2142.                 else
  2143.                 {
  2144.                         gEnv->pLog->LogError("%s: Missing attribute 'isMoreThan' or 'isLessThan' on line %d.", context.treeName, xml->getLine());
  2145.                         return LoadFailure;
  2146.                 }
  2147.  
  2148.                 xml->getAttr("orNeverBeenSet", m_openGateIfTimestampWasNeverSet);
  2149.  
  2150.                 m_timestampID = TimestampID(timestampName);
  2151.  
  2152.                 return LoadChildFromXml(xml, context);
  2153.         }
  2154.  
  2155. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  2156.         virtual XmlNodeRef CreateXmlDescription() override
  2157.         {
  2158.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  2159.  
  2160.                 xml->setTag("IfTime");
  2161.  
  2162.                 xml->setAttr("since", m_timeStampName);
  2163.  
  2164.                 if (m_compareOp == MoreThan)
  2165.                         xml->setAttr("isMoreThan", m_timeThreshold);
  2166.  
  2167.                 if (m_compareOp == LessThan)
  2168.                         xml->setAttr("isLessThan", m_timeThreshold);
  2169.  
  2170.                 if (m_openGateIfTimestampWasNeverSet)
  2171.                         xml->setAttr("orNeverBeenSet", 1);
  2172.  
  2173.                 return xml;
  2174.         }
  2175. #endif
  2176.  
  2177. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  2178.         virtual void Serialize(Serialization::IArchive& archive) override
  2179.         {
  2180.                 archive(m_timeStampName, "name", "^");
  2181.                 if (m_timeStampName.empty())
  2182.                         archive.error(m_timeStampName, "Timestamp must be specified");
  2183.  
  2184.                 archive(m_compareOp, "compareOp", "^");
  2185.                 archive(m_timeThreshold, "timeThreshold", "^");
  2186.  
  2187.                 archive(m_openGateIfTimestampWasNeverSet, "openGateIfTimestampWasNeverSet", "^Open if it was never set");
  2188.  
  2189.                 BaseClass::Serialize(archive);
  2190.         }
  2191. #endif
  2192.  
  2193. protected:
  2194.         virtual void OnInitialize(const UpdateContext& context) override
  2195.         {
  2196.                 FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  2197.  
  2198.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  2199.  
  2200.                 const bool timestampHasBeenSetAtLeastOnce = context.timestamps.HasBeenSetAtLeastOnce(m_timestampID);
  2201.  
  2202.                 if (timestampHasBeenSetAtLeastOnce)
  2203.                 {
  2204.                         bool valid = false;
  2205.                         CTimeValue elapsedTime;
  2206.                         context.timestamps.GetElapsedTimeSince(m_timestampID, elapsedTime, valid);
  2207.                         if (valid)
  2208.                         {
  2209.                                 if ((m_compareOp == MoreThan) && (elapsedTime > m_timeThreshold))
  2210.                                 {
  2211.                                         runtimeData.gateIsOpen = true;
  2212.                                         return;
  2213.                                 }
  2214.                                 else if ((m_compareOp == LessThan) && (elapsedTime < m_timeThreshold))
  2215.                                 {
  2216.                                         runtimeData.gateIsOpen = true;
  2217.                                         return;
  2218.                                 }
  2219.                         }
  2220.                 }
  2221.                 else
  2222.                 {
  2223.                         if (m_openGateIfTimestampWasNeverSet)
  2224.                         {
  2225.                                 runtimeData.gateIsOpen = true;
  2226.                                 return;
  2227.                         }
  2228.                 }
  2229.  
  2230.                 runtimeData.gateIsOpen = false;
  2231.         }
  2232.  
  2233.         virtual Status Update(const UpdateContext& context) override
  2234.         {
  2235.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  2236.  
  2237.                 if (runtimeData.gateIsOpen)
  2238.                         return BaseClass::Update(context);
  2239.                 else
  2240.                         return Failure;
  2241.         }
  2242.  
  2243. private:
  2244.         TimestampID m_timestampID;
  2245.         float       m_timeThreshold;
  2246.         CompareOp   m_compareOp;
  2247.         bool        m_openGateIfTimestampWasNeverSet;
  2248.  
  2249. #ifdef USING_BEHAVIOR_TREE_EDITOR
  2250.         string m_timeStampName;
  2251. #endif
  2252. };
  2253.  
  2254. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  2255. SERIALIZATION_ENUM_BEGIN_NESTED(IfTime, CompareOp, "Compare")
  2256. SERIALIZATION_ENUM(IfTime::MoreThan, "MoreThan", "More Than")
  2257. SERIALIZATION_ENUM(IfTime::LessThan, "LessThan", "Less Than")
  2258. SERIALIZATION_ENUM_END()
  2259. #endif
  2260.  
  2261. //////////////////////////////////////////////////////////////////////////
  2262.  
  2263. class WaitUntilTime : public Action
  2264. {
  2265.         typedef Action BaseClass;
  2266.  
  2267. public:
  2268.         struct RuntimeData
  2269.         {
  2270.         };
  2271.  
  2272.         WaitUntilTime()
  2273.                 : m_timeThreshold(0.0f)
  2274.                 , m_succeedIfTimestampWasNeverSet(false)
  2275.                 , m_compareOp(MoreThan)
  2276.         {
  2277.         }
  2278.  
  2279.         enum CompareOp
  2280.         {
  2281.                 MoreThan,
  2282.                 LessThan,
  2283.         };
  2284.  
  2285.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  2286.         {
  2287.                 const char* timestampName = xml->getAttr("since");
  2288.                 if (!timestampName)
  2289.                 {
  2290.                         gEnv->pLog->LogError("%s: Failed to find 'since' attribute on line %d.", context.treeName, xml->getLine());
  2291.                         return LoadFailure;
  2292.                 }
  2293.  
  2294. #ifdef USING_BEHAVIOR_TREE_EDITOR
  2295.                 m_timeStampName = timestampName;
  2296. #endif
  2297.  
  2298.                 if (xml->getAttr("isMoreThan", m_timeThreshold))
  2299.                 {
  2300.                         m_compareOp = MoreThan;
  2301.                 }
  2302.                 else if (xml->getAttr("isLessThan", m_timeThreshold))
  2303.                 {
  2304.                         m_compareOp = LessThan;
  2305.                 }
  2306.                 else
  2307.                 {
  2308.                         gEnv->pLog->LogError("%s: Missing attribute 'isMoreThan' or 'isLessThan' on line %d.", context.treeName, xml->getLine());
  2309.                         return LoadFailure;
  2310.                 }
  2311.  
  2312.                 xml->getAttr("succeedIfNeverBeenSet", m_succeedIfTimestampWasNeverSet);
  2313.  
  2314.                 m_timestampID = TimestampID(timestampName);
  2315.  
  2316.                 return LoadSuccess;
  2317.         }
  2318.  
  2319. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  2320.         virtual XmlNodeRef CreateXmlDescription() override
  2321.         {
  2322.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  2323.  
  2324.                 xml->setTag("WaitUntilTime");
  2325.  
  2326.                 xml->setAttr("since", m_timeStampName);
  2327.  
  2328.                 if (m_compareOp == MoreThan)
  2329.                         xml->setAttr("isMoreThan", m_timeThreshold);
  2330.  
  2331.                 if (m_compareOp == LessThan)
  2332.                         xml->setAttr("isLessThan", m_timeThreshold);
  2333.  
  2334.                 if (m_succeedIfTimestampWasNeverSet)
  2335.                         xml->setAttr("succeedIfNeverBeenSet", 1);
  2336.  
  2337.                 return xml;
  2338.         }
  2339. #endif
  2340.  
  2341. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  2342.         virtual void Serialize(Serialization::IArchive& archive) override
  2343.         {
  2344.                 archive(m_timeStampName, "name", "^");
  2345.                 if (m_timeStampName.empty())
  2346.                         archive.error(m_timeStampName, "Timestamp must be specified");
  2347.  
  2348.                 archive(m_compareOp, "compareOp", "^");
  2349.                 archive(m_timeThreshold, "timeThreshold", "^");
  2350.  
  2351.                 archive(m_succeedIfTimestampWasNeverSet, "succeedIfTimestampWasNeverSet", "^Succeed if it was never set");
  2352.  
  2353.                 BaseClass::Serialize(archive);
  2354.         }
  2355. #endif
  2356.  
  2357. protected:
  2358.         virtual Status Update(const UpdateContext& context) override
  2359.         {
  2360.                 FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  2361.  
  2362.                 if (m_succeedIfTimestampWasNeverSet && !context.timestamps.HasBeenSetAtLeastOnce(m_timestampID))
  2363.                 {
  2364.                         return Success;
  2365.                 }
  2366.  
  2367.                 bool valid = false;
  2368.                 CTimeValue elapsedTime;
  2369.                 context.timestamps.GetElapsedTimeSince(m_timestampID, elapsedTime, valid);
  2370.                 if (valid)
  2371.                 {
  2372.                         if ((m_compareOp == MoreThan) && (elapsedTime > m_timeThreshold))
  2373.                                 return Success;
  2374.                         else if ((m_compareOp == LessThan) && (elapsedTime < m_timeThreshold))
  2375.                                 return Success;
  2376.                 }
  2377.  
  2378.                 return Running;
  2379.         }
  2380.  
  2381. private:
  2382.         float       m_timeThreshold;
  2383.         TimestampID m_timestampID;
  2384.         CompareOp   m_compareOp;
  2385.         bool        m_succeedIfTimestampWasNeverSet;
  2386.  
  2387. #ifdef USING_BEHAVIOR_TREE_EDITOR
  2388.         string m_timeStampName;
  2389. #endif
  2390. };
  2391.  
  2392. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  2393. SERIALIZATION_ENUM_BEGIN_NESTED(WaitUntilTime, CompareOp, "Compare")
  2394. SERIALIZATION_ENUM(WaitUntilTime::MoreThan, "MoreThan", "More Than")
  2395. SERIALIZATION_ENUM(WaitUntilTime::LessThan, "LessThan", "Less Than")
  2396. SERIALIZATION_ENUM_END()
  2397. #endif
  2398.  
  2399. //////////////////////////////////////////////////////////////////////////
  2400.  
  2401. class AssertTime : public Action
  2402. {
  2403.         typedef Action BaseClass;
  2404.  
  2405. public:
  2406.         struct RuntimeData
  2407.         {
  2408.         };
  2409.  
  2410.         AssertTime()
  2411.                 : m_timeThreshold(0.0f)
  2412.                 , m_succeedIfTimestampWasNeverSet(false)
  2413.                 , m_compareOp(MoreThan)
  2414.         {
  2415.         }
  2416.  
  2417.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  2418.         {
  2419.                 const stack_string timestampName = xml->getAttr("since");
  2420.                 IF_UNLIKELY (timestampName.empty())
  2421.                 {
  2422.                         ErrorReporter(*this, context).LogError("Missing or invalid 'since' attribute.");
  2423.                         return LoadFailure;
  2424.                 }
  2425.  
  2426. #ifdef USING_BEHAVIOR_TREE_EDITOR
  2427.                 m_timeStampName = timestampName.c_str();
  2428. #endif
  2429.  
  2430.                 if (xml->getAttr("isMoreThan", m_timeThreshold))
  2431.                 {
  2432.                         m_compareOp = MoreThan;
  2433.                 }
  2434.                 else if (xml->getAttr("isLessThan", m_timeThreshold))
  2435.                 {
  2436.                         m_compareOp = LessThan;
  2437.                 }
  2438.                 else
  2439.                 {
  2440.                         ErrorReporter(*this, context).LogError("Missing attribute 'isMoreThan' or 'isLessThan'.");
  2441.                         return LoadFailure;
  2442.                 }
  2443.  
  2444.                 xml->getAttr("orNeverBeenSet", m_succeedIfTimestampWasNeverSet);
  2445.  
  2446.                 m_timestampID = TimestampID(timestampName);
  2447.  
  2448.                 return LoadSuccess;
  2449.         }
  2450.  
  2451.         enum CompareOp
  2452.         {
  2453.                 MoreThan,
  2454.                 LessThan,
  2455.         };
  2456.  
  2457. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  2458.         virtual XmlNodeRef CreateXmlDescription() override
  2459.         {
  2460.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  2461.  
  2462.                 xml->setTag("AssertTime");
  2463.  
  2464.                 xml->setAttr("since", m_timeStampName);
  2465.  
  2466.                 if (m_compareOp == MoreThan)
  2467.                         xml->setAttr("isMoreThan", m_timeThreshold);
  2468.  
  2469.                 if (m_compareOp == LessThan)
  2470.                         xml->setAttr("isLessThan", m_timeThreshold);
  2471.  
  2472.                 if (m_succeedIfTimestampWasNeverSet)
  2473.                         xml->setAttr("orNeverBeenSet", 1);
  2474.  
  2475.                 return xml;
  2476.         }
  2477. #endif
  2478.  
  2479. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  2480.         virtual void Serialize(Serialization::IArchive& archive) override
  2481.         {
  2482.                 archive(m_timeStampName, "name", "^");
  2483.                 if (m_timeStampName.empty())
  2484.                         archive.error(m_timeStampName, "Timestamp must be specified");
  2485.  
  2486.                 archive(m_compareOp, "compareOp", "^");
  2487.                 archive(m_timeThreshold, "timeThreshold", "^");
  2488.  
  2489.                 archive(m_succeedIfTimestampWasNeverSet, "succeedIfTimestampWasNeverSet", "^Succeed if it was never set");
  2490.  
  2491.                 BaseClass::Serialize(archive);
  2492.         }
  2493. #endif
  2494.  
  2495. protected:
  2496.         virtual Status Update(const UpdateContext& context) override
  2497.         {
  2498.                 FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI);
  2499.  
  2500.                 if (m_succeedIfTimestampWasNeverSet && !context.timestamps.HasBeenSetAtLeastOnce(m_timestampID))
  2501.                 {
  2502.                         return Success;
  2503.                 }
  2504.  
  2505.                 bool valid = false;
  2506.                 CTimeValue elapsedTime(0.0f);
  2507.                 context.timestamps.GetElapsedTimeSince(m_timestampID, elapsedTime, valid);
  2508.  
  2509.                 if (valid)
  2510.                 {
  2511.                         if ((m_compareOp == MoreThan) && (elapsedTime > m_timeThreshold))
  2512.                                 return Success;
  2513.                         else if ((m_compareOp == LessThan) && (elapsedTime < m_timeThreshold))
  2514.                                 return Success;
  2515.                 }
  2516.  
  2517.                 return Failure;
  2518.         }
  2519.  
  2520. private:
  2521.  
  2522.         float       m_timeThreshold;
  2523.         TimestampID m_timestampID;
  2524.         CompareOp   m_compareOp;
  2525.         bool        m_succeedIfTimestampWasNeverSet;
  2526.  
  2527. #ifdef USING_BEHAVIOR_TREE_EDITOR
  2528.         string m_timeStampName;
  2529. #endif
  2530.  
  2531. };
  2532.  
  2533. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  2534. SERIALIZATION_ENUM_BEGIN_NESTED(AssertTime, CompareOp, "Compare")
  2535. SERIALIZATION_ENUM(AssertTime::MoreThan, "MoreThan", "More Than")
  2536. SERIALIZATION_ENUM(AssertTime::LessThan, "LessThan", "Less Than")
  2537. SERIALIZATION_ENUM_END()
  2538. #endif
  2539.  
  2540. //////////////////////////////////////////////////////////////////////////
  2541.  
  2542. class Fail : public Action
  2543. {
  2544.         typedef Action BaseClass;
  2545.  
  2546. public:
  2547.         struct RuntimeData
  2548.         {
  2549.         };
  2550.  
  2551. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  2552.         virtual XmlNodeRef CreateXmlDescription() override
  2553.         {
  2554.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  2555.                 xml->setTag("Fail");
  2556.                 return xml;
  2557.         }
  2558. #endif
  2559.  
  2560. protected:
  2561.         virtual Status Update(const UpdateContext& context)
  2562.         {
  2563.                 return Failure;
  2564.         }
  2565. };
  2566.  
  2567. //////////////////////////////////////////////////////////////////////////
  2568.  
  2569. class SuppressFailure : public Decorator
  2570. {
  2571.         typedef Decorator BaseClass;
  2572.  
  2573. public:
  2574.         struct RuntimeData
  2575.         {
  2576.         };
  2577.  
  2578. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  2579.         virtual XmlNodeRef CreateXmlDescription() override
  2580.         {
  2581.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  2582.                 xml->setTag("SuppressFailure");
  2583.                 return xml;
  2584.         }
  2585. #endif
  2586.  
  2587.         virtual Status Update(const UpdateContext& context)
  2588.         {
  2589.                 Status s = m_child->Tick(context);
  2590.  
  2591.                 if (s == Running)
  2592.                         return Running;
  2593.                 else
  2594.                         return Success;
  2595.         }
  2596. };
  2597.  
  2598. //////////////////////////////////////////////////////////////////////////
  2599.  
  2600. #if defined(USING_BEHAVIOR_TREE_LOG) || defined(USING_BEHAVIOR_TREE_EDITOR)
  2601.         #define STORE_LOG_MESSAGE
  2602. #endif
  2603.  
  2604. class Log : public Action
  2605. {
  2606.         typedef Action BaseClass;
  2607.  
  2608. public:
  2609.         struct RuntimeData
  2610.         {
  2611.         };
  2612.  
  2613.         virtual LoadResult LoadFromXml(const XmlNodeRef& node, const LoadContext& context) override
  2614.         {
  2615. #ifdef STORE_LOG_MESSAGE
  2616.                 m_message = node->getAttr("message");
  2617. #endif
  2618.  
  2619.                 return LoadSuccess;
  2620.         }
  2621.  
  2622. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  2623.         virtual XmlNodeRef CreateXmlDescription() override
  2624.         {
  2625.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  2626.                 xml->setTag("Log");
  2627.                 xml->setAttr("message", m_message);
  2628.                 return xml;
  2629.         }
  2630. #endif
  2631.  
  2632. #ifdef USING_BEHAVIOR_TREE_SERIALIZATION
  2633.         virtual void Serialize(Serialization::IArchive& archive) override
  2634.         {
  2635.                 archive(m_message, "message", "^");
  2636.                 if (m_message.empty())
  2637.                         archive.error(m_message, "Log message is empty");
  2638.  
  2639.                 BaseClass::Serialize(archive);
  2640.         }
  2641. #endif
  2642.  
  2643. protected:
  2644.         virtual Status Update(const UpdateContext& context) override
  2645.         {
  2646. #ifdef STORE_LOG_MESSAGE
  2647.                 stack_string textBuffer;
  2648.                 textBuffer.Format("%s (%d)", m_message ? m_message : "", GetXmlLine());
  2649.                 context.behaviorLog.AddMessage(m_message);
  2650. #endif
  2651.  
  2652.                 return Success;
  2653.         }
  2654.  
  2655. private:
  2656. #ifdef STORE_LOG_MESSAGE
  2657.         string m_message;
  2658. #endif
  2659. };
  2660.  
  2661. //////////////////////////////////////////////////////////////////////////
  2662.  
  2663. // This node effectively halts the execution of the modular behavior
  2664. // tree because it never finishes.
  2665. class Halt : public Action
  2666. {
  2667.         typedef Action BaseClass;
  2668.  
  2669. public:
  2670.         struct RuntimeData
  2671.         {
  2672.         };
  2673.  
  2674. #ifdef USING_BEHAVIOR_TREE_XML_DESCRIPTION_CREATION
  2675.         virtual XmlNodeRef CreateXmlDescription() override
  2676.         {
  2677.                 XmlNodeRef xml = BaseClass::CreateXmlDescription();
  2678.                 xml->setTag("Halt");
  2679.                 return xml;
  2680.         }
  2681. #endif
  2682.  
  2683. protected:
  2684.         virtual Status Update(const UpdateContext& context) override
  2685.         {
  2686.                 return Running;
  2687.         }
  2688. };
  2689.  
  2690. //////////////////////////////////////////////////////////////////////////
  2691.  
  2692. class Breakpoint : public Action
  2693. {
  2694. public:
  2695.         struct RuntimeData
  2696.         {
  2697.         };
  2698.  
  2699. protected:
  2700.         virtual Status Update(const UpdateContext& context)
  2701.         {
  2702.                 CryDebugBreak();
  2703.                 return Success;
  2704.         }
  2705. };
  2706.  
  2707. //////////////////////////////////////////////////////////////////////////
  2708.  
  2709. class Graft : public Action
  2710. {
  2711. public:
  2712.         typedef Action BaseClass;
  2713.  
  2714.         struct RuntimeData : public IGraftNode
  2715.         {
  2716.                 virtual bool RunBehavior(EntityId entityId, const char* behaviorName, XmlNodeRef behaviorXmlNode) override
  2717.                 {
  2718.                         if (behaviorTreeInstance.get() != NULL)
  2719.                         {
  2720.                                 BehaviorVariablesContext variables(
  2721.                                   behaviorTreeInstance->variables,
  2722.                                   behaviorTreeInstance->behaviorTreeTemplate->variableDeclarations,
  2723.                                   behaviorTreeInstance->variables.Changed());
  2724.  
  2725.                                 IEntity* entity = gEnv->pEntitySystem->GetEntity(entityId);
  2726.                                 assert(entity);
  2727.  
  2728.                                 UpdateContext context(
  2729.                                   entityId,
  2730.                                   *entity,
  2731.                                   variables,
  2732.                                   behaviorTreeInstance->timestampCollection,
  2733.                                   behaviorTreeInstance->blackboard
  2734. #ifdef USING_BEHAVIOR_TREE_LOG
  2735.                                   ,
  2736.                                   behaviorTreeInstance->behaviorLog
  2737. #endif
  2738.                                   );
  2739.  
  2740.                                 behaviorTreeInstance->behaviorTreeTemplate->rootNode->Terminate(context);
  2741.                         }
  2742.  
  2743.                         behaviorTreeInstance = gAIEnv.pBehaviorTreeManager->CreateBehaviorTreeInstanceFromXml(behaviorName, behaviorXmlNode);
  2744.                         if (behaviorTreeInstance.get() != NULL)
  2745.                         {
  2746. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  2747.                                 behaviorTreeName = behaviorName;
  2748. #endif
  2749.                                 return true;
  2750.                         }
  2751.                         else
  2752.                         {
  2753.                                 return false;
  2754.                         }
  2755.                 }
  2756.  
  2757.                 BehaviorTreeInstancePtr behaviorTreeInstance;
  2758.  
  2759. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  2760.                 string behaviorTreeName;
  2761. #endif
  2762.         };
  2763.  
  2764.         virtual LoadResult LoadFromXml(const XmlNodeRef& xml, const LoadContext& context) override
  2765.         {
  2766.                 if (BaseClass::LoadFromXml(xml, context) == LoadFailure)
  2767.                         return LoadFailure;
  2768.  
  2769.                 return LoadSuccess;
  2770.         }
  2771.  
  2772.         virtual void OnInitialize(const UpdateContext& context) override
  2773.         {
  2774.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  2775.                 gAIEnv.pGraftManager->GraftNodeReady(context.entityId, &runtimeData);
  2776.         }
  2777.  
  2778.         virtual Status Update(const UpdateContext& context) override
  2779.         {
  2780.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  2781.  
  2782.                 if (!runtimeData.behaviorTreeInstance.get())
  2783.                         return Running;
  2784.  
  2785.                 Status behaviorStatus = runtimeData.behaviorTreeInstance->behaviorTreeTemplate->rootNode->Tick(context);
  2786.                 if (behaviorStatus == Failure)
  2787.                 {
  2788.                         ErrorReporter(*this, context).LogError("Graft behavior failed to execute.");
  2789.                         return Failure;
  2790.                 }
  2791.  
  2792.                 if (behaviorStatus == Success)
  2793.                 {
  2794.                         gAIEnv.pGraftManager->GraftBehaviorComplete(context.entityId);
  2795.                         runtimeData.behaviorTreeInstance.reset();
  2796. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  2797.                         runtimeData.behaviorTreeName.clear();
  2798. #endif
  2799.                 }
  2800.  
  2801.                 return Running;
  2802.         }
  2803.  
  2804.         virtual void OnTerminate(const UpdateContext& context) override
  2805.         {
  2806.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  2807.                 if (runtimeData.behaviorTreeInstance.get())
  2808.                         runtimeData.behaviorTreeInstance->behaviorTreeTemplate->rootNode->Terminate(context);
  2809.  
  2810.                 gAIEnv.pGraftManager->GraftNodeTerminated(context.entityId);
  2811.         }
  2812.  
  2813.         virtual void HandleEvent(const EventContext& context, const Event& event) override
  2814.         {
  2815.                 RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(context);
  2816.                 if (runtimeData.behaviorTreeInstance.get())
  2817.                 {
  2818.                         runtimeData.behaviorTreeInstance->behaviorTreeTemplate->signalHandler.ProcessSignal(event.GetCRC(), runtimeData.behaviorTreeInstance->variables);
  2819.                         runtimeData.behaviorTreeInstance->timestampCollection.HandleEvent(event.GetCRC());
  2820.                         runtimeData.behaviorTreeInstance->behaviorTreeTemplate->rootNode->SendEvent(context, event);
  2821.                 }
  2822.         }
  2823.  
  2824. #ifdef USING_BEHAVIOR_TREE_NODE_CUSTOM_DEBUG_TEXT
  2825.         virtual void GetCustomDebugText(const UpdateContext& updateContext, stack_string& debugText) const
  2826.         {
  2827.                 const RuntimeData& runtimeData = GetRuntimeData<RuntimeData>(updateContext);
  2828.                 debugText.Format("%s", runtimeData.behaviorTreeName.c_str());
  2829.         }
  2830. #endif
  2831. };
  2832.  
  2833. //////////////////////////////////////////////////////////////////////////
  2834. //////////////////////////////////////////////////////////////////////////
  2835.  
  2836. void RegisterBehaviorTreeNodes_Core()
  2837. {
  2838.         assert(gAIEnv.pBehaviorTreeManager);
  2839.  
  2840.         IBehaviorTreeManager& manager = *gAIEnv.pBehaviorTreeManager;
  2841.  
  2842.         const char* COLOR_FLOW = "00ff00";
  2843.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, Sequence, "Flow\\Sequence", COLOR_FLOW);
  2844.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, Selector, "Flow\\Selector", COLOR_FLOW);
  2845.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, Parallel, "Flow\\Parallel", COLOR_FLOW);
  2846.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, Loop, "Flow\\Loop", COLOR_FLOW);
  2847.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, LoopUntilSuccess, "Flow\\Loop until success", COLOR_FLOW);
  2848.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, Priority, "Flow\\Priority", COLOR_FLOW);
  2849.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, StateMachine, "Flow\\State Machine\\State machine", COLOR_FLOW);
  2850.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, SendTransitionEvent, "Flow\\State Machine\\Send transition event", COLOR_FLOW);
  2851.  
  2852.         const char* COLOR_CONDITION = "00ffff";
  2853.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, IfCondition, "Conditions\\Condition gate", COLOR_CONDITION);
  2854.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, AssertCondition, "Conditions\\Assert condition", COLOR_CONDITION);
  2855.  
  2856.         const char* COLOR_FAIL = "ff0000";
  2857.         const char* COLOR_DEBUG = "000000";
  2858.         const char* COLOR_TIME = "ffffff";
  2859.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, Timeout, "Time\\Timeout", COLOR_FAIL);
  2860.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, Wait, "Time\\Wait", COLOR_TIME);
  2861.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, MonitorCondition, "Time\\Wait for condition", COLOR_TIME);
  2862.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, WaitForEvent, "Time\\Wait for event", COLOR_TIME);
  2863.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, WaitUntilTime, "Time\\Wait for timestamp", COLOR_TIME);
  2864.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, IfTime, "Time\\Timestamp gate", COLOR_TIME);
  2865.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, AssertTime, "Time\\Assert timestamp", COLOR_DEBUG);
  2866.  
  2867.         const char* COLOR_CORE = "0000ff";
  2868.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, SendEvent, "Core\\Send Event", COLOR_CORE);
  2869.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, RandomGate, "Core\\Random gate", COLOR_CORE);
  2870.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, Fail, "Core\\Fail", COLOR_FAIL);
  2871.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, SuppressFailure, "Core\\Suppress failure", COLOR_FAIL);
  2872.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, Log, "Core\\Log message", COLOR_DEBUG);
  2873.         REGISTER_BEHAVIOR_TREE_NODE_WITH_SERIALIZATION(manager, Halt, "Core\\Halt", COLOR_DEBUG);
  2874.  
  2875.         REGISTER_BEHAVIOR_TREE_NODE(manager, Breakpoint);
  2876.  
  2877.         REGISTER_BEHAVIOR_TREE_NODE(manager, Graft);
  2878. }
  2879. }
  2880.  
downloadBehaviorTreeNodes_Core.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