BVB Source Codes

CRYENGINE Show GoalPipe.cpp Source code

Return Download CRYENGINE: download GoalPipe.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 "GoalPipe.h"
  5.  
  6. #include "AILog.h"
  7. #include "CAISystem.h"
  8. #include "GameSpecific/GoalOp_Crysis2.h"
  9. #include "GameSpecific/GoalOp_G02.h"
  10. #include "GameSpecific/GoalOp_G04.h"    //TODO move these out of AISystem
  11. #include "GoalOp.h"
  12. #include "GoalOpStick.h"
  13. #include "GoalOpTrace.h"
  14. #include "Movement/MoveOp.h"
  15. #include "GoalOps/ShootOp.h"
  16. #include "GoalOps/TeleportOp.h"
  17. #include "GoalOpFactory.h"
  18. #include "PipeUser.h"
  19. #include "Mannequin/MannequinGoalOp.h"
  20.  
  21. #include <CrySystem/ISystem.h>
  22. #include <CryNetwork/ISerialize.h>
  23.  
  24. //#pragma optimize("", off)
  25. //#pragma inline_depth(0)
  26.  
  27. namespace
  28. {
  29. struct SAIGoalOpName
  30. {
  31.         EGoalOperations op;
  32.         const char*     szName;
  33. };
  34.  
  35. SAIGoalOpName g_GoalOpNames[] =
  36. {
  37.         { eGO_ACQUIRETARGET,        "acqtarget"            },
  38.         { eGO_ADJUSTAIM,            "adjustaim"            },
  39.         { eGO_PEEK,                 "peek"                 },
  40.         { eGO_ANIMATION,            "animation"            },
  41.         { eGO_ANIMTARGET,           "animtarget"           },
  42.         { eGO_APPROACH,             "approach"             },
  43.         { eGO_BACKOFF,              "backoff"              },
  44.         { eGO_BODYPOS,              "bodypos"              }, // Marcio: kept here for retro-compatibility
  45.         { eGO_BRANCH,               "branch"               },
  46.         { eGO_CHARGE,               "charge"               },
  47.         { eGO_CLEAR,                "clear"                },
  48.         { eGO_COMMUNICATE,          "communicate"          },
  49.         { eGO_DEVALUE,              "devalue"              },
  50.         { eGO_FIRECMD,              "firecmd"              },
  51.         { eGO_FOLLOWPATH,           "followpath"           },
  52.         { eGO_HIDE,                 "hide"                 },
  53.         { eGO_IGNOREALL,            "ignoreall"            },
  54.         { eGO_LOCATE,               "locate"               },
  55.         { eGO_LOOK,                 "look"                 },
  56.         { eGO_LOOKAROUND,           "lookaround"           },
  57.         { eGO_LOOKAT,               "lookat"               },
  58.         { eGO_PATHFIND,             "pathfind"             },
  59.         { eGO_RANDOM,               "random"               },
  60.         { eGO_RUN,                  "run"                  }, // Marcio: kept here for retro-compatibility
  61.         { eGO_SCRIPT,               "script"               },
  62.         { eGO_SEEKCOVER,            "seekcover"            },
  63.         { eGO_SIGNAL,               "signal"               },
  64.         { eGO_SPEED,                "speed"                },
  65.         { eGO_STANCE,               "stance"               },
  66.         { eGO_STICK,                "stick"                },
  67.         { eGO_STICKMINIMUMDISTANCE, "stickminimumdistance" },
  68.         { eGO_STICKPATH,            "stickpath"            },
  69.         { eGO_MOVE,                 "move"                 },
  70.         { eGO_SHOOT,                "shoot"                },
  71.         { eGO_TELEPORT,             "teleport"             },
  72.         { eGO_STRAFE,               "strafe"               },
  73.         { eGO_TACTICALPOS,          "tacticalpos"          },
  74.         { eGO_TIMEOUT,              "timeout"              },
  75.         { eGO_TRACE,                "trace"                },
  76.         { eGO_USECOVER,             "usecover"             },
  77.         { eGO_WAIT,                 "wait"                 },
  78.         { eGO_WAITSIGNAL,           "waitsignal"           },
  79.         { eGO_HOVER,                "hover"                },
  80.         { eGO_FLY,                  "fly"                  },
  81.         { eGO_CHASETARGET,          "chasetarget"          },
  82.         { eGO_FIREWEAPONS,          "fireWeapons"          },
  83.         { eGO_ACQUIREPOSITION,      "acquirePosition"      },
  84.         { eGO_SET_ANIMATION_TAG,    "setAnimationTag"      },
  85.         { eGO_CLEAR_ANIMATION_TAG,  "clearAnimationTag"    },
  86.  
  87.         { eGO_LAST,                 ""                     }, // Sentinel value - must end the array!
  88. };
  89. }
  90.  
  91. QGoal QGoal::Clone()
  92. {
  93.         QGoal goal;
  94.  
  95.         goal.op = op;
  96.  
  97.         if (pGoalOp)
  98.         {
  99.                 switch (op)
  100.                 {
  101.                 case eGO_ACQUIRETARGET:
  102.                         goal.pGoalOp = new COPAcqTarget(static_cast<const COPAcqTarget&>(*pGoalOp));
  103.                         break;
  104.                 case eGO_ADJUSTAIM:
  105.                         goal.pGoalOp = new COPCrysis2AdjustAim(static_cast<const COPCrysis2AdjustAim&>(*pGoalOp));
  106.                         break;
  107.                 case eGO_PEEK:
  108.                         goal.pGoalOp = new COPCrysis2Peek(static_cast<const COPCrysis2Peek&>(*pGoalOp));
  109.                         break;
  110.                 case eGO_ANIMATION:
  111.                         goal.pGoalOp = new COPAnimation(static_cast<const COPAnimation&>(*pGoalOp));
  112.                         break;
  113.                 case eGO_ANIMTARGET:
  114.                         goal.pGoalOp = new COPAnimTarget(static_cast<const COPAnimTarget&>(*pGoalOp));
  115.                         break;
  116.                 case eGO_APPROACH:
  117.                         goal.pGoalOp = new COPApproach(static_cast<const COPApproach&>(*pGoalOp));
  118.                         break;
  119.                 case eGO_BRANCH:
  120.                         goal.pGoalOp = (gAIEnv.configuration.eCompatibilityMode == ECCM_CRYSIS2)
  121.                                        ? static_cast<CGoalOp*>(new COPDummy)
  122.                                        : static_cast<CGoalOp*>(new COPDeValue);
  123.                         break;
  124.                 case eGO_BACKOFF:
  125.                         goal.pGoalOp = new COPBackoff(static_cast<const COPBackoff&>(*pGoalOp));
  126.                         break;
  127.                 case eGO_BODYPOS:
  128.                 case eGO_STANCE:
  129.                         goal.pGoalOp = new COPBodyCmd(static_cast<const COPBodyCmd&>(*pGoalOp));
  130.                         break;
  131.                 case eGO_CLEAR:
  132.                         goal.pGoalOp = new COPClear;
  133.                         break;
  134.                 case eGO_COMMUNICATE:
  135.                         goal.pGoalOp = new COPCommunication(static_cast<const COPCommunication&>(*pGoalOp));
  136.                         break;
  137.                 case eGO_DEVALUE:
  138.                         goal.pGoalOp = new COPDeValue(static_cast<const COPDeValue&>(*pGoalOp));
  139.                         break;
  140.                 case eGO_FIRECMD:
  141.                         goal.pGoalOp = new COPFireCmd(static_cast<const COPFireCmd&>(*pGoalOp));
  142.                         break;
  143.                 case eGO_FOLLOWPATH:
  144.                         goal.pGoalOp = new COPFollowPath(static_cast<const COPFollowPath&>(*pGoalOp));
  145.                         break;
  146.                 case eGO_HIDE:
  147.                         goal.pGoalOp = new COPCrysis2Hide(static_cast<const COPCrysis2Hide&>(*pGoalOp));
  148.                         break;
  149.                 case eGO_IGNOREALL:
  150.                         goal.pGoalOp = new COPIgnoreAll(static_cast<const COPIgnoreAll&>(*pGoalOp));
  151.                         break;
  152.                 case eGO_LOCATE:
  153.                         goal.pGoalOp = new COPLocate(static_cast<const COPLocate&>(*pGoalOp));
  154.                         break;
  155.                 case eGO_LOOK:
  156.                         goal.pGoalOp = new COPLook(static_cast<const COPLook&>(*pGoalOp));
  157.                         break;
  158.                 case eGO_LOOKAROUND:
  159.                         goal.pGoalOp = new COPLookAround(static_cast<const COPLookAround&>(*pGoalOp));
  160.                         break;
  161.                 case eGO_LOOKAT:
  162.                         goal.pGoalOp = new COPLookAt(static_cast<const COPLookAt&>(*pGoalOp));
  163.                         break;
  164.                 case eGO_PATHFIND:
  165.                         goal.pGoalOp = new COPPathFind(static_cast<const COPPathFind&>(*pGoalOp));
  166.                         break;
  167.                 case eGO_RUN:
  168.                 case eGO_SPEED:
  169.                         goal.pGoalOp = new COPRunCmd(static_cast<const COPRunCmd&>(*pGoalOp));
  170.                         break;
  171.                 case eGO_SCRIPT:
  172.                         goal.pGoalOp = new COPScript(static_cast<const COPScript&>(*pGoalOp));
  173.                         break;
  174.                 case eGO_SEEKCOVER:
  175.                         goal.pGoalOp = new COPSeekCover(static_cast<const COPSeekCover&>(*pGoalOp));
  176.                         break;
  177.                 case eGO_SIGNAL:
  178.                         goal.pGoalOp = new COPSignal(static_cast<const COPSignal&>(*pGoalOp));
  179.                         break;
  180.                 case eGO_STICK:
  181.                 case eGO_STICKMINIMUMDISTANCE:
  182.                         goal.pGoalOp = new COPStick(static_cast<const COPStick&>(*pGoalOp));
  183.                         break;
  184.                 case eGO_MOVE:
  185.                         goal.pGoalOp = new MoveOp(static_cast<const MoveOp&>(*pGoalOp));
  186.                         break;
  187.                 case eGO_SHOOT:
  188.                         goal.pGoalOp = new ShootOp(static_cast<const ShootOp&>(*pGoalOp));
  189.                         break;
  190.                 case eGO_TELEPORT:
  191.                         goal.pGoalOp = new TeleportOp(static_cast<const TeleportOp&>(*pGoalOp));
  192.                         break;
  193.                 case eGO_STICKPATH:
  194.                         goal.pGoalOp = new COPCrysis2StickPath(static_cast<const COPCrysis2StickPath&>(*pGoalOp));
  195.                         break;
  196.                 case eGO_STRAFE:
  197.                         goal.pGoalOp = new COPStrafe(static_cast<const COPStrafe&>(*pGoalOp));
  198.                         break;
  199.                 case eGO_TACTICALPOS:
  200.                         goal.pGoalOp = new COPTacticalPos(static_cast<const COPTacticalPos&>(*pGoalOp));
  201.                         break;
  202.                 case eGO_TIMEOUT:
  203.                         goal.pGoalOp = new COPTimeout(static_cast<const COPTimeout&>(*pGoalOp));
  204.                         break;
  205.                 case eGO_TRACE:
  206.                         goal.pGoalOp = new COPTrace(static_cast<const COPTrace&>(*pGoalOp));
  207.                         break;
  208.                 case eGO_WAIT:
  209.                         goal.pGoalOp = new COPWait(static_cast<const COPWait&>(*pGoalOp));
  210.                         break;
  211.                 case eGO_WAITSIGNAL:
  212.                         goal.pGoalOp = new COPWaitSignal(static_cast<const COPWaitSignal&>(*pGoalOp));
  213.                         break;
  214.                 case eGO_HOVER:
  215.                         goal.pGoalOp = new COPCrysis2Hover(static_cast<const COPCrysis2Hover&>(*pGoalOp));
  216.                         break;
  217.                 case eGO_FLY:
  218.                         goal.pGoalOp = new COPCrysis2Fly(static_cast<const COPCrysis2Fly&>(*pGoalOp));
  219.                         break;
  220.                 case eGO_CHASETARGET:
  221.                         goal.pGoalOp = new COPCrysis2ChaseTarget(static_cast<const COPCrysis2ChaseTarget&>(*pGoalOp));
  222.                         break;
  223.  
  224.                 case eGO_FIREWEAPONS:
  225.                         goal.pGoalOp = new COPCrysis2FlightFireWeapons(static_cast<COPCrysis2FlightFireWeapons&>(*pGoalOp));
  226.                         break;
  227.                 case eGO_ACQUIREPOSITION:
  228.                         goal.pGoalOp = new COPAcquirePosition(static_cast<COPAcquirePosition&>(*pGoalOp));
  229.                         break;
  230. #if 0
  231.                 // deprecated and won't compile at all...
  232.                 case eGO_STEER:
  233.                         goal.pGoalOp = new COPSteer(static_cast<const COPSteer&>(*pGoalOp));
  234.                         break;
  235.                 case eGO_COMPANIONSTICK:
  236.                         goal.pGoalOp = new COPCompanionStick(static_cast<const COPCompanionStick&>(*pGoalOp));
  237.                         break;
  238.                 case eGO_CONTINUOUS:
  239.                         goal.pGoalOp = new COPContinuous(static_cast<const COPContinuous&>(*pGoalOp));
  240.                         break;
  241.                 case eGO_DODGE:
  242.                         goal.pGoalOp = new COPDodge(static_cast<const COPDodge&>(*pGoalOp));
  243.                         break;
  244.                 case eGO_FORM:
  245.                         goal.pGoalOp = new COPForm(static_cast<const COPForm&>(*pGoalOp));
  246.                         break;
  247.                 case eGO_G4APPROACH:
  248.                         goal.pGoalOp = new COPG4Approach(static_cast<const COPG4Approach&>(*pGoalOp));
  249.                         break;
  250.                 case eGO_MOVETOWARDS:
  251.                         goal.pGoalOp = new COPMoveTowards(static_cast<const COPMoveTowards&>(*pGoalOp));
  252.                         break;
  253.                 case eGO_PROXIMITY:
  254.                         goal.pGoalOp = new COPProximity(static_cast<const COPProximity&>(*pGoalOp));
  255.                         break;
  256. #endif
  257.                 case eGO_SET_ANIMATION_TAG:
  258.                         goal.pGoalOp = new CSetAnimationTagGoalOp(static_cast<const CSetAnimationTagGoalOp&>(*pGoalOp));
  259.                         break;
  260.                 case eGO_CLEAR_ANIMATION_TAG:
  261.                         goal.pGoalOp = new CClearAnimationTagGoalOp(static_cast<const CClearAnimationTagGoalOp&>(*pGoalOp));
  262.                         break;
  263.  
  264.                 default:
  265.                         assert(!!!"What?!!");
  266.                 }
  267.         }
  268.  
  269.         goal.sPipeName = sPipeName; // The name of the possible pipe.
  270.  
  271.         //TODO evgeny Should go away when we have finally switch to XML
  272.         goal.params = params;
  273.  
  274.         goal.bBlocking = bBlocking;
  275.         goal.eGrouping = eGrouping;
  276.  
  277.         return goal;
  278. }
  279.  
  280. void QGoal::Serialize(TSerialize ser)
  281. {
  282.         ser.EnumValue("op", op, eGO_FIRST, eGO_LAST);
  283.         ser.Value("sPipeName", sPipeName);
  284.         ser.Value("bBlocking", bBlocking);
  285.         ser.EnumValue("eGrouping", eGrouping, IGoalPipe::eGT_NOGROUP, IGoalPipe::eGT_LAST);
  286.         pGoalOp->Serialize(ser);
  287. }
  288.  
  289. CGoalPipe::CGoalPipe(const char* sName, bool bDynamic)
  290.         : m_sName(sName),
  291.         m_bDynamic(bDynamic),
  292.         m_nPosition(0),
  293.         m_pSubPipe(0),
  294.         m_bLoop(true),
  295.         m_nEventId(0),
  296.         m_bHighPriority(false),
  297.         m_bKeepOnTop(false),
  298.         m_nCurrentBlockCounter(0),
  299.         m_lastResult(eGOR_NONE)
  300. {
  301.         PREFAST_SUPPRESS_WARNING(6326) static_assert(CRY_ARRAY_COUNT(g_GoalOpNames) == eGO_LAST + 1, "Invalid array size!");
  302. }
  303.  
  304. CGoalPipe::~CGoalPipe()
  305. {
  306.         if (!m_qGoalPipe.empty())
  307.         {
  308.                 m_qGoalPipe.clear();
  309.         }
  310.  
  311.         SAFE_DELETE(m_pSubPipe);
  312. }
  313.  
  314. CGoalPipe* CGoalPipe::Clone()
  315. {
  316.         CGoalPipe* pClone = new CGoalPipe(m_sName, true);
  317.  
  318.         // copy the labels
  319.         if (!m_Labels.empty())
  320.         {
  321.                 // convert labels to offsets before cloning
  322.                 for (VectorOGoals::iterator gi = m_qGoalPipe.begin(); gi != m_qGoalPipe.end(); ++gi)
  323.                 {
  324.                         if (!gi->params.str.empty() && (gi->op == eGO_BRANCH || gi->op == eGO_RANDOM))
  325.                         {
  326.                                 LabelsMap::iterator it = m_Labels.find(gi->params.str);
  327.                                 if (it != m_Labels.end())
  328.                                 {
  329.                                         int absolute = it->second;
  330.                                         int current = (int)(gi - m_qGoalPipe.begin());
  331.                                         if (current < absolute)
  332.                                                 gi->params.nValueAux = absolute - current - 1;
  333.                                         else if (current > absolute)
  334.                                                 gi->params.nValueAux = absolute - current;
  335.                                         else
  336.                                         {
  337.                                                 gi->params.nValueAux = 0;
  338.                                                 AIWarning("Empty loop at label %s ignored in goal pipe %s.", gi->params.str.c_str(), m_sName.c_str());
  339.                                         }
  340.                                 }
  341.                                 else
  342.                                 {
  343.                                         gi->params.nValueAux = 0;
  344.                                         AIWarning("Label %s not found in goal pipe %s.", gi->params.str.c_str(), m_sName.c_str());
  345.                                 }
  346.                                 gi->params.str.clear();
  347.                         }
  348.                 }
  349.  
  350.                 // we don't need the labels anymore
  351.                 m_Labels.clear();
  352.         }
  353.  
  354.         for (VectorOGoals::iterator gi = m_qGoalPipe.begin(); gi != m_qGoalPipe.end(); ++gi)
  355.         {
  356.                 QGoal& goal = (*gi);
  357.                 if (goal.op != eGO_LAST)
  358.                         pClone->m_qGoalPipe.push_back(goal.Clone());
  359.                 else
  360.                         pClone->PushPipe(goal.sPipeName.c_str(), goal.bBlocking, goal.eGrouping, goal.params);
  361.         }
  362.  
  363.         return pClone;
  364. }
  365.  
  366. void CGoalPipe::PushGoal(const XmlNodeRef& goalOpNode, EGroupType eGrouping)
  367. {
  368.         const char* szGoalOpName = goalOpNode->getTag();
  369.  
  370.         EGoalOperations op = CGoalPipe::GetGoalOpEnum(szGoalOpName);
  371.         if (op == eGO_LAST)
  372.         {
  373.                 AIError("Goal pipe '%s': Tag '%s' is not recognized as a goalop name; skipping.",
  374.                         GetName(), szGoalOpName);
  375.                 return;
  376.         }
  377.  
  378.         CGoalOp* pGoalOp = CreateGoalOp(op, goalOpNode);
  379.         assert(pGoalOp);
  380.         if (pGoalOp)
  381.         {
  382.                 QGoal newgoal;
  383.                 newgoal.pGoalOp = pGoalOp;
  384.                 newgoal.op = op;
  385.                 newgoal.sPipeName = CGoalPipe::GetGoalOpName(op); // Goals should know their own names soon
  386.                 newgoal.bBlocking = (stricmp(goalOpNode->getAttr("blocking"), "false") != 0);
  387.                 newgoal.eGrouping = eGrouping;
  388.  
  389.                 m_qGoalPipe.push_back(newgoal);
  390.         }
  391. }
  392.  
  393. CGoalOp* CGoalPipe::CreateGoalOp(EGoalOperations op, const XmlNodeRef& goalOpNode)
  394. {
  395.         switch (op)
  396.         {
  397.         case eGO_ACQUIRETARGET:
  398.                 return new COPAcqTarget(goalOpNode);
  399.         case eGO_ADJUSTAIM:
  400.                 return new COPCrysis2AdjustAim(goalOpNode);
  401.         case eGO_PEEK:
  402.                 return new COPCrysis2Peek(goalOpNode);
  403.         case eGO_ANIMATION:
  404.                 return new COPAnimation(goalOpNode);
  405.         case eGO_ANIMTARGET:
  406.                 return new COPAnimTarget(goalOpNode);
  407.         case eGO_APPROACH:
  408.                 return new COPApproach(goalOpNode);
  409.         case eGO_BACKOFF:
  410.                 return new COPBackoff(goalOpNode);
  411.         case eGO_BODYPOS:
  412.         case eGO_STANCE:
  413.                 return new COPBodyCmd(goalOpNode);
  414.         case eGO_BRANCH:
  415.                 return (gAIEnv.configuration.eCompatibilityMode == ECCM_CRYSIS2)
  416.                        ? static_cast<CGoalOp*>(new COPDummy)
  417.                        : static_cast<CGoalOp*>(new COPDeValue);
  418.         case eGO_CLEAR:
  419.                 return new COPClear;
  420.         case eGO_COMMUNICATE:
  421.                 return new COPCommunication(goalOpNode);
  422.         case eGO_DEVALUE:
  423.                 return new COPDeValue(goalOpNode);
  424.         case eGO_FIRECMD:
  425.                 return new COPFireCmd(goalOpNode);
  426.         case eGO_FOLLOWPATH:
  427.                 return new COPFollowPath(goalOpNode);
  428.         case eGO_HIDE:
  429.                 return new COPCrysis2Hide(goalOpNode);
  430.         case eGO_IGNOREALL:
  431.                 return new COPIgnoreAll(goalOpNode);
  432.         case eGO_LOCATE:
  433.                 return new COPLocate(goalOpNode);
  434.         case eGO_LOOK:
  435.                 return new COPLook(goalOpNode);
  436.         case eGO_LOOKAROUND:
  437.                 return new COPLookAround(goalOpNode);
  438.         case eGO_LOOKAT:
  439.                 return new COPLookAt(goalOpNode);
  440.         case eGO_PATHFIND:
  441.                 return new COPPathFind(goalOpNode);
  442.         case eGO_RUN:
  443.         case eGO_SPEED:
  444.                 return new COPRunCmd(goalOpNode);
  445.         case eGO_SCRIPT:
  446.                 return new COPScript(goalOpNode);
  447.         case eGO_SEEKCOVER:
  448.                 return new COPSeekCover(goalOpNode);
  449.         case eGO_SIGNAL:
  450.                 return new COPSignal(goalOpNode);
  451.         case eGO_STICK:
  452.                 return new COPStick(goalOpNode);
  453.         case eGO_STICKMINIMUMDISTANCE:
  454.                 return new COPStick(goalOpNode);
  455.         case eGO_MOVE:
  456.                 return new MoveOp(goalOpNode);
  457.         case eGO_SHOOT:
  458.                 return new ShootOp(goalOpNode);
  459.         case eGO_TELEPORT:
  460.                 return new TeleportOp(goalOpNode);
  461.         case eGO_STICKPATH:
  462.                 return new COPCrysis2StickPath(goalOpNode);
  463.         case eGO_STRAFE:
  464.                 return new COPStrafe(goalOpNode);
  465.         case eGO_TACTICALPOS:
  466.                 return new COPTacticalPos(goalOpNode);
  467.         case eGO_TIMEOUT:
  468.                 return new COPTimeout(goalOpNode);
  469.         case eGO_TRACE:
  470.                 return new COPTrace(goalOpNode);
  471.         case eGO_WAIT:
  472.                 return new COPWait(goalOpNode);
  473.         case eGO_WAITSIGNAL:
  474.                 return new COPWaitSignal(goalOpNode);
  475.         case eGO_HOVER:
  476.                 return new COPCrysis2Hover(goalOpNode);
  477.         case eGO_FLY:
  478.                 return new COPCrysis2Fly(goalOpNode);
  479.         case eGO_CHASETARGET:
  480.                 return new COPCrysis2ChaseTarget(goalOpNode);
  481.         case eGO_FIREWEAPONS:
  482.                 return new COPCrysis2FlightFireWeapons(goalOpNode);
  483.         case eGO_ACQUIREPOSITION:
  484.                 return new COPAcquirePosition(goalOpNode);
  485. #if 0
  486.         // deprecated and won't compile at all...
  487.         case eGO_CONTINUOUS:
  488.                 return new COPContinuous(goalOpNode);
  489.         case eGO_MOVETOWARDS:
  490.                 return new COPMoveTowards(goalOpNode);
  491.         case eGO_FORM:
  492.                 return new COPForm(goalOpNode);
  493.         case eGO_G4APPROACH:
  494.                 return new COPG4Approach(goalOpNode);
  495.         case eGO_DODGE:
  496.                 return new COPDodge(goalOpNode);
  497.         case eGO_COMPANIONSTICK:
  498.                 return new COPCompanionStick(goalOpNode);
  499.         case eGO_STEER:
  500.                 return new COPSteer(goalOpNode);
  501.         case eGO_PROXIMITY:
  502.                 return new COPProximity(goalOpNode);
  503. #endif
  504.  
  505.         case eGO_SET_ANIMATION_TAG:
  506.                 return new CSetAnimationTagGoalOp(goalOpNode);
  507.         case eGO_CLEAR_ANIMATION_TAG:
  508.                 return new CClearAnimationTagGoalOp(goalOpNode);
  509.  
  510.         default:
  511.                 AIError("Unrecognized goalop code: %d.", (int)(op));
  512.                 assert(!!!"Unrecognized goalop code.");
  513.                 return 0;
  514.         }
  515. }
  516.  
  517. void CGoalPipe::SetDebugName(const char* name)
  518. {
  519.         m_sDebugName = name;
  520. }
  521.  
  522. void CGoalPipe::ParseParams(const GoalParams& node)
  523. {
  524.         for (VectorOGoals::iterator it = m_qGoalPipe.begin(); m_qGoalPipe.end() != it; ++it)
  525.         {
  526.                 if (it->pGoalOp)
  527.                         it->pGoalOp->ParseParams(node);
  528.                 else
  529.                         assert(it->pGoalOp.get());
  530.         }
  531. }
  532.  
  533. void CGoalPipe::ParseParam(const char* param, const GoalParams& value)
  534. {
  535.         for (VectorOGoals::iterator it = m_qGoalPipe.begin(); m_qGoalPipe.end() != it; ++it)
  536.         {
  537.                 it->pGoalOp->ParseParam(param, value);
  538.         }
  539. }
  540.  
  541. void CGoalPipe::PushLabel(const char* label)
  542. {
  543.         LabelsMap::iterator it = m_Labels.find(CONST_TEMP_STRING(label));
  544.         if (it != m_Labels.end())
  545.                 AIWarning("Label %s already exists in goal pipe %s. Overriding previous label!", label, m_sName.c_str());
  546.  
  547.         m_Labels[label] = m_qGoalPipe.size();
  548. }
  549.  
  550. EGoalOperations CGoalPipe::GetGoalOpEnum(const char* szName)
  551. {
  552.         for (SAIGoalOpName* opName = g_GoalOpNames; opName->op != eGO_LAST; ++opName)
  553.         {
  554.                 // [2/10/2010 evgeny] Changed "strcmp" to "stricmp" to accommodate names like "SeekCoverPos"
  555.                 if (!stricmp(opName->szName, szName)) // Compare the op names
  556.                 {
  557.                         return opName->op;
  558.                 }
  559.         }
  560.  
  561.         return eGO_LAST;
  562. }
  563.  
  564. const char* CGoalPipe::GetGoalOpName(EGoalOperations op)
  565. {
  566.         return (op < eGO_LAST) ? g_GoalOpNames[op].szName : 0;
  567. }
  568.  
  569. void CGoalPipe::PushGoal(EGoalOperations op, bool bBlocking, EGroupType eGrouping, GoalParameters& params)
  570. {
  571.         // Note that very few of the individual goalops manipulate the blocking or grouping params
  572.         QGoal newgoal;
  573.  
  574.         if (op != eGO_WAIT)
  575.         {
  576.                 if (eGrouping == IGoalPipe::eGT_GROUPED)
  577.                 {
  578.                         ++m_nCurrentBlockCounter;
  579.                 }
  580.                 else
  581.                 {
  582.                         m_nCurrentBlockCounter = 0; // continuous group counter.
  583.                 }
  584.         }
  585.  
  586.         // Try the factories first
  587.         newgoal.pGoalOp = static_cast<CGoalOp*>(gAIEnv.pGoalOpFactory->GetGoalOp(op, params));
  588.         if (newgoal.pGoalOp)
  589.         {
  590.                 // Could adjust the ops below to avoid this redundancy
  591.                 newgoal.op = op;
  592.                 newgoal.params = params;
  593.                 newgoal.bBlocking = bBlocking;
  594.                 newgoal.eGrouping = eGrouping;
  595.                 m_qGoalPipe.push_back(newgoal);
  596.                 return;
  597.         }
  598.  
  599.         switch (op)
  600.         {
  601.         case eGO_ACQUIRETARGET:
  602.                 {
  603.                         newgoal.pGoalOp = new COPAcqTarget(params.str);
  604.                 }
  605.                 break;
  606.         case eGO_APPROACH:
  607.                 {
  608.                         float duration, endDistance;
  609.                         if (params.nValue & AI_USE_TIME)
  610.                         {
  611.                                 duration = fabsf(params.fValue);
  612.                                 endDistance = 0.0f;
  613.                         }
  614.                         else
  615.                         {
  616.                                 duration = 0.0f;
  617.                                 endDistance = params.fValue;
  618.                         }
  619.  
  620.                         // Random variation on the end distance.
  621.                         if (params.vPos.x > 0.01f)
  622.                         {
  623.                                 float u = cry_random(0, 9) / 9.0f;
  624.                                 if (endDistance > 0.0f)
  625.                                         endDistance = max(0.0f, endDistance - u * params.vPos.x);
  626.                                 else
  627.                                         endDistance = min(0.0f, endDistance + u * params.vPos.x);
  628.                         }
  629.  
  630.                         newgoal.pGoalOp = new COPApproach(endDistance, params.fValueAux, duration,
  631.                                                           (params.nValue & AILASTOPRES_USE) != 0, (params.nValue & AILASTOPRES_LOOKAT) != 0,
  632.                                                           (params.nValue & AI_REQUEST_PARTIAL_PATH) != 0, (params.nValue & AI_STOP_ON_ANIMATION_START) != 0, params.str);
  633.                 }
  634.                 break;
  635.         case eGO_FOLLOWPATH:
  636.                 {
  637.                         bool pathFindToStart = (params.nValue & 1) != 0;
  638.                         bool reverse = (params.nValue & 2) != 0;
  639.                         bool startNearest = (params.nValue & 4) != 0;
  640.                         bool usePointList = (params.nValue & 8) != 0;
  641.                         bool controlSpeed = (params.nValue & 16) != 0;
  642.                         newgoal.pGoalOp = new COPFollowPath(pathFindToStart, reverse, startNearest, params.nValueAux, params.fValueAux, usePointList, controlSpeed, params.fValue);
  643.                 }
  644.                 break;
  645.         case eGO_BACKOFF:
  646.                 {
  647.                         newgoal.pGoalOp = new COPBackoff(params.fValue, params.fValueAux, params.nValue);
  648.                 }
  649.                 break;
  650.         case eGO_FIRECMD:
  651.                 {
  652.                         newgoal.pGoalOp = new COPFireCmd(static_cast<EFireMode>(params.nValue), params.bValue, params.fValue, params.fValueAux);
  653.                 }
  654.                 break;
  655.         case eGO_STANCE:
  656.         case eGO_BODYPOS:
  657.                 {
  658.                         newgoal.pGoalOp = new COPBodyCmd(static_cast<EStance>(params.nValue), params.bValue);
  659.                 }
  660.                 break;
  661.         case eGO_STRAFE:
  662.                 {
  663.                         newgoal.pGoalOp = new COPStrafe(params.fValue, params.fValueAux, params.bValue);
  664.                 }
  665.                 break;
  666.         case eGO_TIMEOUT:
  667.                 {
  668.                         if (!gEnv->pSystem)
  669.                                 AIError("CGoalPipe::PushGoal Pushing goals without a valid System instance [Code bug]");
  670.  
  671.                         newgoal.pGoalOp = new COPTimeout(params.fValue, params.fValueAux);
  672.                 }
  673.                 break;
  674.         case eGO_SPEED:
  675.         case eGO_RUN:
  676.                 {
  677.                         newgoal.pGoalOp = new COPRunCmd(params.fValue, params.fValueAux, params.vPos.x);
  678.                 }
  679.                 break;
  680.         case eGO_LOOKAROUND:
  681.                 {
  682.                         newgoal.pGoalOp = new COPLookAround(params.fValue, params.fValueAux, params.vPos.x, params.vPos.y, params.nValueAux != 0, (params.nValue & AI_BREAK_ON_LIVE_TARGET) != 0, (params.nValue & AILASTOPRES_USE) != 0, params.bValue);
  683.                 }
  684.                 break;
  685.         case eGO_LOCATE:
  686.                 {
  687.                         newgoal.pGoalOp = new COPLocate(params.str.c_str(), params.nValue, params.fValue);
  688.                 }
  689.                 break;
  690.         case eGO_PATHFIND:
  691.                 {
  692.                         newgoal.pGoalOp = new COPPathFind(params.str.c_str(), static_cast<CAIObject*>(params.pTarget), 0.f, 0.f, (params.nValue & AI_REQUEST_PARTIAL_PATH) ? 1.f : 0.f);
  693.                 }
  694.                 break;
  695.         case eGO_TRACE:
  696.                 {
  697.                         bool bParam = (params.nValue > 0);
  698.                         newgoal.pGoalOp = new COPTrace(bParam, params.fValue, params.nValueAux > 0);
  699.                 }
  700.                 break;
  701.         case eGO_IGNOREALL:
  702.                 {
  703.                         newgoal.pGoalOp = new COPIgnoreAll(params.bValue);
  704.                 }
  705.                 break;
  706.         case eGO_SIGNAL:
  707.                 {
  708.                         newgoal.pGoalOp = new COPSignal(params.nValueAux, params.str, static_cast<ESignalFilter>(params.nValue), (int)params.fValueAux);
  709.                 }
  710.                 break;
  711.         case eGO_SCRIPT:
  712.                 {
  713.                         newgoal.pGoalOp = new COPScript(params.scriptCode);
  714.                 }
  715.                 break;
  716.         case eGO_DEVALUE:
  717.                 {
  718.                         newgoal.pGoalOp = new COPDeValue((int)params.fValue, params.bValue);
  719.                 }
  720.                 break;
  721. #if 0
  722.         // deprecated and won't compile at all...
  723.         case eGO_HIDE:
  724.                 {
  725.                         newgoal.pGoalOp = new COPHide(params.fValue, params.fValueAux, params.nValue, params.bValue,
  726.                                                       (params.nValueAux & AILASTOPRES_LOOKAT) != 0);
  727.                 }
  728.                 break;
  729. #endif
  730.         case eGO_STICKMINIMUMDISTANCE:
  731.         case eGO_STICK:
  732.                 {
  733.                         float duration, endDistance;
  734.                         if (params.nValue & AI_USE_TIME)
  735.                         {
  736.                                 duration = fabsf(params.fValue);
  737.                                 endDistance = 0.0f;
  738.                         }
  739.                         else
  740.                         {
  741.                                 duration = 0.0f;
  742.                                 endDistance = params.fValue;
  743.                         }
  744.  
  745.                         // Random variation on the end distance.
  746.                         if (params.vPos.x > 0.01f)
  747.                         {
  748.                                 float u = cry_random(0, 9) / 9.0f;
  749.                                 if (endDistance > 0.0f)
  750.                                         endDistance = max(0.0f, endDistance - u * params.vPos.x);
  751.                                 else
  752.                                         endDistance = min(0.0f, endDistance + u * params.vPos.x);
  753.                         }
  754.  
  755.                         const ETraceEndMode eTraceEndMode = params.bValue ? eTEM_FixedDistance : eTEM_MinimumDistance;
  756.  
  757.                         // Note: the flag 0x01 means break in a goalpipe description but we change it to continuous flag inside stick goalop.
  758.                         newgoal.pGoalOp = new COPStick(endDistance, params.fValueAux, duration, params.nValue, params.nValueAux, eTraceEndMode);
  759.                         /*                      (params.nValue & AILASTOPRES_USE) != 0, (params.nValue & AILASTOPRES_LOOKAT) != 0,
  760.                                 (params.nValueAux & 0x01) == 0, (params.nValueAux & 0x02) != 0, (params.nValue & AI_REQUEST_PARTIAL_PATH)!=0,
  761.                                 (params.nValue & AI_STOP_ON_ANIMATION_START)!=0, (params.nValue & AI_CONSTANT_SPEED)!=0);*/
  762.  
  763.                 }
  764.                 break;
  765.         case eGO_MOVE:
  766.                 {
  767.                         newgoal.pGoalOp = new MoveOp();
  768.                 }
  769.                 break;
  770.         case eGO_SHOOT:
  771.                 {
  772.                         newgoal.pGoalOp = new ShootOp();
  773.                 }
  774.                 break;
  775.         case eGO_TELEPORT:
  776.                 {
  777.                         newgoal.pGoalOp = new TeleportOp();
  778.                 }
  779.                 break;
  780.         case eGO_TACTICALPOS:
  781.                 {
  782.                         // Create Tactical Position goalop based on a given query ID
  783.                         newgoal.pGoalOp = new COPTacticalPos(params.nValue, static_cast<EAIRegister>(params.nValueAux));
  784.                 }
  785.                 break;
  786.         case eGO_LOOK:
  787.                 {
  788.                         // Create Look goalop
  789.                         newgoal.pGoalOp = new COPLook(params.nValue, params.bValue, static_cast<EAIRegister>(params.nValueAux));
  790.                 }
  791.                 break;
  792.         case eGO_CLEAR:
  793.                 {
  794.                         if (gAIEnv.configuration.eCompatibilityMode == ECCM_CRYSIS2)
  795.                         {
  796.                                 // Executing COPDeValue will remove the attention target. We don't want this for Crysis 2.
  797.                                 // Instead we add a dummy goalop that does nothing except saying it's done. /Jonas
  798.                                 newgoal.pGoalOp = new COPDummy();
  799.                         }
  800.                         else
  801.                         {
  802.                                 newgoal.pGoalOp = new COPDeValue();
  803.                         }
  804.                 }
  805.                 break;
  806.         case eGO_BRANCH:
  807.                 {
  808.                         if (gAIEnv.configuration.eCompatibilityMode == ECCM_CRYSIS2)
  809.                         {
  810.                                 // Executing COPDeValue will remove the attention target. We don't want this for Crysis 2.
  811.                                 // Instead we add a dummy goalop that does nothing except saying it's done. /Jonas
  812.                                 newgoal.pGoalOp = new COPDummy();
  813.                         }
  814.                         else
  815.                         {
  816.                                 newgoal.pGoalOp = new COPDeValue();
  817.                         }
  818.  
  819.                         bBlocking = false;
  820.                 }
  821.                 break;
  822.         case eGO_RANDOM:
  823.                 {
  824.                         newgoal.pGoalOp = new COPDeValue();
  825.                         bBlocking = false;
  826.                 }
  827.                 break;
  828.         case eGO_LOOKAT:
  829.                 {
  830.                         newgoal.pGoalOp = new COPLookAt(params.fValue, params.fValueAux, params.nValue, params.nValueAux != 0, params.bValue);
  831.                 }
  832.                 break;
  833.         case eGO_ANIMATION:
  834.                 {
  835.                         newgoal.pGoalOp = new COPAnimation((EAnimationMode) params.nValue, params.str, params.bValue);
  836.                 }
  837.                 break;
  838.         case eGO_ANIMTARGET:
  839.                 {
  840.                         newgoal.pGoalOp = new COPAnimTarget((params.nValue == AIANIM_SIGNAL), params.str, params.vPos.x, params.vPos.y, params.vPos.z, params.vPosAux, params.bValue);
  841.                 }
  842.                 break;
  843.         case eGO_WAITSIGNAL:
  844.                 {
  845.                         // (MATT) Note that all but form 0 appear to be possible to remove {2008/08/09}
  846.                         switch (int(params.fValue))
  847.                         {
  848.                         case 0:
  849.                                 newgoal.pGoalOp = new COPWaitSignal(params.str, params.fValueAux);
  850.                                 break;
  851.                         case 1:
  852.                                 newgoal.pGoalOp = new COPWaitSignal(params.str, params.strAux, params.fValueAux);
  853.                                 break;
  854.                         case 2:
  855.                                 newgoal.pGoalOp = new COPWaitSignal(params.str, params.nValue, params.fValueAux);
  856.                                 break;
  857.                         case 3:
  858.                                 newgoal.pGoalOp = new COPWaitSignal(params.str, EntityId(params.nValue), params.fValueAux);
  859.                                 break;
  860.                         default:
  861.                                 return;
  862.                         }
  863.                 }
  864.                 break;
  865.         case eGO_WAIT:
  866.                 {
  867.                         newgoal.pGoalOp = new COPWait(params.nValue, m_nCurrentBlockCounter);
  868.                         m_nCurrentBlockCounter = 0;
  869.                         bBlocking = true;                   // wait always has to be blocking
  870.                         eGrouping = IGoalPipe::eGT_GROUPED; // wait always needs to be grouped
  871.                 }
  872.                 break;
  873.         case eGO_SEEKCOVER:
  874.                 assert(false);
  875.                 break;
  876.  
  877. #if 0
  878.         // deprecated and won't compile at all...
  879.         case eGO_G4APPROACH:
  880.                 assert(false);
  881.                 break;
  882.         case eGO_STEER:
  883.                 {
  884.                         newgoal.pGoalOp = new COPSteer(params.fValue, params.fValueAux);
  885.                 }
  886.                 break;
  887.         case eGO_FORM:
  888.                 {
  889.                         newgoal.pGoalOp = new COPForm(params.str.c_str());
  890.                 }
  891.                 break;
  892.         case eGO_MOVETOWARDS:
  893.                 {
  894.                         float duration, endDistance;
  895.                         if (params.nValue & AI_USE_TIME)
  896.                         {
  897.                                 duration = fabsf(params.fValue);
  898.                                 endDistance = 0.0f;
  899.                         }
  900.                         else
  901.                         {
  902.                                 duration = 0.0f;
  903.                                 endDistance = params.fValue;
  904.                         }
  905.  
  906.                         // Random variation on the end distance.
  907.                         if (params.vPos.x > 0.01f)
  908.                         {
  909.                                 float u = cry_random(0, 9) / 9.0f;
  910.                                 if (endDistance > 0.0f)
  911.                                         endDistance = max(0.0f, endDistance - u * params.vPos.x);
  912.                                 else
  913.                                         endDistance = min(0.0f, endDistance + u * params.vPos.x);
  914.                         }
  915.  
  916.                         /*                      newgoal.pGoalOp = new COPApproach(endDistance, params.fValueAux, duration, (params.nValue & AILASTOPRES_USE) != 0,
  917.                            (params.nValue & AILASTOPRES_LOOKAT) != 0, (params.nValue & AI_REQUEST_PARTIAL_PATH)!=0,
  918.                            (params.nValue & AI_STOP_ON_ANIMATION_START)!=0, params.szString);*/
  919.  
  920.                         newgoal.pGoalOp = new COPMoveTowards(endDistance, duration); //, params.nValue);
  921.                 }
  922.                 break;
  923.         case eGO_CONTINUOUS:
  924.                 {
  925.                         newgoal.pGoalOp = new COPContinuous(params.bValue);
  926.                 }
  927.                 break;
  928.         case eGO_PROXIMITY:
  929.                 {
  930.                         newgoal.pGoalOp = new COPProximity(params.fValue, params.str, (params.nValue & 0x1) != 0, (params.nValue & 0x2) != 0);
  931.                 }
  932.                 break;
  933.         case eGO_DODGE:
  934.                 {
  935.                         newgoal.pGoalOp = new COPDodge(params.fValue, params.bValue);
  936.                 }
  937.                 break;
  938.         case eGO_COMPANIONSTICK:
  939.                 {
  940.                         newgoal.pGoalOp = new COPCompanionStick(params.fValue, params.fValueAux, params.vPos.x);
  941.                 }
  942.                 break;
  943. #endif
  944.         case eGO_SET_ANIMATION_TAG:
  945.                 {
  946.                         newgoal.pGoalOp = new CSetAnimationTagGoalOp(params.str.c_str());
  947.                 }
  948.                 break;
  949.         case eGO_CLEAR_ANIMATION_TAG:
  950.                 {
  951.                         newgoal.pGoalOp = new CClearAnimationTagGoalOp(params.str.c_str());
  952.                 }
  953.                 break;
  954.  
  955.         default:
  956.                 // Trying to push undefined/unimplemented goalop.
  957.                 AIAssert(0);
  958.         }
  959.  
  960.         newgoal.op = op;
  961.         newgoal.params = params;
  962.         newgoal.bBlocking = bBlocking;
  963.         newgoal.eGrouping = eGrouping;
  964.  
  965.         m_qGoalPipe.push_back(newgoal);
  966. }
  967.  
  968. //
  969. //-------------------------------------------------------------------------------------------------------
  970. void CGoalPipe::PushPipe(const char* szName, bool bBlocking, EGroupType eGrouping, GoalParameters& params)
  971. {
  972.         if (eGrouping == IGoalPipe::eGT_GROUPED)
  973.                 ++m_nCurrentBlockCounter;
  974.         else
  975.                 m_nCurrentBlockCounter = 0; // continuous group counter.
  976.  
  977.         QGoal newgoal;
  978.         newgoal.op = eGO_LAST;
  979.         newgoal.sPipeName = szName;
  980.         newgoal.params = params;
  981.         newgoal.bBlocking = bBlocking;
  982.         newgoal.eGrouping = eGrouping;
  983.  
  984.         m_qGoalPipe.push_back(newgoal);
  985. }
  986.  
  987. //
  988. //-------------------------------------------------------------------------------------------------------
  989. void CGoalPipe::PushGoal(IGoalOp* pGoalOp, EGoalOperations op, bool bBlocking, EGroupType eGrouping, const GoalParameters& params)
  990. {
  991.         // (MATT) For now we fetch a bunch of the params back from the GoalOp, because eventually they will disappear {2008/02/22}
  992.  
  993.         // Dropped the checks for wait op - it shouldn't end up here anyway
  994.         if (eGrouping == IGoalPipe::eGT_GROUPED)
  995.                 ++m_nCurrentBlockCounter;
  996.  
  997.         QGoal newgoal;
  998.         newgoal.op = op;
  999.         newgoal.pGoalOp = static_cast<CGoalOp*>(pGoalOp);
  1000.         newgoal.sPipeName = CGoalPipe::GetGoalOpName(op); // Goals should know their own names soon
  1001.         newgoal.params = params;
  1002.         newgoal.bBlocking = bBlocking;
  1003.         newgoal.eGrouping = eGrouping;
  1004.  
  1005.         m_qGoalPipe.push_back(newgoal);
  1006. }
  1007.  
  1008. //
  1009. //-------------------------------------------------------------------------------------------------------
  1010. EPopGoalResult CGoalPipe::PopGoal(QGoal& theGoal, CPipeUser* pOperand)
  1011. {
  1012.         // if we are processing a subpipe
  1013.         if (m_pSubPipe)
  1014.         {
  1015.                 EPopGoalResult result = m_pSubPipe->PopGoal(theGoal, pOperand);
  1016.                 if (result == ePGR_AtEnd)
  1017.                 {
  1018.                         CCCPOINT(CGoalPipe_PopGoal_A);
  1019.  
  1020.                         bool dontProcessParentPipe = m_pSubPipe->m_nEventId != 0;
  1021.  
  1022.                         // this subpipe is finished
  1023.                         m_pSubPipe->ResetGoalops(pOperand);
  1024.                         SAFE_DELETE(m_pSubPipe);
  1025.  
  1026.                         if (!m_refArgument.IsNil() && m_refArgument.GetAIObject())
  1027.                                 pOperand->SetLastOpResult(m_refArgument);
  1028.  
  1029.                         pOperand->NotifyListeners(this, ePN_Resumed);
  1030.                         if (dontProcessParentPipe)
  1031.                                 return ePGR_BreakLoop;
  1032.                 }
  1033.                 else
  1034.                         return result;
  1035.         }
  1036.  
  1037.         CCCPOINT(CGoalPipe_PopGoal_B);
  1038.  
  1039.         if (m_nPosition < m_qGoalPipe.size())
  1040.         {
  1041.                 QGoal& current = m_qGoalPipe[m_nPosition++];
  1042.                 if (current.op == eGO_LAST)
  1043.                 {
  1044.                         if (CGoalPipe* pPipe = gAIEnv.pPipeManager->IsGoalPipe(current.sPipeName))
  1045.                         {
  1046.                                 CCCPOINT(CGoalPipe_PopGoal_C);
  1047.  
  1048.                                 // this goal is a subpipe of goals, get that one until it is finished
  1049.                                 m_pSubPipe = pPipe;
  1050.                                 if (pOperand->GetAttentionTarget())
  1051.                                         pPipe->m_vAttTargetPosAtStart = pOperand->GetAttentionTarget()->GetPos();
  1052.                                 else
  1053.                                         pPipe->m_vAttTargetPosAtStart.zero();
  1054.                                 return m_pSubPipe->PopGoal(theGoal, pOperand);
  1055.                         }
  1056.                 }
  1057.                 else
  1058.                 {
  1059.                         CCCPOINT(CGoalPipe_PopGoal_D);
  1060.  
  1061.                         // this is an atomic goal, just return it
  1062.                         theGoal = current;
  1063.                         // goal successfully retrieved
  1064.                         if (0 != theGoal.pGoalOp)
  1065.                                 return ePGR_Succeed;
  1066.                         else
  1067.                         {
  1068.                                 // MERGE :  (MATT) We should hammer this down in Crysis and make this a full error {2008/01/07:12:38:43}
  1069.                                 AIWarning("CGoalPipe::PushGoal - Attempting to push goalpipe that does not exist: \"%s\"", current.sPipeName.c_str());
  1070.                                 return ePGR_AtEnd;
  1071.                         }
  1072.                 }
  1073.         }
  1074.  
  1075.         CCCPOINT(CGoalPipe_PopGoal_E);
  1076.  
  1077.         // we have reached the end of this goal pipe
  1078.         // reset position and let the world know we are done
  1079.         pOperand->NotifyListeners(this, ePN_Finished);
  1080.         //Reset();
  1081.         return ePGR_AtEnd;
  1082. }
  1083.  
  1084. EPopGoalResult CGoalPipe::PeekPopGoalResult() const
  1085. {
  1086.         if (m_pSubPipe)
  1087.         {
  1088.                 bool dontProcessParentPipe = m_pSubPipe->m_nEventId != 0;
  1089.                 if (dontProcessParentPipe)
  1090.                         return ePGR_BreakLoop;
  1091.  
  1092.                 return m_pSubPipe->PeekPopGoalResult();
  1093.         }
  1094.  
  1095.         if (m_nPosition < m_qGoalPipe.size())
  1096.         {
  1097.                 const QGoal& current = m_qGoalPipe[m_nPosition];
  1098.  
  1099.                 if (current.op == eGO_LAST)
  1100.                 {
  1101.                         if (CGoalPipe* pPipe = gAIEnv.pPipeManager->IsGoalPipe(current.sPipeName))
  1102.                         {
  1103.                                 // this goal is a subpipe of goals, get that one until it is finished
  1104.                                 //m_pSubPipe = pPipe;
  1105.                                 EPopGoalResult result = pPipe->PeekPopGoalResult();
  1106.  
  1107.                                 delete pPipe;
  1108.                                 return result;
  1109.                         }
  1110.  
  1111.                         return ePGR_AtEnd;
  1112.                 }
  1113.                 else
  1114.                 {
  1115.                         if (current.pGoalOp)
  1116.                                 return ePGR_Succeed;
  1117.                         else
  1118.                                 return ePGR_AtEnd;
  1119.                 }
  1120.         }
  1121.  
  1122.         return ePGR_AtEnd;
  1123. }
  1124.  
  1125. void CGoalPipe::Reset()
  1126. {
  1127.         m_nPosition = 0;
  1128.         SAFE_DELETE(m_pSubPipe);
  1129.         m_lastResult = eGOR_NONE;
  1130. }
  1131.  
  1132. void CGoalPipe::ResetGoalops(CPipeUser* pPipeUser)
  1133. {
  1134.         if (m_pSubPipe)
  1135.         {
  1136.                 m_pSubPipe->ResetGoalops(pPipeUser);
  1137.         }
  1138.  
  1139.         for (VectorOGoals::iterator gi = m_qGoalPipe.begin(); gi != m_qGoalPipe.end(); ++gi)
  1140.         {
  1141.                 QGoal& goal = *gi;
  1142.                 if (CGoalOp* pGoalOp = goal.pGoalOp)
  1143.                 {
  1144.                         pGoalOp->Reset(pPipeUser);
  1145.                 }
  1146.         }
  1147. }
  1148.  
  1149. // Makes the IP of this pipe jump to the desired position
  1150. bool CGoalPipe::Jump(int position)
  1151. {
  1152.         // if we are processing a subpipe
  1153.         if (m_pSubPipe)
  1154.         {
  1155.                 return m_pSubPipe->Jump(position);
  1156.         }
  1157.  
  1158.         if (position < 0)
  1159.                 --position;
  1160.  
  1161.         if (m_nPosition)
  1162.                 m_nPosition += position;
  1163.  
  1164.         return position < 0;
  1165. }
  1166.  
  1167. // obsolete - string labels are converted to integer relative offsets
  1168. // TODO: cut this version of Jump in a few weeks
  1169. bool CGoalPipe::Jump(const char* label)
  1170. {
  1171.         // if we are processing a subpipe
  1172.         if (m_pSubPipe)
  1173.         {
  1174.                 return m_pSubPipe->Jump(label);
  1175.                 //return;
  1176.         }
  1177.         int step = 0;
  1178.         LabelsMap::iterator it = m_Labels.find(CONST_TEMP_STRING(label));
  1179.         if (it != m_Labels.end())
  1180.         {
  1181.                 step = it->second - m_nPosition;
  1182.                 m_nPosition = it->second;
  1183.         }
  1184.         else
  1185.                 AIWarning("Label %s not found in goal pipe %s.", label, m_sName.c_str());
  1186.  
  1187.         return step < 0;
  1188. }
  1189.  
  1190. void CGoalPipe::ReExecuteGroup()
  1191. {
  1192.         // this must be the last inserted goal pipe
  1193.         AIAssert(!m_pSubPipe);
  1194.  
  1195.         // m_nPosition points to one beyond where our current executing op lives
  1196.         if (0 < m_nPosition && m_nPosition <= m_qGoalPipe.size())
  1197.         {
  1198.                 unsigned int nGoalOpPos = m_nPosition - 1;
  1199.                 assert(0 <= nGoalOpPos && nGoalOpPos < m_qGoalPipe.size());
  1200.  
  1201.                 switch (m_qGoalPipe[nGoalOpPos].eGrouping)
  1202.                 {
  1203.                 case IGoalPipe::eGT_GROUPED:
  1204.                         while ((m_nPosition > 0) && (m_qGoalPipe[m_nPosition - 1].eGrouping == IGoalPipe::eGT_GROUPED))
  1205.                         {
  1206.                                 --m_nPosition;
  1207.                         }
  1208.                         break;
  1209.  
  1210.                 case IGoalPipe::eGT_GROUPWITHPREV:
  1211.                         while ((--m_nPosition > 0) && (m_qGoalPipe[m_nPosition].eGrouping == IGoalPipe::eGT_GROUPWITHPREV))
  1212.                         {
  1213.                         }
  1214.                         break;
  1215.  
  1216.                 case IGoalPipe::eGT_NOGROUP:
  1217.                         // Use the current goal op position so we retrieve the correct one when the pipe starts up again
  1218.                         m_nPosition = nGoalOpPos;
  1219.                         break;
  1220.                 }
  1221.         }
  1222. }
  1223.  
  1224. void CGoalPipe::SetSubpipe(CGoalPipe* pPipe)
  1225. {
  1226.         if (m_pSubPipe && pPipe)
  1227.                 pPipe->SetSubpipe(m_pSubPipe);
  1228.         m_pSubPipe = pPipe;
  1229. }
  1230.  
  1231. //
  1232. //------------------------------------------------------------------------------------------------------
  1233. bool CGoalPipe::RemoveSubpipe(CPipeUser* pPipeUser, int& goalPipeId, bool keepInserted, bool keepHigherPriority)
  1234. {
  1235.         if (m_bHighPriority)
  1236.                 keepHigherPriority = false;
  1237.         if (!m_pSubPipe)
  1238.                 return false;
  1239.         if (!goalPipeId && !m_pSubPipe->m_pSubPipe)
  1240.                 goalPipeId = m_pSubPipe->m_nEventId;
  1241.         if (m_pSubPipe->m_nEventId == goalPipeId)
  1242.         {
  1243.                 if (keepInserted)
  1244.                 {
  1245.                         CGoalPipe* temp = m_pSubPipe;
  1246.                         m_pSubPipe = m_pSubPipe->m_pSubPipe;
  1247.                         temp->m_pSubPipe = NULL;
  1248.                         temp->ResetGoalops(pPipeUser);
  1249.                         delete temp;
  1250.                 }
  1251.                 else
  1252.                 {
  1253.                         if (keepHigherPriority)
  1254.                         {
  1255.                                 CGoalPipe* temp = m_pSubPipe;
  1256.                                 while (temp && (!temp->m_pSubPipe || !temp->m_pSubPipe->m_bHighPriority))
  1257.                                         temp = temp->m_pSubPipe;
  1258.                                 if (temp)
  1259.                                 {
  1260.                                         CGoalPipe* subPipe = m_pSubPipe;
  1261.                                         m_pSubPipe = temp->m_pSubPipe;
  1262.                                         temp->m_pSubPipe = NULL;
  1263.                                         subPipe->ResetGoalops(pPipeUser);
  1264.                                         delete subPipe;
  1265.                                         return true;
  1266.                                 }
  1267.                         }
  1268.                         // there's no higher priority pipe
  1269.                         m_pSubPipe->ResetGoalops(pPipeUser);
  1270.                         delete m_pSubPipe;
  1271.                         m_pSubPipe = NULL;
  1272.                 }
  1273.                 return true;
  1274.         }
  1275.         else
  1276.                 return m_pSubPipe->RemoveSubpipe(pPipeUser, goalPipeId, keepInserted, keepHigherPriority);
  1277. }
  1278.  
  1279. void CGoalPipe::Serialize(TSerialize ser, VectorOGoals& activeGoals)
  1280. {
  1281.         ser.Value("GoalPipePos", m_nPosition);
  1282.         ser.Value("nEventId", m_nEventId);
  1283.         ser.Value("bHighPriority", m_bHighPriority);
  1284.         ser.EnumValue("m_lastResult", m_lastResult, eGOR_NONE, eGOR_LAST);
  1285.  
  1286.         m_refArgument.Serialize(ser, "m_refArgument");
  1287.  
  1288.         // take care of active goals
  1289.         ser.BeginGroup("ActiveGoals");
  1290.         int counter = 0;
  1291.         int goalIdx;
  1292.         char groupName[256];
  1293.         if (ser.IsWriting())
  1294.         {
  1295.                 for (uint32 activeIdx = 0; activeIdx < activeGoals.size(); ++activeIdx)
  1296.                 {
  1297.                         VectorOGoals::iterator actGoal = std::find(m_qGoalPipe.begin(), m_qGoalPipe.end(), activeGoals[activeIdx]);
  1298.                         if (actGoal != m_qGoalPipe.end())
  1299.                         {
  1300.                                 cry_sprintf(groupName, "ActiveGoal-%d", counter);
  1301.                                 ser.BeginGroup(groupName);
  1302.                                 goalIdx = (int)(actGoal - m_qGoalPipe.begin());
  1303.                                 ser.Value("goalIdx", goalIdx);
  1304.                                 m_qGoalPipe[goalIdx].Serialize(ser);
  1305.                                 ser.EndGroup();
  1306.                                 ++counter;
  1307.                         }
  1308.                 }
  1309.                 ser.Value("activeGoalGounter", counter);
  1310.         }
  1311.         else
  1312.         {
  1313.                 ser.Value("activeGoalGounter", counter);
  1314.                 activeGoals.resize(counter);
  1315.                 for (int i = 0; i < counter; ++i)
  1316.                 {
  1317.                         cry_sprintf(groupName, "ActiveGoal-%d", i);
  1318.                         ser.BeginGroup(groupName);
  1319.                         ser.Value("goalIdx", goalIdx);
  1320.                         activeGoals[i] = m_qGoalPipe[goalIdx];
  1321.                         m_qGoalPipe[goalIdx].Serialize(ser);
  1322.                         ser.EndGroup();
  1323.                 }
  1324.         }
  1325.         ser.EndGroup();
  1326.  
  1327.         bool bIsInSubpipe = IsInSubpipe();
  1328.  
  1329.         if (ser.IsReading())
  1330.         {
  1331.                 AIAssert(!bIsInSubpipe); // Danny not completely sure this is a correct assertion to make
  1332.         }
  1333.  
  1334.         // If we are reading, bIsInSubpipe is ignored (we branch based on what we read from the stream instead)
  1335.         if (ser.BeginOptionalGroup("SubPipe", bIsInSubpipe))
  1336.         {
  1337.                 if (ser.IsReading())
  1338.                 {
  1339.                         assert(!m_pSubPipe);
  1340.  
  1341.                         string subPipeName;
  1342.                         ser.Value("GoalSubPipe", subPipeName);
  1343.                         // clone the goal pipe before serializing into it
  1344.                         SetSubpipe(gAIEnv.pPipeManager->IsGoalPipe(subPipeName));
  1345.                 }
  1346.                 else
  1347.                 {
  1348.                         ser.Value("GoalSubPipe", GetSubpipe()->m_sName);
  1349.                 }
  1350.  
  1351.                 if (m_pSubPipe)
  1352.                         m_pSubPipe->Serialize(ser, activeGoals);
  1353.  
  1354.                 ser.EndGroup();
  1355.         }
  1356. }
  1357.  
  1358. //
  1359. //------------------------------------------------------------------------------------------------------
  1360. #ifdef SERIALIZE_DYNAMIC_GOALPIPES
  1361. void CGoalPipe::SerializeDynamic(TSerialize ser)
  1362. {
  1363.         // Shouldn't be called for non-dynamic goal pipes.
  1364.         //      Goal pipes created from XML won't work, since their
  1365.         //      params won't be serialized or reread, leading
  1366.         //      to just having the default params after loading.
  1367.         assert(m_bDynamic);
  1368.         if (!m_bDynamic)
  1369.                 return;
  1370.  
  1371.         uint32 count(m_qGoalPipe.size());
  1372.         char buffer[16];
  1373.         ser.Value("count", count);
  1374.         for (uint32 curIdx(0); curIdx < count; ++curIdx)
  1375.         {
  1376.                 cry_sprintf(buffer, "goal_%d", curIdx);
  1377.                 ser.BeginGroup(buffer);
  1378.                 {
  1379.                         QGoal gl;
  1380.                         if (ser.IsWriting())
  1381.                                 gl = m_qGoalPipe[curIdx];
  1382.                         ser.EnumValue("op", gl.op, eGO_FIRST, eGO_LAST);
  1383.                         ser.Value("sPipeName", gl.sPipeName);
  1384.                         ser.Value("bBlocking", gl.bBlocking);
  1385.                         ser.EnumValue("Grouping", gl.eGrouping, IGoalPipe::eGT_NOGROUP, IGoalPipe::eGT_LAST);
  1386.                         gl.params.Serialize(ser);
  1387.                         if (ser.IsReading())
  1388.                         {
  1389.                                 if (gl.op != eGO_LAST)
  1390.                                 {
  1391.                                         uint32 prevNumGoalOps = GetNumGoalOps();
  1392.                                         PushGoal(gl.op, gl.bBlocking, gl.eGrouping, gl.params);
  1393.                                         if (prevNumGoalOps < GetNumGoalOps())
  1394.                                                 gl.pGoalOp = GetGoalOp(GetNumGoalOps() - 1);
  1395.                                 }
  1396.                                 else
  1397.                                         PushPipe(gl.sPipeName, gl.bBlocking, gl.eGrouping, gl.params);
  1398.                         }
  1399.                         if (gl.pGoalOp)
  1400.                                 gl.pGoalOp->Serialize(ser);
  1401.                 }
  1402.                 ser.EndGroup();
  1403.         }
  1404.         ser.Value("Labels", m_Labels);
  1405. }
  1406.  
  1407. void GoalParameters::Serialize(TSerialize ser)
  1408. {
  1409.         ser.Value("vPos", vPos);
  1410.         ser.Value("vPosAux", vPosAux);
  1411.  
  1412.         ser.Value("fValue", fValue);
  1413.         ser.Value("fValueAux", fValueAux);
  1414.  
  1415.         ser.Value("nValue", nValue);
  1416.         ser.Value("nValueAux", nValueAux);
  1417.  
  1418.         ser.Value("bValue", bValue);
  1419.  
  1420.         ser.Value("str", str);
  1421.         ser.Value("strAux", strAux);
  1422.         ser.Value("scriptCode", scriptCode);
  1423. }
  1424.  
  1425. #endif // SERIALIZE_DYNAMIC_GOALPIPES
  1426.  
downloadGoalPipe.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