BVB Source Codes

CRYENGINE Show FlowLogicNodes.cpp Source code

Return Download CRYENGINE: download FlowLogicNodes.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   FlowLogicNodes.h
  5. //  Version:     v1.00
  6. //  Created:     30/6/2005 by Timur.
  7. //  Compilers:   Visual Studio.NET 2003
  8. //  Description:
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15. #include <CryFlowGraph/IFlowBaseNode.h>
  16.  
  17. class CLogicNode : public CFlowBaseNode<eNCT_Instanced>
  18. {
  19. public:
  20.         CLogicNode(SActivationInfo* pActInfo) : m_bResult(2) {};
  21.  
  22.         void Serialize(SActivationInfo*, TSerialize ser)
  23.         {
  24.                 ser.Value("m_bResult", m_bResult);
  25.         }
  26.  
  27.         enum EInputs
  28.         {
  29.                 INP_A = 0,
  30.                 INP_B,
  31.                 INP_Always
  32.         };
  33.  
  34.         virtual IFlowNodePtr Clone(SActivationInfo* pActInfo) = 0;
  35.  
  36.         virtual void         GetConfiguration(SFlowNodeConfig& config)
  37.         {
  38.                 static const SInputPortConfig in_config[] = {
  39.                         InputPortConfig<bool>("A",      _HELP("out = A op B")),
  40.                         InputPortConfig<bool>("B",      _HELP("out = A op B")),
  41.                         InputPortConfig<bool>("Always", _HELP("if true, the outputs will be activated every time an input is. If false, outputs only will be activated when the value does change")),
  42.                         { 0 }
  43.                 };
  44.                 static const SOutputPortConfig out_config[] = {
  45.                         OutputPortConfig<bool>("out",   _HELP("out = A op B")),
  46.                         OutputPortConfig<bool>("true",  _HELP("triggered if out is true")),
  47.                         OutputPortConfig<bool>("false", _HELP("triggered if out is false")),
  48.                         { 0 }
  49.                 };
  50.                 config.sDescription = _HELP("Do logical operation on input ports and outputs result to [out] port. True port is triggered if the result was true, otherwise the false port is triggered.");
  51.                 config.pInputPorts = in_config;
  52.                 config.pOutputPorts = out_config;
  53.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  54.                 config.SetCategory(EFLN_APPROVED);
  55.         }
  56.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  57.         {
  58.                 switch (event)
  59.                 {
  60.                 case eFE_Initialize:
  61.                         {
  62.                                 m_bResult = 2;
  63.                                 break;
  64.                         }
  65.  
  66.                 case eFE_Activate:
  67.                         {
  68.                                 bool a = GetPortBool(pActInfo, INP_A);
  69.                                 bool b = GetPortBool(pActInfo, INP_B);
  70.                                 int result = Execute(a, b) ? 1 : 0;
  71.                                 bool activateOutputs = GetPortBool(pActInfo, INP_Always) || m_bResult != result;
  72.                                 m_bResult = result;
  73.                                 if (activateOutputs)
  74.                                 {
  75.                                         ActivateOutput(pActInfo, 0, result);
  76.                                         if (result)
  77.                                                 ActivateOutput(pActInfo, 1, true);
  78.                                         else
  79.                                                 ActivateOutput(pActInfo, 2, true);
  80.                                 }
  81.                         }
  82.                 }
  83.                 ;
  84.         };
  85.  
  86. private:
  87.         virtual bool Execute(bool a, bool b) = 0;
  88.  
  89.         int8 m_bResult;
  90. };
  91.  
  92. //////////////////////////////////////////////////////////////////////////
  93. class CFlowNode_AND : public CLogicNode
  94. {
  95. public:
  96.         CFlowNode_AND(SActivationInfo* pActInfo) : CLogicNode(pActInfo) {}
  97.         IFlowNodePtr Clone(SActivationInfo* pActInfo) { return new CFlowNode_AND(pActInfo); }
  98.  
  99.         virtual void GetMemoryUsage(ICrySizer* s) const
  100.         {
  101.                 s->Add(*this);
  102.         }
  103. private:
  104.         bool Execute(bool a, bool b) { return a && b; }
  105. };
  106.  
  107. //////////////////////////////////////////////////////////////////////////
  108. class CFlowNode_OR : public CLogicNode
  109. {
  110. public:
  111.         CFlowNode_OR(SActivationInfo* pActInfo) : CLogicNode(pActInfo) {}
  112.         IFlowNodePtr Clone(SActivationInfo* pActInfo) { return new CFlowNode_OR(pActInfo); }
  113.  
  114.         virtual void GetMemoryUsage(ICrySizer* s) const
  115.         {
  116.                 s->Add(*this);
  117.         }
  118. private:
  119.         bool Execute(bool a, bool b) { return a || b; }
  120. };
  121.  
  122. //////////////////////////////////////////////////////////////////////////
  123. class CFlowNode_XOR : public CLogicNode
  124. {
  125. public:
  126.         CFlowNode_XOR(SActivationInfo* pActInfo) : CLogicNode(pActInfo) {}
  127.         IFlowNodePtr Clone(SActivationInfo* pActInfo) { return new CFlowNode_XOR(pActInfo); }
  128.  
  129.         virtual void GetMemoryUsage(ICrySizer* s) const
  130.         {
  131.                 s->Add(*this);
  132.         }
  133. private:
  134.         bool Execute(bool a, bool b) { return a ^ b; }
  135. };
  136.  
  137. //////////////////////////////////////////////////////////////////////////
  138. class CFlowNode_NOT : public CFlowBaseNode<eNCT_Singleton>
  139. {
  140. public:
  141.         CFlowNode_NOT(SActivationInfo* pActInfo) {};
  142.         virtual void GetConfiguration(SFlowNodeConfig& config)
  143.         {
  144.                 static const SInputPortConfig in_config[] = {
  145.                         InputPortConfig<bool>("in", _HELP("out = not in")),
  146.                         { 0 }
  147.                 };
  148.                 static const SOutputPortConfig out_config[] = {
  149.                         OutputPortConfig<bool>("out", _HELP("out = not in")),
  150.                         { 0 }
  151.                 };
  152.                 config.sDescription = _HELP("Inverts [in] port, [out] port will output true when [in] is false, and will output false when [in] is true");
  153.                 config.pInputPorts = in_config;
  154.                 config.pOutputPorts = out_config;
  155.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  156.                 config.SetCategory(EFLN_APPROVED);
  157.         }
  158.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  159.         {
  160.                 switch (event)
  161.                 {
  162.                 case eFE_Activate:
  163.                 case eFE_Initialize:
  164.                         {
  165.                                 bool a = GetPortBool(pActInfo, 0);
  166.                                 bool result = !a;
  167.                                 ActivateOutput(pActInfo, 0, result);
  168.                         }
  169.                 }
  170.                 ;
  171.         };
  172.  
  173.         virtual void GetMemoryUsage(ICrySizer* s) const
  174.         {
  175.                 s->Add(*this);
  176.         }
  177. };
  178.  
  179. //////////////////////////////////////////////////////////////////////////
  180. class CFlowNode_OnChange : public CFlowBaseNode<eNCT_Instanced>
  181. {
  182. public:
  183.         CFlowNode_OnChange(SActivationInfo* pActInfo) { m_bCurrent = false; };
  184.         virtual IFlowNodePtr Clone(SActivationInfo* pActInfo) { return new CFlowNode_OnChange(pActInfo); }
  185.         virtual void         GetConfiguration(SFlowNodeConfig& config)
  186.         {
  187.                 static const SInputPortConfig in_config[] = {
  188.                         InputPortConfig<bool>("in"),
  189.                         { 0 }
  190.                 };
  191.                 static const SOutputPortConfig out_config[] = {
  192.                         OutputPortConfig<bool>("out"),
  193.                         { 0 }
  194.                 };
  195.                 config.sDescription = _HELP("Only send [in] value into the [out] when it is different from the previous value");
  196.                 config.pInputPorts = in_config;
  197.                 config.pOutputPorts = out_config;
  198.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  199.                 config.SetCategory(EFLN_APPROVED);
  200.         }
  201.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  202.         {
  203.                 switch (event)
  204.                 {
  205.                 case eFE_Activate:
  206.                 case eFE_Initialize:
  207.                         {
  208.                                 bool a = GetPortBool(pActInfo, 0);
  209.                                 if (a != m_bCurrent)
  210.                                 {
  211.                                         ActivateOutput(pActInfo, 0, a);
  212.                                         m_bCurrent = a;
  213.                                 }
  214.                         }
  215.                 }
  216.                 ;
  217.         };
  218.  
  219.         virtual void GetMemoryUsage(ICrySizer* s) const
  220.         {
  221.                 s->Add(*this);
  222.         }
  223. private:
  224.         bool m_bCurrent;
  225. };
  226.  
  227. //////////////////////////////////////////////////////////////////////////
  228. class CFlowNode_Any : public CFlowBaseNode<eNCT_Singleton>
  229. {
  230. public:
  231.         static const int NUM_INPUTS = 10;
  232.  
  233.         CFlowNode_Any(SActivationInfo* pActInfo) {}
  234.  
  235.         virtual void GetConfiguration(SFlowNodeConfig& config)
  236.         {
  237.                 static const SInputPortConfig in_config[] = {
  238.                         InputPortConfig_AnyType("in1",  _HELP("Input 1")),
  239.                         InputPortConfig_AnyType("in2",  _HELP("Input 2")),
  240.                         InputPortConfig_AnyType("in3",  _HELP("Input 3")),
  241.                         InputPortConfig_AnyType("in4",  _HELP("Input 4")),
  242.                         InputPortConfig_AnyType("in5",  _HELP("Input 5")),
  243.                         InputPortConfig_AnyType("in6",  _HELP("Input 6")),
  244.                         InputPortConfig_AnyType("in7",  _HELP("Input 7")),
  245.                         InputPortConfig_AnyType("in8",  _HELP("Input 8")),
  246.                         InputPortConfig_AnyType("in9",  _HELP("Input 9")),
  247.                         InputPortConfig_AnyType("in10", _HELP("Input 10")),
  248.                         { 0 }
  249.                 };
  250.                 static const SOutputPortConfig out_config[] = {
  251.                         OutputPortConfig_AnyType("out", _HELP("Output")),
  252.                         { 0 }
  253.                 };
  254.                 config.sDescription = _HELP("Port joiner - triggers it's output when any input is triggered");
  255.                 config.pInputPorts = in_config;
  256.                 config.pOutputPorts = out_config;
  257.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  258.                 config.SetCategory(EFLN_APPROVED);
  259.         }
  260.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  261.         {
  262.                 switch (event)
  263.                 {
  264.                 case eFE_Activate:
  265.                         for (int i = 0; i < NUM_INPUTS; i++)
  266.                         {
  267.                                 if (IsPortActive(pActInfo, i))
  268.                                         ActivateOutput(pActInfo, 0, pActInfo->pInputPorts[i]);
  269.                         }
  270.                         break;
  271.                 }
  272.         }
  273.  
  274.         virtual void GetMemoryUsage(ICrySizer* s) const
  275.         {
  276.                 s->Add(*this);
  277.         }
  278. };
  279.  
  280. //////////////////////////////////////////////////////////////////////////
  281. class CFlowNode_Blocker : public CFlowBaseNode<eNCT_Singleton>
  282. {
  283. public:
  284.  
  285.         CFlowNode_Blocker(SActivationInfo* pActInfo) {}
  286.  
  287.         virtual void GetConfiguration(SFlowNodeConfig& config)
  288.         {
  289.                 static const SInputPortConfig in_config[] = {
  290.                         InputPortConfig<bool>("Block", false,           _HELP("If true blocks [In] data. Otherwise passes [In] to [Out]")),
  291.                         InputPortConfig_AnyType("In",  _HELP("Input")),
  292.                         { 0 }
  293.                 };
  294.                 static const SOutputPortConfig out_config[] = {
  295.                         OutputPortConfig_AnyType("Out", _HELP("Output")),
  296.                         { 0 }
  297.                 };
  298.                 config.sDescription = _HELP("Blocker - If enabled blocks [In] signals, otherwise passes them to [Out]");
  299.                 config.pInputPorts = in_config;
  300.                 config.pOutputPorts = out_config;
  301.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  302.                 config.SetCategory(EFLN_APPROVED);
  303.         }
  304.  
  305.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  306.         {
  307.                 switch (event)
  308.                 {
  309.                 case eFE_Activate:
  310.                 case eFE_Initialize:
  311.                         if (IsPortActive(pActInfo, 1) && !GetPortBool(pActInfo, 0))
  312.                         {
  313.                                 ActivateOutput(pActInfo, 0, GetPortAny(pActInfo, 1));
  314.                         }
  315.                         break;
  316.                 }
  317.         }
  318.  
  319.         virtual void GetMemoryUsage(ICrySizer* s) const
  320.         {
  321.                 s->Add(*this);
  322.         }
  323. };
  324.  
  325. //////////////////////////////////////////////////////////////////////////
  326. class CFlowNode_LogicGate : public CFlowBaseNode<eNCT_Instanced>
  327. {
  328.         enum
  329.         {
  330.                 INP_In = 0,
  331.                 INP_Closed,
  332.                 INP_Open,
  333.                 INP_Close
  334.         };
  335.  
  336. protected:
  337.         bool m_bClosed;
  338.  
  339. public:
  340.         CFlowNode_LogicGate(SActivationInfo* pActInfo) : m_bClosed(false) {}
  341.  
  342.         virtual IFlowNodePtr Clone(SActivationInfo* pActInfo)
  343.         {
  344.                 return new CFlowNode_LogicGate(pActInfo);
  345.         }
  346.  
  347.         virtual void Serialize(SActivationInfo*, TSerialize ser)
  348.         {
  349.                 ser.Value("m_bClosed", m_bClosed);
  350.         }
  351.  
  352.         virtual void GetConfiguration(SFlowNodeConfig& config)
  353.         {
  354.                 static const SInputPortConfig in_config[] = {
  355.                         InputPortConfig_AnyType("In",   _HELP("Input")),
  356.                         InputPortConfig<bool>("Closed", false,                            _HELP("If true blocks [In] data. Otherwise passes [In] to [Out]")),
  357.                         InputPortConfig_Void("Open",    _HELP("Sets [Closed] to false.")),
  358.                         InputPortConfig_Void("Close",   _HELP("Sets [Closed] to true.")),
  359.                         { 0 }
  360.                 };
  361.                 static const SOutputPortConfig out_config[] = {
  362.                         OutputPortConfig_AnyType("Out", _HELP("Output")),
  363.                         { 0 }
  364.                 };
  365.                 config.sDescription = _HELP("If closed, blocks [In] signals, otherwise passes them to [Out]");
  366.                 config.pInputPorts = in_config;
  367.                 config.pOutputPorts = out_config;
  368.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  369.                 config.SetCategory(EFLN_APPROVED);
  370.         }
  371.  
  372.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  373.         {
  374.                 switch (event)
  375.                 {
  376.                 case eFE_Initialize:
  377.                         m_bClosed = GetPortBool(pActInfo, INP_Closed);
  378.                         break;
  379.  
  380.                 case eFE_Activate:
  381.                         if (IsPortActive(pActInfo, INP_Closed))
  382.                                 m_bClosed = GetPortBool(pActInfo, INP_Closed);
  383.                         if (IsPortActive(pActInfo, INP_Open))
  384.                                 m_bClosed = false;
  385.                         if (IsPortActive(pActInfo, INP_Close))
  386.                                 m_bClosed = true;
  387.                         if (IsPortActive(pActInfo, INP_In) && !m_bClosed)
  388.                                 ActivateOutput(pActInfo, INP_In, GetPortAny(pActInfo, INP_In));
  389.                         break;
  390.                 }
  391.         }
  392.  
  393.         virtual void GetMemoryUsage(ICrySizer* s) const
  394.         {
  395.                 s->Add(*this);
  396.         }
  397. };
  398.  
  399. //////////////////////////////////////////////////////////////////////////
  400. class CFlowNode_All : public CFlowBaseNode<eNCT_Instanced>
  401. {
  402. public:
  403.         static const int NUM_INPUTS = 6;
  404.  
  405.         CFlowNode_All(SActivationInfo* pActInfo) : m_inputCount(0)
  406.         {
  407.                 ResetState();
  408.         }
  409.  
  410.         void ResetState()
  411.         {
  412.                 for (unsigned i = 0; i < NUM_INPUTS; i++)
  413.                         m_triggered[i] = false;
  414.                 m_outputTrig = false;
  415.         }
  416.  
  417.         virtual IFlowNodePtr Clone(SActivationInfo* pActInfo)
  418.         {
  419.                 CFlowNode_All* clone = new CFlowNode_All(pActInfo);
  420.                 clone->m_inputCount = m_inputCount;
  421.                 return clone;
  422.         }
  423.  
  424.         virtual void Serialize(SActivationInfo*, TSerialize ser)
  425.         {
  426.                 char name[32];
  427.                 ser.Value("m_inputCount", m_inputCount);
  428.                 ser.Value("m_outputTrig", m_outputTrig);
  429.                 for (int i = 0; i < NUM_INPUTS; ++i)
  430.                 {
  431.                         cry_sprintf(name, "m_triggered_%d", i);
  432.                         ser.Value(name, m_triggered[i]);
  433.                 }
  434.         }
  435.  
  436.         virtual void GetConfiguration(SFlowNodeConfig& config)
  437.         {
  438.                 static const SInputPortConfig in_config[] = {
  439.                         InputPortConfig_Void("in1",   _HELP("Input 1")),
  440.                         InputPortConfig_Void("in2",   _HELP("Input 2")),
  441.                         InputPortConfig_Void("in3",   _HELP("Input 3")),
  442.                         InputPortConfig_Void("in4",   _HELP("Input 4")),
  443.                         InputPortConfig_Void("in5",   _HELP("Input 5")),
  444.                         InputPortConfig_Void("in6",   _HELP("Input 6")),
  445.                         InputPortConfig_Void("Reset", _HELP("Reset")),
  446.                         { 0 }
  447.                 };
  448.                 static const SOutputPortConfig out_config[] = {
  449.                         OutputPortConfig_Void("Out", _HELP("Output")),
  450.                         { 0 }
  451.                 };
  452.                 config.sDescription = _HELP("All - Triggers output when all connected inputs are triggered.");
  453.                 config.pInputPorts = in_config;
  454.                 config.pOutputPorts = out_config;
  455.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  456.                 config.SetCategory(EFLN_APPROVED);
  457.         }
  458.  
  459.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  460.         {
  461.                 switch (event)
  462.                 {
  463.                 case eFE_ConnectInputPort:
  464.                         // Count the number if inputs connected.
  465.                         if (pActInfo->connectPort < NUM_INPUTS)
  466.                                 m_inputCount++;
  467.                         break;
  468.                 case eFE_DisconnectInputPort:
  469.                         // Count the number if inputs connected.
  470.                         if (pActInfo->connectPort < NUM_INPUTS)
  471.                                 m_inputCount--;
  472.                         break;
  473.                 case eFE_Initialize:
  474.                         ResetState();
  475.                 // Fall through to check the input.
  476.                 case eFE_Activate:
  477.                         // Inputs
  478.                         int ntrig = 0;
  479.                         for (int i = 0; i < NUM_INPUTS; i++)
  480.                         {
  481.                                 if (!m_triggered[i] && IsPortActive(pActInfo, i))
  482.                                         m_triggered[i] = (event == eFE_Activate);
  483.                                 if (m_triggered[i])
  484.                                         ntrig++;
  485.                         }
  486.                         // Reset
  487.                         if (IsPortActive(pActInfo, NUM_INPUTS))
  488.                         {
  489.                                 ResetState();
  490.                                 ntrig = 0;
  491.                         }
  492.                         // If all inputs have been triggered, trigger output.
  493.                         // make sure we actually have connected inputs!
  494.                         if (!m_outputTrig && m_inputCount > 0 && ntrig == m_inputCount)
  495.                         {
  496.                                 ActivateOutput(pActInfo, 0, true);
  497.                                 m_outputTrig = (event == eFE_Activate);
  498.                         }
  499.                         break;
  500.                 }
  501.         }
  502.  
  503.         virtual void GetMemoryUsage(ICrySizer* s) const
  504.         {
  505.                 s->Add(*this);
  506.         }
  507.  
  508.         int  m_inputCount;
  509.         bool m_triggered[NUM_INPUTS];
  510.         bool m_outputTrig;
  511. };
  512.  
  513. //////////////////////////////////////////////////////////////////////////
  514. class CFlowNode_LogicOnce : public CFlowBaseNode<eNCT_Instanced>
  515. {
  516. public:
  517.         CFlowNode_LogicOnce(SActivationInfo* pActInfo) : m_bTriggered(false)
  518.         {
  519.         }
  520.  
  521.         virtual IFlowNodePtr Clone(SActivationInfo* pActInfo)
  522.         {
  523.                 return new CFlowNode_LogicOnce(pActInfo);
  524.         }
  525.  
  526.         virtual void Serialize(SActivationInfo*, TSerialize ser)
  527.         {
  528.                 ser.Value("m_bTriggered", m_bTriggered);
  529.         }
  530.  
  531.         virtual void GetConfiguration(SFlowNodeConfig& config)
  532.         {
  533.                 static const SInputPortConfig in_config[] = {
  534.                         InputPortConfig_AnyType("Input1"),
  535.                         InputPortConfig_AnyType("Input2"),
  536.                         InputPortConfig_AnyType("Input3"),
  537.                         InputPortConfig_AnyType("Input4"),
  538.                         InputPortConfig_AnyType("Input5"),
  539.                         InputPortConfig_AnyType("Input6"),
  540.                         InputPortConfig_Void("Reset",     _HELP("Reset (and allow new trigger)")),
  541.                         { 0 }
  542.                 };
  543.                 static const SOutputPortConfig out_config[] = {
  544.                         OutputPortConfig_AnyType("Out", _HELP("Output")),
  545.                         { 0 }
  546.                 };
  547.                 config.sDescription = _HELP("Triggers only once and passes from activated Input port to output port [Out].");
  548.                 config.pInputPorts = in_config;
  549.                 config.pOutputPorts = out_config;
  550.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  551.                 config.SetCategory(EFLN_APPROVED);
  552.         }
  553.  
  554.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  555.         {
  556.                 switch (event)
  557.                 {
  558.                 case eFE_Initialize:
  559.                         m_bTriggered = false;
  560.                         break;
  561.                 case eFE_Activate:
  562.                         if (m_bTriggered == false)
  563.                         {
  564.                                 for (int i = 0; i < 6; i++)
  565.                                 {
  566.                                         if (IsPortActive(pActInfo, i))
  567.                                         {
  568.                                                 ActivateOutput(pActInfo, 0, GetPortAny(pActInfo, i));
  569.                                                 m_bTriggered = true;
  570.                                                 break;
  571.                                         }
  572.                                 }
  573.                         }
  574.                         if (IsPortActive(pActInfo, 6))
  575.                                 m_bTriggered = false;
  576.                         break;
  577.                 }
  578.         }
  579.  
  580.         virtual void GetMemoryUsage(ICrySizer* s) const
  581.         {
  582.                 s->Add(*this);
  583.         }
  584.  
  585.         bool m_bTriggered;
  586. };
  587.  
  588. //////////////////////////////////////////////////////////////////////////
  589. class CFlowNode_LogicCountBlocker : public CFlowBaseNode<eNCT_Instanced>
  590. {
  591.         enum
  592.         {
  593.                 INP_In = 0,
  594.                 INP_Reset,
  595.                 INP_Limit,
  596.  
  597.                 OUT_Out = 0,
  598.         };
  599.  
  600. public:
  601.         CFlowNode_LogicCountBlocker(SActivationInfo* pActInfo) : m_timesTriggered(0)
  602.         {
  603.         }
  604.  
  605.         virtual IFlowNodePtr Clone(SActivationInfo* pActInfo)
  606.         {
  607.                 return new CFlowNode_LogicCountBlocker(pActInfo);
  608.         }
  609.  
  610.         virtual void Serialize(SActivationInfo*, TSerialize ser)
  611.         {
  612.                 ser.Value("timesTriggered", m_timesTriggered);
  613.         }
  614.  
  615.         virtual void GetConfiguration(SFlowNodeConfig& config)
  616.         {
  617.                 static const SInputPortConfig in_config[] =
  618.                 {
  619.                         InputPortConfig_AnyType("In"),
  620.                         InputPortConfig_Void("Reset", _HELP("Reset (counter starts from 0 again)")),
  621.                         InputPortConfig<int>("Limit", 1,                                            _HELP("How many times 'in' triggered values are sent to the output. After this number is reached, the output will not be triggered again (unless a reset is called)"),0, _UICONFIG("v_min=1,v_max=1000000000")),
  622.                         { 0 }
  623.                 };
  624.                 static const SOutputPortConfig out_config[] = {
  625.                         OutputPortConfig_AnyType("Out", _HELP("Output the value sent to 'in'")),
  626.                         { 0 }
  627.                 };
  628.                 config.sDescription = _HELP("The value triggered into 'in' is sent to 'out' a maximum number of times");
  629.                 config.pInputPorts = in_config;
  630.                 config.pOutputPorts = out_config;
  631.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  632.                 config.SetCategory(EFLN_APPROVED);
  633.         }
  634.  
  635.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  636.         {
  637.                 switch (event)
  638.                 {
  639.                 case eFE_Initialize:
  640.                         m_timesTriggered = 0;
  641.                         break;
  642.                 case eFE_Activate:
  643.                         int limit = GetPortInt(pActInfo, INP_Limit);
  644.  
  645.                         if (m_timesTriggered < limit && IsPortActive(pActInfo, INP_In))
  646.                         {
  647.                                 ActivateOutput(pActInfo, OUT_Out, GetPortAny(pActInfo, INP_In));
  648.                                 m_timesTriggered++;
  649.                                 break;
  650.                         }
  651.                         if (IsPortActive(pActInfo, INP_Reset))
  652.                                 m_timesTriggered = 0;
  653.                         break;
  654.                 }
  655.         }
  656.  
  657.         virtual void GetMemoryUsage(ICrySizer* s) const
  658.         {
  659.                 s->Add(*this);
  660.         }
  661.  
  662. private:
  663.         int m_timesTriggered;
  664. };
  665.  
  666. //////////////////////////////////////////////////////////////////////////
  667. class CFlowNode_LogicNoSerializeOnce : public CFlowBaseNode<eNCT_Instanced>
  668. {
  669. public:
  670.         CFlowNode_LogicNoSerializeOnce(SActivationInfo* pActInfo) : m_bTriggered(false)
  671.         {
  672.         }
  673.  
  674.         virtual IFlowNodePtr Clone(SActivationInfo* pActInfo)
  675.         {
  676.                 return new CFlowNode_LogicNoSerializeOnce(pActInfo);
  677.         }
  678.  
  679.         virtual void Serialize(SActivationInfo*, TSerialize ser)
  680.         {
  681.                 // this node IN PURPOSE does not serialize m_bTriggered. The whole idea of this node is to be used for things that have to be triggered only once in a level,
  682.                 // even if a previous savegame is loaded. Its first use is for Tutorial PopUps: after the player see one, that popup should not popup again even if the player loads a previous savegame.
  683.                 // It is not perfect: leaving the game, re-launching, and using the "Resume Game" option, will make the node to be triggered again if an input is activated.
  684.  
  685.                 //              ser.Value("m_bTriggered", m_bTriggered);
  686.         }
  687.  
  688.         virtual void GetConfiguration(SFlowNodeConfig& config)
  689.         {
  690.                 static const SInputPortConfig in_config[] = {
  691.                         InputPortConfig_AnyType("Input1"),
  692.                         InputPortConfig_Void("Reset",     _HELP("Reset (and allow new trigger)")),
  693.                         { 0 }
  694.                 };
  695.                 static const SOutputPortConfig out_config[] = {
  696.                         OutputPortConfig_AnyType("Out", _HELP("Output")),
  697.                         { 0 }
  698.                 };
  699.                 config.sDescription = _HELP("Triggers only once and passes from activated Input port to output port [Out]. \nWARNING!! The triggered flag is not serialized on savegame!. \nThis means that even if a previous savegame is loaded after the node has been triggered, the node wont be triggered again");
  700.                 config.pInputPorts = in_config;
  701.                 config.pOutputPorts = out_config;
  702.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  703.                 config.SetCategory(EFLN_APPROVED);
  704.         }
  705.  
  706.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  707.         {
  708.                 switch (event)
  709.                 {
  710.                 case eFE_Initialize:
  711.                         if (gEnv->IsEditor())
  712.                                 m_bTriggered = false;
  713.                         break;
  714.                 case eFE_Activate:
  715.                         if (m_bTriggered == false)
  716.                         {
  717.                                 for (int i = 0; i < 6; i++)
  718.                                 {
  719.                                         if (IsPortActive(pActInfo, i))
  720.                                         {
  721.                                                 ActivateOutput(pActInfo, 0, GetPortAny(pActInfo, i));
  722.                                                 m_bTriggered = true;
  723.                                                 break;
  724.                                         }
  725.                                 }
  726.                         }
  727.                         if (IsPortActive(pActInfo, 6))
  728.                                 m_bTriggered = false;
  729.                         break;
  730.                 }
  731.         }
  732.  
  733.         virtual void GetMemoryUsage(ICrySizer* s) const
  734.         {
  735.                 s->Add(*this);
  736.         }
  737.  
  738.         bool m_bTriggered;
  739. };
  740.  
  741. //////////////////////////////////////////////////////////////////////////
  742. class CFlowNode_RandomSelect : public CFlowBaseNode<eNCT_Singleton>
  743. {
  744. public:
  745.  
  746.         static const int NUM_OUTPUTS = 10;
  747.  
  748.         CFlowNode_RandomSelect(SActivationInfo* pActInfo) {}
  749.  
  750.         virtual void GetConfiguration(SFlowNodeConfig& config)
  751.         {
  752.                 static const SInputPortConfig in_config[] = {
  753.                         InputPortConfig_AnyType("In",  _HELP("Input")),
  754.                         InputPortConfig<int>("outMin", _HELP("Min number of outputs to activate.")),
  755.                         InputPortConfig<int>("outMax", _HELP("Max number of outputs to activate.")),
  756.                         { 0 }
  757.                 };
  758.  
  759.                 static const SOutputPortConfig out_config[] = {
  760.                         OutputPortConfig_AnyType("Out1",  _HELP("Output1")),
  761.                         OutputPortConfig_AnyType("Out2",  _HELP("Output2")),
  762.                         OutputPortConfig_AnyType("Out3",  _HELP("Output3")),
  763.                         OutputPortConfig_AnyType("Out4",  _HELP("Output4")),
  764.                         OutputPortConfig_AnyType("Out5",  _HELP("Output5")),
  765.                         OutputPortConfig_AnyType("Out6",  _HELP("Output6")),
  766.                         OutputPortConfig_AnyType("Out7",  _HELP("Output7")),
  767.                         OutputPortConfig_AnyType("Out8",  _HELP("Output8")),
  768.                         OutputPortConfig_AnyType("Out9",  _HELP("Output9")),
  769.                         OutputPortConfig_AnyType("Out10", _HELP("Output10")),
  770.                         { 0 }
  771.                 };
  772.                 config.sDescription = _HELP("Passes the activated input value to a random amount [outMin <= random <= outMax] outputs.");
  773.                 config.pInputPorts = in_config;
  774.                 config.pOutputPorts = out_config;
  775.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  776.                 config.SetCategory(EFLN_APPROVED);
  777.         }
  778.  
  779.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  780.         {
  781.                 switch (event)
  782.                 {
  783.                 case eFE_Initialize:
  784.                 case eFE_Activate:
  785.                         if (IsPortActive(pActInfo, 0))
  786.                         {
  787.                                 int minOut = GetPortInt(pActInfo, 1);
  788.                                 int maxOut = GetPortInt(pActInfo, 2);
  789.  
  790.                                 minOut = CLAMP(minOut, 0, NUM_OUTPUTS);
  791.                                 maxOut = CLAMP(maxOut, 0, NUM_OUTPUTS);
  792.                                 if (maxOut < minOut)
  793.                                         std::swap(minOut, maxOut);
  794.  
  795.                                 int n = cry_random(minOut, maxOut);
  796.  
  797.                                 // Collect the outputs to use
  798.                                 static int out[NUM_OUTPUTS];
  799.                                 for (unsigned i = 0; i < NUM_OUTPUTS; i++)
  800.                                         out[i] = -1;
  801.                                 int nout = 0;
  802.                                 for (int i = 0; i < NUM_OUTPUTS; i++)
  803.                                 {
  804.                                         if (IsOutputConnected(pActInfo, i))
  805.                                         {
  806.                                                 out[nout] = i;
  807.                                                 nout++;
  808.                                         }
  809.                                 }
  810.                                 if (n > nout)
  811.                                         n = nout;
  812.  
  813.                                 // Shuffle
  814.                                 for (int i = 0; i < n; i++)
  815.                                         std::swap(out[i], out[cry_random(0, nout - 1)]);
  816.  
  817.                                 // Set outputs.
  818.                                 for (int i = 0; i < n; i++)
  819.                                 {
  820.                                         if (out[i] == -1)
  821.                                                 continue;
  822.                                         ActivateOutput(pActInfo, out[i], GetPortAny(pActInfo, 0));
  823.                                 }
  824.  
  825.                         }
  826.                         break;
  827.                 }
  828.         }
  829.  
  830.         virtual void GetMemoryUsage(ICrySizer* s) const
  831.         {
  832.                 s->Add(*this);
  833.         }
  834. };
  835.  
  836. //////////////////////////////////////////////////////////////////////////
  837. class CFlowNode_RandomTrigger : public CFlowBaseNode<eNCT_Instanced>
  838. {
  839. public:
  840.  
  841.         static const int NUM_OUTPUTS = 10;
  842.  
  843.         CFlowNode_RandomTrigger(SActivationInfo* pActInfo) : m_nOutputCount(0) { Init(); Reset(); }
  844.  
  845.         enum INPUTS
  846.         {
  847.                 EIP_Input = 0,
  848.                 EIP_Reset,
  849.         };
  850.  
  851.         virtual void GetConfiguration(SFlowNodeConfig& config)
  852.         {
  853.                 static const SInputPortConfig in_config[] = {
  854.                         InputPortConfig_AnyType("In", _HELP("Input")),
  855.                         InputPortConfig_Void("Reset", _HELP("Reset randomness")),
  856.                         { 0 }
  857.                 };
  858.                 static const SOutputPortConfig out_config[] = {
  859.                         OutputPortConfig_AnyType("Out1",  _HELP("Output1")),
  860.                         OutputPortConfig_AnyType("Out2",  _HELP("Output2")),
  861.                         OutputPortConfig_AnyType("Out3",  _HELP("Output3")),
  862.                         OutputPortConfig_AnyType("Out4",  _HELP("Output4")),
  863.                         OutputPortConfig_AnyType("Out5",  _HELP("Output5")),
  864.                         OutputPortConfig_AnyType("Out6",  _HELP("Output6")),
  865.                         OutputPortConfig_AnyType("Out7",  _HELP("Output7")),
  866.                         OutputPortConfig_AnyType("Out8",  _HELP("Output8")),
  867.                         OutputPortConfig_AnyType("Out9",  _HELP("Output9")),
  868.                         OutputPortConfig_AnyType("Out10", _HELP("Output10")),
  869.                         OutputPortConfig_Void("Done",     _HELP("Triggered after all [connected] outputs have triggered")),
  870.                         { 0 }
  871.                 };
  872.                 config.sDescription = _HELP("On each [In] trigger, triggers one of the connected outputs in random order.");
  873.                 config.pInputPorts = in_config;
  874.                 config.pOutputPorts = out_config;
  875.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  876.                 config.SetCategory(EFLN_APPROVED);
  877.         }
  878.  
  879.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  880.         {
  881.                 switch (event)
  882.                 {
  883.                 case eFE_ConnectOutputPort:
  884.                         if (pActInfo->connectPort < NUM_OUTPUTS)
  885.                         {
  886.                                 ++m_nConnectionCounts[pActInfo->connectPort];
  887.                                 // check if already connected
  888.                                 for (int i = 0; i < m_nOutputCount; ++i)
  889.                                 {
  890.                                         if (m_nConnectedPorts[i] == pActInfo->connectPort)
  891.                                                 return;
  892.                                 }
  893.                                 m_nConnectedPorts[m_nOutputCount++] = pActInfo->connectPort;
  894.                                 Reset();
  895.                         }
  896.                         break;
  897.                 case eFE_DisconnectOutputPort:
  898.                         if (pActInfo->connectPort < NUM_OUTPUTS)
  899.                         {
  900.                                 for (int i = 0; i < m_nOutputCount; ++i)
  901.                                 {
  902.                                         // check if really connected
  903.                                         if (m_nConnectedPorts[i] == pActInfo->connectPort)
  904.                                         {
  905.                                                 if (m_nConnectionCounts[pActInfo->connectPort] == 1)
  906.                                                 {
  907.                                                         m_nConnectedPorts[i] = m_nPorts[m_nOutputCount - 1]; // copy last value to here
  908.                                                         m_nConnectedPorts[m_nOutputCount - 1] = -1;
  909.                                                         --m_nOutputCount;
  910.                                                         Reset();
  911.                                                 }
  912.                                                 --m_nConnectionCounts[pActInfo->connectPort];
  913.                                                 return;
  914.                                         }
  915.                                 }
  916.                         }
  917.                         break;
  918.                 case eFE_Initialize:
  919.                         Reset();
  920.                         break;
  921.  
  922.                 case eFE_Activate:
  923.                         if (IsPortActive(pActInfo, EIP_Reset))
  924.                         {
  925.                                 Reset();
  926.                         }
  927.                         if (IsPortActive(pActInfo, EIP_Input))
  928.                         {
  929.                                 int numCandidates = m_nOutputCount - m_nTriggered;
  930.                                 if (numCandidates <= 0)
  931.                                         return;
  932.                                 const int cand = cry_random(0, numCandidates - 1);
  933.                                 const int whichPort = m_nPorts[cand];
  934.                                 m_nPorts[cand] = m_nPorts[numCandidates - 1];
  935.                                 m_nPorts[numCandidates - 1] = -1;
  936.                                 ++m_nTriggered;
  937.                                 assert(whichPort >= 0 && whichPort < NUM_OUTPUTS);
  938.                                 // CryLogAlways("CFlowNode_RandomTrigger: Activating %d", whichPort);
  939.                                 ActivateOutput(pActInfo, whichPort, GetPortAny(pActInfo, EIP_Input));
  940.                                 assert(m_nTriggered > 0 && m_nTriggered <= m_nOutputCount);
  941.                                 if (m_nTriggered == m_nOutputCount)
  942.                                 {
  943.                                         // CryLogAlways("CFlowNode_RandomTrigger: Done.");
  944.                                         // Done
  945.                                         ActivateOutput(pActInfo, NUM_OUTPUTS, true);
  946.                                         Reset();
  947.                                 }
  948.                         }
  949.                         break;
  950.                 }
  951.         }
  952.  
  953.         void Init()
  954.         {
  955.                 for (int i = 0; i < NUM_OUTPUTS; ++i)
  956.                 {
  957.                         m_nConnectedPorts[i] = -1;
  958.                         m_nConnectionCounts[i] = 0;
  959.                 }
  960.         }
  961.  
  962.         void Reset()
  963.         {
  964.                 memcpy(m_nPorts, m_nConnectedPorts, sizeof(m_nConnectedPorts));
  965.                 m_nTriggered = 0;
  966.         }
  967.  
  968.         virtual void GetMemoryUsage(ICrySizer* s) const
  969.         {
  970.                 s->Add(*this);
  971.         }
  972.  
  973.         virtual IFlowNodePtr Clone(SActivationInfo* pActInfo)
  974.         {
  975.                 CFlowNode_RandomTrigger* pClone = new CFlowNode_RandomTrigger(pActInfo);
  976.                 // copy connected ports to cloned node
  977.                 // because atm. we don't send the  eFE_ConnectOutputPort or eFE_DisconnectOutputPort
  978.                 // to cloned graphs (see CFlowGraphBase::Clone)
  979.                 memcpy(pClone->m_nConnectedPorts, m_nConnectedPorts, sizeof(m_nConnectedPorts));
  980.                 memcpy(pClone->m_nConnectionCounts, m_nConnectionCounts, sizeof(m_nConnectionCounts));
  981.                 pClone->Reset();
  982.                 return pClone;
  983.         }
  984.  
  985.         virtual void Serialize(SActivationInfo*, TSerialize ser)
  986.         {
  987.                 char name[32];
  988.                 ser.Value("m_nOutputCount", m_nOutputCount);
  989.                 ser.Value("m_nTriggered", m_nTriggered);
  990.                 for (int i = 0; i < NUM_OUTPUTS; ++i)
  991.                 {
  992.                         cry_sprintf(name, "m_nPorts_%d", i);
  993.                         ser.Value(name, m_nPorts[i]);
  994.                 }
  995.                 // the m_nConnectedPorts must not be serialized. it's generated automatically
  996.                 // sanity check
  997.                 if (ser.IsReading())
  998.                 {
  999.                         bool bNeedReset = false;
  1000.                         for (int i = 0; i < NUM_OUTPUTS && !bNeedReset; ++i)
  1001.                         {
  1002.                                 bool bFound = false;
  1003.                                 for (int j = 0; j < NUM_OUTPUTS && !bFound; ++j)
  1004.                                 {
  1005.                                         bFound = (m_nPorts[i] == m_nConnectedPorts[j]);
  1006.                                 }
  1007.                                 bNeedReset = !bFound;
  1008.                         }
  1009.                         // if some of the serialized port can not be found, reset
  1010.                         if (bNeedReset)
  1011.                                 Reset();
  1012.                 }
  1013.         }
  1014.  
  1015.         int m_nConnectedPorts[NUM_OUTPUTS];   // array with port-numbers which are connected.
  1016.         int m_nPorts[NUM_OUTPUTS];            // permutation of m_nConnectedPorts array with m_nOutputCount valid entries
  1017.         int m_nConnectionCounts[NUM_OUTPUTS]; // number of connections on each port
  1018.         int m_nTriggered;
  1019.         int m_nOutputCount;
  1020. };
  1021.  
  1022. //////////////////////////////////////////////////////////////////////////
  1023. class CFlowNode_Sequentializer : public CFlowBaseNode<eNCT_Instanced>
  1024. {
  1025. public:
  1026.  
  1027.         enum
  1028.         {
  1029.                 NUM_OUTPUTS = 10,
  1030.                 PORT_NONE   = 0xffffffff,
  1031.         };
  1032.  
  1033.         CFlowNode_Sequentializer(SActivationInfo* pActInfo)
  1034.                 : m_needToCheckConnectedPorts(true)
  1035.                 , m_closed(false)
  1036.                 , m_lastTriggeredPort(PORT_NONE)
  1037.                 , m_numConnectedPorts(0)
  1038.         {
  1039.                 ZeroArray(m_connectedPorts);
  1040.         }
  1041.  
  1042.         enum INPUTS
  1043.         {
  1044.                 IN_Input = 0,
  1045.                 IN_Closed,
  1046.                 IN_Open,
  1047.                 IN_Close,
  1048.                 IN_Reset,
  1049.                 IN_Reverse
  1050.         };
  1051.  
  1052.         virtual void GetConfiguration(SFlowNodeConfig& config)
  1053.         {
  1054.                 static_assert(PORT_NONE + 1 == 0, "Unexpected enum value!"); // or else the automatic boundary checks when incrememting the port number would not work
  1055.  
  1056.                 static const SInputPortConfig in_config[] = {
  1057.                         InputPortConfig_AnyType("In",    _HELP("Input")),
  1058.                         InputPortConfig<bool>("Closed",  false,                                         _HELP("If true blocks all signals.")),
  1059.                         InputPortConfig_Void("Open",     _HELP("Sets [Closed] to false.")),
  1060.                         InputPortConfig_Void("Close",    _HELP("Sets [Closed] to true.")),
  1061.                         InputPortConfig_Void("Reset",    _HELP("Forces next output to be Port1 again")),
  1062.                         InputPortConfig<bool>("Reverse", false,                                         _HELP("If true, the order of output activation is reversed.")),
  1063.                         { 0 }
  1064.                 };
  1065.                 static const SOutputPortConfig out_config[] = {
  1066.                         OutputPortConfig_AnyType("Out1",  _HELP("Output1")),
  1067.                         OutputPortConfig_AnyType("Out2",  _HELP("Output2")),
  1068.                         OutputPortConfig_AnyType("Out3",  _HELP("Output3")),
  1069.                         OutputPortConfig_AnyType("Out4",  _HELP("Output4")),
  1070.                         OutputPortConfig_AnyType("Out5",  _HELP("Output5")),
  1071.                         OutputPortConfig_AnyType("Out6",  _HELP("Output6")),
  1072.                         OutputPortConfig_AnyType("Out7",  _HELP("Output7")),
  1073.                         OutputPortConfig_AnyType("Out8",  _HELP("Output8")),
  1074.                         OutputPortConfig_AnyType("Out9",  _HELP("Output9")),
  1075.                         OutputPortConfig_AnyType("Out10", _HELP("Output10")),
  1076.                         { 0 }
  1077.                 };
  1078.                 config.sDescription = _HELP("On each [In] trigger, triggers one of the connected outputs in sequential order.");
  1079.                 config.pInputPorts = in_config;
  1080.                 config.pOutputPorts = out_config;
  1081.                 config.nFlags |= EFLN_AISEQUENCE_SUPPORTED;
  1082.                 config.SetCategory(EFLN_APPROVED);
  1083.         }
  1084.  
  1085.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  1086.         {
  1087.                 switch (event)
  1088.                 {
  1089.                 case eFE_Initialize:
  1090.                         m_closed = GetPortBool(pActInfo, IN_Closed);
  1091.  
  1092.                 case eFE_ConnectOutputPort:
  1093.                 case eFE_DisconnectOutputPort:
  1094.                         {
  1095.                                 m_lastTriggeredPort = PORT_NONE;
  1096.                                 m_needToCheckConnectedPorts = true;
  1097.                                 m_numConnectedPorts = 0;
  1098.                                 break;
  1099.                         }
  1100.  
  1101.                 case eFE_Activate:
  1102.                         {
  1103.                                 if (IsPortActive(pActInfo, IN_Closed))
  1104.                                         m_closed = GetPortBool(pActInfo, IN_Closed);
  1105.                                 if (IsPortActive(pActInfo, IN_Open))
  1106.                                         m_closed = false;
  1107.                                 if (IsPortActive(pActInfo, IN_Close))
  1108.                                         m_closed = true;
  1109.  
  1110.                                 if (IsPortActive(pActInfo, IN_Reset))
  1111.                                 {
  1112.                                         m_lastTriggeredPort = PORT_NONE;
  1113.                                 }
  1114.  
  1115.                                 if (m_needToCheckConnectedPorts)
  1116.                                 {
  1117.                                         m_needToCheckConnectedPorts = false;
  1118.                                         m_numConnectedPorts = 0;
  1119.                                         for (int port = 0; port < NUM_OUTPUTS; ++port)
  1120.                                         {
  1121.                                                 if (IsOutputConnected(pActInfo, port))
  1122.                                                 {
  1123.                                                         m_connectedPorts[m_numConnectedPorts] = port;
  1124.                                                         m_numConnectedPorts++;
  1125.                                                 }
  1126.                                         }
  1127.                                 }
  1128.  
  1129.                                 if (IsPortActive(pActInfo, IN_Input) && m_numConnectedPorts > 0 && !m_closed)
  1130.                                 {
  1131.                                         bool reversed = GetPortBool(pActInfo, IN_Reverse);
  1132.                                         unsigned int port = m_lastTriggeredPort;
  1133.  
  1134.                                         if (reversed)
  1135.                                         {
  1136.                                                 port = min(m_numConnectedPorts - 1, port - 1); // this takes care of both the initial state when it has the PORT_NONE value, and the overflow in the normal decrement situation
  1137.                                         }
  1138.                                         else
  1139.                                         {
  1140.                                                 port = (port + 1) % m_numConnectedPorts;
  1141.                                         }
  1142.  
  1143.                                         ActivateOutput(pActInfo, m_connectedPorts[port], GetPortAny(pActInfo, IN_Input));
  1144.                                         m_lastTriggeredPort = port;
  1145.                                 }
  1146.                                 break;
  1147.                         }
  1148.                 }
  1149.         }
  1150.  
  1151.         virtual void GetMemoryUsage(ICrySizer* s) const
  1152.         {
  1153.                 s->Add(*this);
  1154.         }
  1155.  
  1156.         virtual IFlowNodePtr Clone(SActivationInfo* pActInfo)
  1157.         {
  1158.                 CFlowNode_Sequentializer* pClone = new CFlowNode_Sequentializer(pActInfo);
  1159.                 return pClone;
  1160.         }
  1161.  
  1162.         virtual void Serialize(SActivationInfo*, TSerialize ser)
  1163.         {
  1164.                 ser.Value("m_lastTriggeredPort", m_lastTriggeredPort);
  1165.                 ser.Value("m_closed", m_closed);
  1166.         }
  1167.  
  1168.         bool IsOutputConnected(SActivationInfo* pActInfo, int nPort) const
  1169.         {
  1170.                 SFlowAddress addr(pActInfo->myID, nPort, true);
  1171.                 return pActInfo->pGraph->IsOutputConnected(addr);
  1172.         }
  1173.  
  1174.         bool         m_needToCheckConnectedPorts;
  1175.         bool         m_closed;
  1176.         unsigned int m_lastTriggeredPort;
  1177.         unsigned int m_numConnectedPorts;
  1178.         int          m_connectedPorts[NUM_OUTPUTS];
  1179. };
  1180.  
  1181. REGISTER_FLOW_NODE("Logic:AND", CFlowNode_AND);
  1182. REGISTER_FLOW_NODE("Logic:OR", CFlowNode_OR);
  1183. REGISTER_FLOW_NODE("Logic:XOR", CFlowNode_XOR);
  1184. REGISTER_FLOW_NODE("Logic:NOT", CFlowNode_NOT);
  1185. REGISTER_FLOW_NODE("Logic:OnChange", CFlowNode_OnChange);
  1186. REGISTER_FLOW_NODE("Logic:Any", CFlowNode_Any);
  1187. REGISTER_FLOW_NODE("Logic:Blocker", CFlowNode_Blocker);
  1188. REGISTER_FLOW_NODE("Logic:All", CFlowNode_All);
  1189. REGISTER_FLOW_NODE("Logic:RandomSelect", CFlowNode_RandomSelect);
  1190. REGISTER_FLOW_NODE("Logic:RandomTrigger", CFlowNode_RandomTrigger);
  1191. REGISTER_FLOW_NODE("Logic:Once", CFlowNode_LogicOnce);
  1192. REGISTER_FLOW_NODE("Logic:CountBlocker", CFlowNode_LogicCountBlocker);
  1193. REGISTER_FLOW_NODE("Logic:NoSerializeOnce", CFlowNode_LogicNoSerializeOnce);
  1194. REGISTER_FLOW_NODE("Logic:Gate", CFlowNode_LogicGate);
  1195. REGISTER_FLOW_NODE("Logic:Sequentializer", CFlowNode_Sequentializer);
  1196.  
downloadFlowLogicNodes.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