BVB Source Codes

CRYENGINE Show FlowNodeAIHelicopter.cpp Source code

Return Download CRYENGINE: download FlowNodeAIHelicopter.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 "FlowEntityNode.h"
  5.  
  6. #include <CryAISystem/IAISystem.h>
  7. #include <CryAISystem/IAIObject.h>
  8. #include <CryAISystem/IAIActor.h>
  9.  
  10. namespace
  11. {
  12. void AISendSignal(IEntity* const pEntity, const char* const signalName)
  13. {
  14.         CRY_ASSERT(pEntity);
  15.         CRY_ASSERT(signalName);
  16.  
  17.         IAIObject* const pAiObject = pEntity->GetAI();
  18.         if (pAiObject)
  19.         {
  20.                 const uint32 signalNameCrc = CCrc32::Compute(signalName);
  21.                 gEnv->pAISystem->SendSignal(SIGNALFILTER_SENDER, 1, signalName, pAiObject, NULL, signalNameCrc);
  22.         }
  23. }
  24. }
  25.  
  26. //////////////////////////////////////////////////////////////////////////
  27. class CFlowNode_Helicopter_EnableCombatMode
  28.         : public CFlowBaseNode<eNCT_Singleton>
  29. {
  30.         enum INPUTS
  31.         {
  32.                 eInputPort_Enable,
  33.                 eInputPort_Disable,
  34.         };
  35.  
  36. public:
  37.         CFlowNode_Helicopter_EnableCombatMode(SActivationInfo* pActInfo)
  38.         {
  39.         }
  40.  
  41.         ~CFlowNode_Helicopter_EnableCombatMode()
  42.         {
  43.         }
  44.  
  45.         virtual void GetMemoryUsage(ICrySizer* s) const
  46.         {
  47.                 s->Add(*this);
  48.         }
  49.  
  50.         virtual void GetConfiguration(SFlowNodeConfig& config)
  51.         {
  52.                 static const SInputPortConfig inPorts[] =
  53.                 {
  54.                         InputPortConfig_Void("Enable"),
  55.                         InputPortConfig_Void("Disable"),
  56.                         { 0 }
  57.                 };
  58.  
  59.                 static const SOutputPortConfig outPorts[] =
  60.                 {
  61.                         { 0 }
  62.                 };
  63.  
  64.                 config.pInputPorts = inPorts;
  65.                 config.pOutputPorts = outPorts;
  66.                 config.nFlags |= EFLN_TARGET_ENTITY;
  67.                 config.sDescription = _HELP("When enabled, combat mode changes the behaviour from trying to strictly follow paths to trying to find the best position in the path from where to engage the target. The default state is disabled.");
  68.                 config.SetCategory(EFLN_APPROVED);
  69.         }
  70.  
  71.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  72.         {
  73.                 IEntity* pEntity = pActInfo->pEntity;
  74.                 if (pEntity == NULL)
  75.                 {
  76.                         return;
  77.                 }
  78.  
  79.                 switch (event)
  80.                 {
  81.                 case eFE_Activate:
  82.                         if (IsPortActive(pActInfo, eInputPort_Enable))
  83.                         {
  84.                                 AISendSignal(pEntity, "CombatTargetEnabled");
  85.                         }
  86.                         else if (IsPortActive(pActInfo, eInputPort_Disable))
  87.                         {
  88.                                 AISendSignal(pEntity, "CombatTargetDisabled");
  89.                         }
  90.                         break;
  91.                 }
  92.         }
  93. };
  94.  
  95. //////////////////////////////////////////////////////////////////////////
  96. class CFlowNode_Helicopter_EnableFiring
  97.         : public CFlowBaseNode<eNCT_Singleton>
  98. {
  99.         enum INPUTS
  100.         {
  101.                 eInputPort_Enable,
  102.                 eInputPort_Disable,
  103.         };
  104.  
  105. public:
  106.         CFlowNode_Helicopter_EnableFiring(SActivationInfo* pActInfo)
  107.         {
  108.         }
  109.  
  110.         ~CFlowNode_Helicopter_EnableFiring()
  111.         {
  112.         }
  113.  
  114.         virtual void GetMemoryUsage(ICrySizer* s) const
  115.         {
  116.                 s->Add(*this);
  117.         }
  118.  
  119.         virtual void GetConfiguration(SFlowNodeConfig& config)
  120.         {
  121.                 static const SInputPortConfig inPorts[] =
  122.                 {
  123.                         InputPortConfig_Void("Enable"),
  124.                         InputPortConfig_Void("Disable"),
  125.                         { 0 }
  126.                 };
  127.  
  128.                 static const SOutputPortConfig outPorts[] =
  129.                 {
  130.                         { 0 }
  131.                 };
  132.  
  133.                 config.pInputPorts = inPorts;
  134.                 config.pOutputPorts = outPorts;
  135.                 config.nFlags |= EFLN_TARGET_ENTITY;
  136.                 config.sDescription = _HELP("When enabled in combination with combat mode the AI is allowed to shoot at the target. If disabled it just tactically positions itself to places from where it can see/hit the target. The default state is enabled.");
  137.                 config.SetCategory(EFLN_APPROVED);
  138.         }
  139.  
  140.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  141.         {
  142.                 IEntity* pEntity = pActInfo->pEntity;
  143.                 if (pEntity == NULL)
  144.                 {
  145.                         return;
  146.                 }
  147.  
  148.                 switch (event)
  149.                 {
  150.                 case eFE_Activate:
  151.                         if (IsPortActive(pActInfo, eInputPort_Enable))
  152.                         {
  153.                                 AISendSignal(pEntity, "FiringAllowed");
  154.                         }
  155.                         else if (IsPortActive(pActInfo, eInputPort_Disable))
  156.                         {
  157.                                 AISendSignal(pEntity, "FiringNotAllowed");
  158.                         }
  159.                         break;
  160.                 }
  161.         }
  162. };
  163.  
  164. //////////////////////////////////////////////////////////////////////////
  165. class CFlowNode_Helicopter_FollowPath
  166.         : public CFlowBaseNode<eNCT_Instanced>
  167.         , public IEntityEventListener
  168. {
  169.         enum INPUTS
  170.         {
  171.                 eInputPort_Start,
  172.                 eInputPort_Stop,
  173.                 eInputPort_PathName,
  174.                 eInputPort_Loop,
  175.                 eInputPort_Speed,
  176.         };
  177.  
  178.         enum OUTPUTS
  179.         {
  180.                 eOutputPort_ArrivedAtEnd,
  181.                 eOutputPort_ArrivedNearToEnd,
  182.                 eOutputPort_Stopped,
  183.         };
  184.  
  185. public:
  186.         CFlowNode_Helicopter_FollowPath(SActivationInfo* pActInfo)
  187.                 : m_scriptEventEntityId(0)
  188.                 , m_activateArrivedAtPathEnd(false)
  189.                 , m_activateArrivedCloseToPathEnd(false)
  190.                 , m_activateStopped(false)
  191.                 , m_restartOnPostSerialize(false)
  192.         {
  193.         }
  194.  
  195.         ~CFlowNode_Helicopter_FollowPath()
  196.         {
  197.                 UnregisterAsPathNotificationListener();
  198.         }
  199.  
  200.         virtual IFlowNodePtr Clone(SActivationInfo *pActInfo)
  201.         {
  202.                 return new CFlowNode_Helicopter_FollowPath(pActInfo);
  203.         }
  204.  
  205.         virtual void GetMemoryUsage(ICrySizer* s) const
  206.         {
  207.                 s->Add(*this);
  208.         }
  209.  
  210.         virtual void GetConfiguration(SFlowNodeConfig& config)
  211.         {
  212.                 static const SInputPortConfig inPorts[] =
  213.                 {
  214.                         InputPortConfig_Void("Start"),
  215.                         InputPortConfig_Void("Stop"),
  216.                         InputPortConfig<string>("PathName"),
  217.                         InputPortConfig<bool>("LoopPath",   false),
  218.                         InputPortConfig<float>("Speed",     30),
  219.                         { 0 }
  220.                 };
  221.  
  222.                 static const SOutputPortConfig outPorts[] =
  223.                 {
  224.                         OutputPortConfig_Void("ArrivedAtEnd"),
  225.                         OutputPortConfig_Void("ArrivedNearToEnd"),
  226.                         OutputPortConfig_Void("Stopped"),
  227.                         { 0 }
  228.                 };
  229.  
  230.                 config.pInputPorts = inPorts;
  231.                 config.pOutputPorts = outPorts;
  232.                 config.nFlags |= EFLN_TARGET_ENTITY;
  233.                 config.sDescription = _HELP("Set the path the AI should follow. When not in combat mode it will follow as accurately as possible from start to end. When in combat mode it represents the path along where the AI is allowed to position itself/patrol.");
  234.                 config.SetCategory(EFLN_APPROVED);
  235.         }
  236.  
  237.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  238.         {
  239.                 IEntity* pEntity = pActInfo->pEntity;
  240.                 if (pEntity == NULL)
  241.                 {
  242.                         return;
  243.                 }
  244.  
  245.                 switch (event)
  246.                 {
  247.                 case eFE_Activate:
  248.                         if (IsPortActive(pActInfo, eInputPort_Start))
  249.                         {
  250.                                 NotifyCurrentListenerFollowPathStopped(pEntity);
  251.  
  252.                                 const bool loop = GetPortBool(pActInfo, eInputPort_Loop);
  253.                                 StartFollowPath(pActInfo, loop ? eSFPLM_StartFromClosestPathLocation : eSFPLM_StartFromBeginningOfPath);
  254.                         }
  255.                         else if (IsPortActive(pActInfo, eInputPort_Stop))
  256.                         {
  257.                                 ActivateOutput(pActInfo, eOutputPort_Stopped, true);
  258.                                 AISendSignal(pEntity, "StopFollowPath");
  259.                                 Reset(pActInfo);
  260.                         }
  261.                         else if (IsPortActive(pActInfo, eInputPort_Speed))
  262.                         {
  263.                                 ProcessEventSpeedPortActivated(pActInfo);
  264.                         }
  265.                         break;
  266.  
  267.                 case eFE_Update:
  268.                         {
  269.                                 bool reset = false;
  270.                                 if (m_activateArrivedCloseToPathEnd)
  271.                                 {
  272.                                         m_activateArrivedCloseToPathEnd = false;
  273.                                         ActivateOutput(pActInfo, eOutputPort_ArrivedNearToEnd, true);
  274.                                         // Don't reset, let's still keep listening for end or stop.
  275.                                 }
  276.  
  277.                                 if (m_activateArrivedAtPathEnd)
  278.                                 {
  279.                                         m_activateArrivedAtPathEnd = false;
  280.                                         ActivateOutput(pActInfo, eOutputPort_ArrivedAtEnd, true);
  281.                                         reset = true;
  282.                                 }
  283.  
  284.                                 if (m_activateStopped)
  285.                                 {
  286.                                         m_activateStopped = false;
  287.                                         ActivateOutput(pActInfo, eOutputPort_Stopped, true);
  288.                                         reset = true;
  289.                                 }
  290.  
  291.                                 if (reset)
  292.                                 {
  293.                                         Reset(pActInfo);
  294.                                 }
  295.                         }
  296.                         break;
  297.                 }
  298.         }
  299.  
  300.         void Reset(SActivationInfo* pActInfo)
  301.         {
  302.                 UnregisterAsPathNotificationListener();
  303.  
  304.                 m_activateArrivedAtPathEnd = false;
  305.                 m_activateArrivedCloseToPathEnd = false;
  306.                 m_activateStopped = false;
  307.  
  308.                 pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false);
  309.  
  310.                 m_restartOnPostSerialize = false;
  311.         }
  312.  
  313.         virtual void Serialize(SActivationInfo* pActInfo, TSerialize ser)
  314.         {
  315.                 ser.Value("m_restartOnPostSerialize", m_restartOnPostSerialize);
  316.         }
  317.  
  318.         virtual void PostSerialize(SActivationInfo* pActInfo)
  319.         {
  320.                 if (m_restartOnPostSerialize)
  321.                 {
  322.                         StartFollowPath(pActInfo, eSFPLM_StartFromClosestPathLocation);
  323.                 }
  324.         }
  325.  
  326.         virtual void OnEntityEvent(IEntity* pEntity, SEntityEvent& event)
  327.         {
  328.                 if (event.event != ENTITY_EVENT_SCRIPT_EVENT)
  329.                 {
  330.                         return;
  331.                 }
  332.  
  333.                 const char* eventName = reinterpret_cast<const char*>(event.nParam[0]);
  334.                 const uint32 eventNameCrc = CCrc32::Compute(eventName);
  335.  
  336.                 static const uint32 s_arrivedAtPathEndCrc = CCrc32::Compute("ArrivedAtPathEnd");
  337.                 static const uint32 s_arrivedCloseToPathEndCrc = CCrc32::Compute("ArrivedCloseToPathEnd");
  338.                 static const uint32 s_pathFollowingStoppedCrc = CCrc32::Compute("PathFollowingStopped");
  339.  
  340.                 if (eventNameCrc == s_arrivedAtPathEndCrc)
  341.                 {
  342.                         m_activateArrivedAtPathEnd = true;
  343.                 }
  344.                 else if (eventNameCrc == s_arrivedCloseToPathEndCrc)
  345.                 {
  346.                         m_activateArrivedCloseToPathEnd = true;
  347.                 }
  348.                 else if (eventNameCrc == s_pathFollowingStoppedCrc)
  349.                 {
  350.                         // Ignore event because the decision to stop the path following doesn't come from a different flownode, so it
  351.                         // means that the path hasn't changed so we will continue following it later (likely when exiting combat mode)
  352.                 }
  353.         }
  354.  
  355. private:
  356.         void RegisterAsPathNotificationListener(const EntityId entityId)
  357.         {
  358.                 UnregisterAsPathNotificationListener();
  359.  
  360.                 if (entityId)
  361.                 {
  362.                         CFlowNode_Helicopter_FollowPath* pNode = GetCurrentFollowPathNode(entityId);
  363.                         if (pNode)
  364.                         {
  365.                                 pNode->UnregisterAsPathNotificationListener();
  366.                         }
  367.                         SetCurrentFollowPathNode(entityId, this);
  368.  
  369.                         m_scriptEventEntityId = entityId;
  370.                         gEnv->pEntitySystem->AddEntityEventListener(m_scriptEventEntityId, ENTITY_EVENT_SCRIPT_EVENT, this);
  371.                 }
  372.         }
  373.  
  374.         void UnregisterAsPathNotificationListener()
  375.         {
  376.                 if (m_scriptEventEntityId)
  377.                 {
  378.                         CFlowNode_Helicopter_FollowPath* pNode = GetCurrentFollowPathNode(m_scriptEventEntityId);
  379.                         if (pNode == this)
  380.                         {
  381.                                 SetCurrentFollowPathNode(m_scriptEventEntityId, NULL);
  382.                         }
  383.  
  384.                         gEnv->pEntitySystem->RemoveEntityEventListener(m_scriptEventEntityId, ENTITY_EVENT_SCRIPT_EVENT, this);
  385.                         m_scriptEventEntityId = 0;
  386.                 }
  387.         }
  388.  
  389.         static CFlowNode_Helicopter_FollowPath* GetCurrentFollowPathNode(const EntityId entityId)
  390.         {
  391.                 IEntity* pEntity = gEnv->pEntitySystem->GetEntity(entityId);
  392.                 if (pEntity)
  393.                 {
  394.                         IScriptTable* pScriptTable = pEntity->GetScriptTable();
  395.                         if (pScriptTable)
  396.                         {
  397.                                 ScriptAnyValue value;
  398.                                 const bool getValueSuccess = pScriptTable->GetValueAny("Helicopter_FlowNodeFollowPath", value);
  399.                                 if (getValueSuccess)
  400.                                 {
  401.                                         CFlowNode_Helicopter_FollowPath* pNode = const_cast<CFlowNode_Helicopter_FollowPath*>(reinterpret_cast<const CFlowNode_Helicopter_FollowPath*>(value.ptr));
  402.                                         return pNode;
  403.                                 }
  404.                         }
  405.                 }
  406.                 return NULL;
  407.         }
  408.  
  409.         static void SetCurrentFollowPathNode(const EntityId entityId, CFlowNode_Helicopter_FollowPath* pNode)
  410.         {
  411.                 IEntity* pEntity = gEnv->pEntitySystem->GetEntity(entityId);
  412.                 if (pEntity)
  413.                 {
  414.                         IScriptTable* pScriptTable = pEntity->GetScriptTable();
  415.                         if (pScriptTable)
  416.                         {
  417.                                 ScriptAnyValue value;
  418.                                 value.type = ANY_THANDLE;
  419.                                 value.ptr = pNode;
  420.                                 pScriptTable->SetValueAny("Helicopter_FlowNodeFollowPath", value);
  421.                         }
  422.                 }
  423.         }
  424.  
  425.         void NotifyCurrentListenerFollowPathStopped(IEntity* pEntity)
  426.         {
  427.                 assert(pEntity);
  428.                 const EntityId entityId = pEntity->GetId();
  429.                 CFlowNode_Helicopter_FollowPath* pNode = GetCurrentFollowPathNode(entityId);
  430.                 if (pNode && pNode != this)
  431.                 {
  432.                         pNode->m_activateStopped = true;
  433.                 }
  434.         }
  435.  
  436.         void ProcessEventSpeedPortActivated(SActivationInfo* pActInfo)
  437.         {
  438.                 assert(pActInfo != NULL);
  439.  
  440.                 IEntity* pEntity = pActInfo->pEntity;
  441.                 if (pEntity == NULL)
  442.                 {
  443.                         return;
  444.                 }
  445.  
  446.                 IAIObject* pAiObject = pEntity->GetAI();
  447.                 IF_UNLIKELY (pAiObject == NULL)
  448.                 {
  449.                         return;
  450.                 }
  451.  
  452.                 IAIActor* pAiActor = pAiObject->CastToIAIActor();
  453.                 IF_UNLIKELY (pAiActor == NULL)
  454.                 {
  455.                         return;
  456.                 }
  457.  
  458.                 IScriptTable* pEntityTable = pEntity->GetScriptTable();
  459.                 IF_UNLIKELY (pEntityTable == NULL)
  460.                 {
  461.                         return;
  462.                 }
  463.  
  464.                 const float speed = GetPortFloat(pActInfo, eInputPort_Speed);
  465.  
  466.                 pEntityTable->SetValue("Helicopter_Speed", speed);
  467.         }
  468.  
  469.         enum StartFollowPathLocationMode
  470.         {
  471.                 eSFPLM_StartFromBeginningOfPath,
  472.                 eSFPLM_StartFromClosestPathLocation
  473.         };
  474.  
  475.         void StartFollowPath(SActivationInfo* pActInfo, const StartFollowPathLocationMode startPathLocationMode)
  476.         {
  477.                 IEntity* pEntity = pActInfo->pEntity;
  478.                 IF_UNLIKELY (pEntity == NULL)
  479.                 {
  480.                         return;
  481.                 }
  482.  
  483.                 Reset(pActInfo);
  484.  
  485.                 IScriptTable* pEntityTable = pEntity->GetScriptTable();
  486.                 IF_UNLIKELY (pEntityTable == NULL)
  487.                 {
  488.                         return;
  489.                 }
  490.  
  491.                 IAIObject* pAiObject = pEntity->GetAI();
  492.                 IF_UNLIKELY (pAiObject == NULL)
  493.                 {
  494.                         return;
  495.                 }
  496.  
  497.                 IAIActor* pAiActor = pAiObject->CastToIAIActor();
  498.                 IF_UNLIKELY (pAiActor == NULL)
  499.                 {
  500.                         return;
  501.                 }
  502.  
  503.                 const EntityId entityId = pEntity->GetId();
  504.                 RegisterAsPathNotificationListener(entityId);
  505.  
  506.                 const string& pathName = GetPortString(pActInfo, eInputPort_PathName);
  507.                 const bool loop = GetPortBool(pActInfo, eInputPort_Loop);
  508.                 const float speed = GetPortFloat(pActInfo, eInputPort_Speed);
  509.  
  510.                 pAiActor->SetPathToFollow(pathName.c_str());
  511.  
  512.                 pEntityTable->SetValue("Helicopter_Loop", loop);
  513.                 pEntityTable->SetValue("Helicopter_Speed", speed);
  514.  
  515.                 const bool startFromClosestLocation = (startPathLocationMode == eSFPLM_StartFromClosestPathLocation);
  516.                 pEntityTable->SetValue("Helicopter_StartFromClosestLocation", startFromClosestLocation);
  517.  
  518.                 pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true);
  519.  
  520.                 AISendSignal(pEntity, "StartFollowPath");
  521.  
  522.                 m_restartOnPostSerialize = true;
  523.         }
  524.  
  525. private:
  526.         EntityId m_scriptEventEntityId;
  527.         bool     m_activateArrivedAtPathEnd;
  528.         bool     m_activateArrivedCloseToPathEnd;
  529.         bool     m_activateStopped;
  530.  
  531.         bool     m_restartOnPostSerialize;
  532. };
  533.  
  534. //////////////////////////////////////////////////////////////////////////
  535. class CFlowNode_Helicopter_ForceFire
  536.         : public CFlowBaseNode<eNCT_Singleton>
  537.           , public IEntityEventListener
  538. {
  539.         enum INPUTS
  540.         {
  541.                 eInputPort_Enable,
  542.                 eInputPort_Disable,
  543.                 eInputPort_Target,
  544.         };
  545.  
  546.         enum OUTPUTS
  547.         {
  548.                 eOutputPort_Finished,
  549.         };
  550.  
  551. public:
  552.         CFlowNode_Helicopter_ForceFire(SActivationInfo* pActInfo)
  553.                 : m_scriptEventEntityId(0)
  554.                 , m_activateFinished(false)
  555.         {
  556.         }
  557.  
  558.         ~CFlowNode_Helicopter_ForceFire()
  559.         {
  560.                 UnregisterScriptEventListener();
  561.         }
  562.  
  563.         virtual void GetMemoryUsage(ICrySizer* s) const
  564.         {
  565.                 s->Add(*this);
  566.         }
  567.  
  568.         virtual void GetConfiguration(SFlowNodeConfig& config)
  569.         {
  570.                 static const SInputPortConfig inPorts[] =
  571.                 {
  572.                         InputPortConfig_Void("Enable"),
  573.                         InputPortConfig_Void("Disable"),
  574.                         InputPortConfig<EntityId>("Target"),
  575.                         { 0 }
  576.                 };
  577.  
  578.                 static const SOutputPortConfig outPorts[] =
  579.                 {
  580.                         OutputPortConfig_Void("Finished"),
  581.                         { 0 }
  582.                 };
  583.  
  584.                 config.pInputPorts = inPorts;
  585.                 config.pOutputPorts = outPorts;
  586.                 config.nFlags |= EFLN_TARGET_ENTITY;
  587.                 config.sDescription = _HELP("Forces the attention target of the fligh ai to a specific entity.");
  588.                 config.SetCategory(EFLN_APPROVED);
  589.         }
  590.  
  591.         virtual void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  592.         {
  593.                 IEntity* pEntity = pActInfo->pEntity;
  594.                 if (pEntity == NULL)
  595.                 {
  596.                         return;
  597.                 }
  598.  
  599.                 switch (event)
  600.                 {
  601.                 case eFE_Activate:
  602.                         if (IsPortActive(pActInfo, eInputPort_Enable))
  603.                         {
  604.                                 IScriptTable* pEntityTable = pEntity->GetScriptTable();
  605.                                 IF_UNLIKELY (pEntityTable == NULL)
  606.                                 {
  607.                                         return;
  608.                                 }
  609.  
  610.                                 const EntityId targetEntityId = GetPortEntityId(pActInfo, eInputPort_Target);
  611.                                 pEntityTable->SetValue("Helicopter_ForcedTargetId", targetEntityId);
  612.  
  613.                                 RegisterScriptEventlistener(pEntity->GetId());
  614.                                 pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true);
  615.  
  616.                                 AISendSignal(pEntity, "StartForceFire");
  617.                         }
  618.                         else if (IsPortActive(pActInfo, eInputPort_Disable))
  619.                         {
  620.                                 AISendSignal(pEntity, "StopForceFire");
  621.                         }
  622.                         break;
  623.  
  624.                 case eFE_Update:
  625.                         {
  626.                                 if (m_activateFinished)
  627.                                 {
  628.                                         ActivateOutput(pActInfo, eOutputPort_Finished, true);
  629.                                         Reset(pActInfo);
  630.                                 }
  631.                         }
  632.                         break;
  633.                 }
  634.         }
  635.  
  636.         virtual void OnEntityEvent(IEntity* pEntity, SEntityEvent& event)
  637.         {
  638.                 if (event.event != ENTITY_EVENT_SCRIPT_EVENT)
  639.                 {
  640.                         return;
  641.                 }
  642.  
  643.                 const char* eventName = reinterpret_cast<const char*>(event.nParam[0]);
  644.                 const uint32 eventNameCrc = CCrc32::Compute(eventName);
  645.  
  646.                 static const uint32 s_forceAttentionTargetFinishedCrc = CCrc32::Compute("ForceAttentionTargetFinished");
  647.  
  648.                 if (eventNameCrc == s_forceAttentionTargetFinishedCrc)
  649.                 {
  650.                         m_activateFinished = true;
  651.                 }
  652.         }
  653.  
  654. private:
  655.         void RegisterScriptEventlistener(const EntityId entityId)
  656.         {
  657.                 UnregisterScriptEventListener();
  658.  
  659.                 if (entityId)
  660.                 {
  661.                         m_scriptEventEntityId = entityId;
  662.                         gEnv->pEntitySystem->AddEntityEventListener(m_scriptEventEntityId, ENTITY_EVENT_SCRIPT_EVENT, this);
  663.                 }
  664.         }
  665.  
  666.         void UnregisterScriptEventListener()
  667.         {
  668.                 if (m_scriptEventEntityId)
  669.                 {
  670.                         gEnv->pEntitySystem->RemoveEntityEventListener(m_scriptEventEntityId, ENTITY_EVENT_SCRIPT_EVENT, this);
  671.                         m_scriptEventEntityId = 0;
  672.                 }
  673.         }
  674.  
  675.         void Reset(SActivationInfo* pActInfo)
  676.         {
  677.                 m_activateFinished = false;
  678.                 UnregisterScriptEventListener();
  679.                 pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false);
  680.         }
  681.  
  682. private:
  683.         EntityId m_scriptEventEntityId;
  684.         bool     m_activateFinished;
  685. };
  686.  
  687. REGISTER_FLOW_NODE("Vehicle:Helicopter:FollowPath", CFlowNode_Helicopter_FollowPath);
  688. REGISTER_FLOW_NODE("Vehicle:Helicopter:EnableCombatMode", CFlowNode_Helicopter_EnableCombatMode);
  689. REGISTER_FLOW_NODE("Vehicle:Helicopter:EnableFiring", CFlowNode_Helicopter_EnableFiring);
  690. REGISTER_FLOW_NODE("Vehicle:Helicopter:ForceFire", CFlowNode_Helicopter_ForceFire);
  691.  
downloadFlowNodeAIHelicopter.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