AIStateMachine.h 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // AIStateMachine.h
  24. // Finite state machine encapsulation
  25. // Author: Michael S. Booth, January 2002
  26. #pragma once
  27. #ifndef _AI_STATE_MACHINE_H_
  28. #define _AI_STATE_MACHINE_H_
  29. #include "Lib/Basetype.h"
  30. #include "Common/AudioEventRTS.h"
  31. #include "Common/GameMemory.h"
  32. #include "Common/StateMachine.h"
  33. #include "GameLogic/TerrainLogic.h"
  34. // FORWARD DECLARATIONS ///////////////////////////////////////////////////////////////////////////
  35. class AIGuardMachine;
  36. class AITNGuardMachine;
  37. class Weapon;
  38. class Team;
  39. class AIAttackState;
  40. class AttackStateMachine;
  41. class AIGroup;
  42. class Squad;
  43. //-----------------------------------------------------------------------------------------------------------
  44. /**
  45. * The AI state IDs.
  46. * Each of these constants will be associated with an instance of a State class
  47. * in a given StateMachine.
  48. */
  49. enum AIStateType
  50. {
  51. AI_IDLE,
  52. AI_MOVE_TO, ///< move to the GoalObject or GoalPosition
  53. AI_FOLLOW_WAYPOINT_PATH_AS_TEAM, ///< follow a waypoint path as a team
  54. AI_FOLLOW_WAYPOINT_PATH_AS_INDIVIDUALS, ///< follow a waypoint path
  55. AI_FOLLOW_WAYPOINT_PATH_AS_TEAM_EXACT, ///< follow a waypoint path as a team
  56. AI_FOLLOW_WAYPOINT_PATH_AS_INDIVIDUALS_EXACT,///< follow a waypoint path
  57. AI_FOLLOW_PATH, ///< follow a simple list of points
  58. AI_FOLLOW_EXITPRODUCTION_PATH, ///< the same, but only when exiting production facility
  59. AI_WAIT,
  60. AI_ATTACK_POSITION, ///< attempt to kill GoalPosition
  61. AI_ATTACK_OBJECT, ///< attempt to kill GoalObject
  62. AI_FORCE_ATTACK_OBJECT, ///< attempt to kill GoalObject, force fire on it.
  63. AI_ATTACK_AND_FOLLOW_OBJECT, ///< attempt to kill GoalObject, following it if necessary (and possible)
  64. AI_DEAD,
  65. AI_DOCK, ///< dock with GoalObject, if GoalObject has a DockUpdate module
  66. AI_ENTER, ///< move to GoalObject and "enter" it when close
  67. AI_GUARD, ///< guard your current location
  68. AI_HUNT, ///< seek and destroy behavior
  69. AI_WANDER, ///< Wander around following a waypoint path.
  70. AI_PANIC, ///< Run around screaming following a waypoint path.
  71. AI_ATTACK_SQUAD, ///< Set the unit to attempt to kill all objects in goalSquad.
  72. AI_GUARD_TUNNEL_NETWORK, ///< Guard from inside a tunnel network.
  73. AI_GET_REPAIRED, ///< Get repaired at a repair depot
  74. AI_MOVE_OUT_OF_THE_WAY, ///< Move out of the way of another unit.
  75. AI_MOVE_AND_TIGHTEN, ///< Move in order to tighten up a formation.
  76. AI_MOVE_AND_EVACUATE, ///< Move to, then empty transport.
  77. AI_MOVE_AND_EVACUATE_AND_EXIT, ///< Move to, then empty transport.
  78. AI_MOVE_AND_DELETE, ///< Move to, then delete self.
  79. AI_ATTACK_AREA, ///< Attack units in an area.
  80. AI_HACK_INTERNET, ///< Hack internet for free money (no target required).
  81. AI_ATTACK_MOVE_TO, ///< Attack-move to a location
  82. AI_ATTACKFOLLOW_WAYPOINT_PATH_AS_INDIVIDUALS, ///< Attack-Follow down a waypoint path as individuals
  83. AI_ATTACKFOLLOW_WAYPOINT_PATH_AS_TEAM, ///< Attack-Follow down a waypoint path as a team
  84. AI_FACE_OBJECT,
  85. AI_FACE_POSITION,
  86. AI_RAPPEL_INTO, /**< rappel from current pos down to target object.
  87. if target is building, will enter and kill lots of folks.
  88. if target is null, will rappel to ground. */
  89. AI_COMBATDROP, /**< attempt to send AI_RAPPEL_INTO to contents. */
  90. AI_EXIT, ///< exit the obj, waiting if necessary
  91. AI_PICK_UP_CRATE, ///< Pick up a crate created by a kill. jba.
  92. AI_MOVE_AWAY_FROM_REPULSORS, ///< Civilians are running away from repulsors. (enemies or dead civs, usually) jba
  93. AI_WANDER_IN_PLACE, ///< Civilians just wander around a spot, rather than along a path.
  94. AI_BUSY, ///< This is a state that things will be in when they are busy doing random stuff that doesn't require AI interaction.
  95. NUM_AI_STATES
  96. };
  97. //-----------------------------------------------------------------------------------------------------------
  98. // generically state transition conditions
  99. extern Bool outOfWeaponRangeObject( State *thisState, void* userData );
  100. extern Bool outOfWeaponRangePosition( State *thisState, void* userData );
  101. extern Bool wantToSquishTarget( State *thisState, void* userData );
  102. //-----------------------------------------------------------------------------------------------------------
  103. /**
  104. The AI state machine. This is used by AIUpdate to implement all of the
  105. commands in the AICommandInterface.
  106. NOTE NOTE NOTE NOTE NOTE
  107. Do NOT subclass this unless you want ALL of the states this machine possesses.
  108. If you only want SOME of the states, please make a new StateMachine, descended
  109. from StateMachine, NOT AIStateMachine. Thank you. (srj)
  110. NOTE NOTE NOTE NOTE NOTE
  111. */
  112. class AIStateMachine : public StateMachine
  113. {
  114. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AIStateMachine, "AIStateMachine" );
  115. public:
  116. /**
  117. * The implementation of this constructor defines the states
  118. * used by this machine.
  119. */
  120. AIStateMachine( Object *owner, AsciiString name );
  121. virtual void clear();
  122. virtual StateReturnType resetToDefaultState();
  123. virtual StateReturnType setState( StateID newStateID );
  124. /// @todo Rethink state parameter passing. Continuing in this fashion will have a pile of params in the machine (MSB)
  125. void setGoalPath( const std::vector<Coord3D>* path );
  126. void addToGoalPath( const Coord3D *pathPoint );
  127. const Coord3D *getGoalPathPosition( Int i ) const; ///< return path position at index "i"
  128. Int getGoalPathSize() const { return m_goalPath.size(); }
  129. void setGoalWaypoint( const Waypoint *way ); ///< move toward this waypoint, continue if connected
  130. const Waypoint *getGoalWaypoint();
  131. // All of these wind up storing a Squad, as it is the only one that can always be safely created.
  132. void setGoalTeam( const Team *team );
  133. void setGoalSquad( const Squad *squad );
  134. void setGoalAIGroup( const AIGroup *group );
  135. Squad *getGoalSquad(void);
  136. StateReturnType setTemporaryState( StateID newStateID, Int frameLimitCoount ); ///< change the temporary state of the machine, and number of frames limit.
  137. StateID getTemporaryState(void) const {return m_temporaryState?m_temporaryState->getID():INVALID_STATE_ID;}
  138. public: // overrides.
  139. virtual StateReturnType updateStateMachine(); ///< run one step of the machine
  140. #ifdef STATE_MACHINE_DEBUG
  141. virtual AsciiString getCurrentStateName() const ;
  142. #endif
  143. protected:
  144. // snapshot interface
  145. virtual void crc( Xfer *xfer );
  146. virtual void xfer( Xfer *xfer );
  147. virtual void loadPostProcess();
  148. private:
  149. std::vector<Coord3D> m_goalPath; ///< defines a simple path to follow
  150. const Waypoint * m_goalWaypoint;
  151. Squad * m_goalSquad;
  152. /** A temporary state to run for a while (usually AI_MOVE_OUT_OF_THE_WAY).
  153. Doesn't clear or reset the state machine, so it goes back to doing what it was doing. jba. */
  154. State *m_temporaryState;
  155. UnsignedInt m_temporaryStateFramEnd; ///< Last frame to run m_temporaryState.
  156. };
  157. //-----------------------------------------------------------------------------------------------------------
  158. class AttackStateMachine : public StateMachine
  159. {
  160. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AttackStateMachine, "AttackStateMachine" );
  161. public:
  162. // Attack states.
  163. enum StateType
  164. {
  165. CHASE_TARGET, ///< Chase a moving target (optionally following it)
  166. APPROACH_TARGET, ///< Approach a non-moving target.
  167. AIM_AT_TARGET, ///< rotate to face GoalObject or GoalPosition
  168. FIRE_WEAPON, ///< fire the machine owner's current weapon
  169. NUM_ATTACK_STATES
  170. };
  171. AttackStateMachine( Object *owner, AIAttackState* att, AsciiString name, Bool follow, Bool attackingObject, Bool forceAttacking );
  172. protected:
  173. // snapshot interface
  174. virtual void crc( Xfer *xfer );
  175. virtual void xfer( Xfer *xfer );
  176. virtual void loadPostProcess();
  177. };
  178. //-----------------------------------------------------------------------------------------------------------
  179. class AIIdleState : public State
  180. {
  181. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIIdleState, "AIIdleState")
  182. private:
  183. UnsignedShort m_initialSleepOffset;
  184. Bool m_shouldLookForTargets;
  185. Bool m_inited;
  186. void doInitIdleState();
  187. public:
  188. enum AIIdleTargetingType
  189. {
  190. LOOK_FOR_TARGETS,
  191. DO_NOT_LOOK_FOR_TARGETS
  192. };
  193. virtual Bool isIdle(void) const { return true; }
  194. AIIdleState( StateMachine *machine, AIIdleTargetingType shouldLookForTargets);
  195. virtual StateReturnType onEnter();
  196. virtual StateReturnType update();
  197. protected:
  198. // snapshot interface
  199. virtual void crc( Xfer *xfer );
  200. virtual void xfer( Xfer *xfer );
  201. virtual void loadPostProcess();
  202. };
  203. EMPTY_DTOR(AIIdleState)
  204. //-----------------------------------------------------------------------------------------------------------
  205. /**
  206. * Basic pathfinding and moving to a goal position.
  207. * Not for direct use (hence no associated state ID), but for deriving from.
  208. */
  209. class AIInternalMoveToState : public State
  210. {
  211. MEMORY_POOL_GLUE_ABC(AIInternalMoveToState)
  212. public:
  213. AIInternalMoveToState( StateMachine *machine, AsciiString name ) : State( machine, name )
  214. {
  215. m_goalPosition.zero();
  216. m_pathGoalPosition.zero();
  217. m_pathTimestamp = 0;
  218. m_blockedRepathTimestamp = 0;
  219. m_adjustDestinations = true;
  220. m_goalLayer = LAYER_INVALID;
  221. }
  222. virtual StateReturnType onEnter();
  223. virtual void onExit( StateExitType status );
  224. virtual StateReturnType update();
  225. protected:
  226. void setAdjustsDestination(Bool b) { m_adjustDestinations = b; }
  227. Bool getAdjustsDestination() const;
  228. void setGoalPos(const Coord3D* pos) { m_goalPosition = *pos; }
  229. const Coord3D* getGoalPos() const { return &m_goalPosition; }
  230. virtual Bool computePath(); ///< compute the path
  231. void forceRepath()
  232. {
  233. m_pathGoalPosition.x = m_pathGoalPosition.y = m_pathGoalPosition.z = -100.0f;
  234. m_pathTimestamp = -MIN_REPATH_TIME;
  235. }
  236. private:
  237. void startMoveSound();
  238. protected:
  239. // snapshot interface
  240. virtual void crc( Xfer *xfer );
  241. virtual void xfer( Xfer *xfer );
  242. virtual void loadPostProcess();
  243. private:
  244. enum { MIN_REPATH_TIME = 10 }; ///< minimum # of frames must elapse before re-pathing
  245. protected:
  246. Coord3D m_goalPosition; ///< the goal position to move to
  247. PathfindLayerEnum m_goalLayer; ///< The layer we are moving towards.
  248. Coord3D m_pathGoalPosition; ///< the position our current path leads to
  249. private:
  250. AudioHandle m_ambientPlayingHandle; ///< Audio handle for the looping sound that we may play.
  251. UnsignedInt m_pathTimestamp; ///< time of last pathfind
  252. UnsignedInt m_blockedRepathTimestamp; ///< time of last blocked pathfind
  253. Bool m_adjustDestinations; ///< Adjust destinations to avoid stacking units on top of each other. Normally true, but
  254. // occasionally false for things like car bombs.
  255. protected:
  256. Bool m_waitingForPath; ///< If we are waiting for a path.
  257. Bool m_tryOneMoreRepath; ///< If true, after we complete movement do another compute path.
  258. };
  259. EMPTY_DTOR(AIInternalMoveToState)
  260. //-----------------------------------------------------------------------------------------------------------
  261. /**
  262. * Move to the GoalPosition, or GoalObject.
  263. */
  264. class AIRappelState : public State
  265. {
  266. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIRappelState, "AIRappelState")
  267. protected:
  268. Real m_rappelRate;
  269. Real m_destZ;
  270. Bool m_targetIsBldg;
  271. protected:
  272. // snapshot interface
  273. virtual void crc( Xfer *xfer );
  274. virtual void xfer( Xfer *xfer );
  275. virtual void loadPostProcess();
  276. public:
  277. AIRappelState( StateMachine *machine );
  278. virtual StateReturnType onEnter();
  279. virtual void onExit( StateExitType status );
  280. virtual StateReturnType update();
  281. };
  282. EMPTY_DTOR(AIRappelState)
  283. //-----------------------------------------------------------------------------------------------------------
  284. /**
  285. * Spin. Busy-like
  286. */
  287. class AIBusyState : public State
  288. {
  289. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIBusyState, "AIBusyState")
  290. public:
  291. AIBusyState( StateMachine *machine ) : State( machine, "AIBusyState" ) { }
  292. virtual StateReturnType onEnter() { return STATE_CONTINUE; }
  293. virtual void onExit( StateExitType status ) { }
  294. virtual StateReturnType update() { return STATE_CONTINUE; }
  295. virtual Bool isBusy(void) const { return true; }
  296. protected:
  297. // snapshot interface STUBBED.
  298. virtual void crc( Xfer *xfer ){};
  299. virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
  300. virtual void loadPostProcess(){};
  301. };
  302. EMPTY_DTOR(AIBusyState)
  303. //-----------------------------------------------------------------------------------------------------------
  304. /**
  305. * Move to the GoalPosition, or GoalObject.
  306. */
  307. class AIMoveToState : public AIInternalMoveToState
  308. {
  309. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIMoveToState, "AIMoveToState")
  310. protected:
  311. Bool m_isMoveTo;
  312. public:
  313. AIMoveToState( StateMachine *machine );
  314. virtual StateReturnType onEnter();
  315. virtual void onExit( StateExitType status );
  316. virtual StateReturnType update();
  317. };
  318. EMPTY_DTOR(AIMoveToState)
  319. //-----------------------------------------------------------------------------------------------------------
  320. /**
  321. * Moves out of the way of another object.
  322. */
  323. class AIMoveOutOfTheWayState : public AIInternalMoveToState
  324. {
  325. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIMoveOutOfTheWayState, "AIMoveOutOfTheWayState")
  326. public:
  327. AIMoveOutOfTheWayState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIMoveOutOfTheWayState" ) { }
  328. virtual StateReturnType onEnter();
  329. virtual void onExit( StateExitType status );
  330. virtual StateReturnType update();
  331. protected:
  332. virtual Bool computePath(); ///< compute the path
  333. };
  334. EMPTY_DTOR(AIMoveOutOfTheWayState)
  335. //-----------------------------------------------------------------------------------------------------------
  336. /**
  337. * Moves toward goal pos to tighen up a formation.
  338. */
  339. class AIMoveAndTightenState : public AIInternalMoveToState
  340. {
  341. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIMoveAndTightenState, "AIMoveAndTightenState")
  342. public:
  343. AIMoveAndTightenState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIMoveAndTightenState" )
  344. {
  345. m_checkForPath = false;
  346. m_okToRepathTimes = 0;
  347. }
  348. AIMoveAndTightenState( StateMachine *machine, const char *name ) : AIInternalMoveToState( machine, name )
  349. {
  350. m_checkForPath = false;
  351. m_okToRepathTimes = 0;
  352. }
  353. virtual StateReturnType onEnter();
  354. virtual StateReturnType update();
  355. protected:
  356. virtual Bool computePath(); ///< compute the path
  357. Int m_okToRepathTimes;
  358. Bool m_checkForPath;
  359. protected:
  360. // snapshot interface
  361. virtual void crc( Xfer *xfer );
  362. virtual void xfer( Xfer *xfer );
  363. virtual void loadPostProcess();
  364. };
  365. EMPTY_DTOR(AIMoveAndTightenState)
  366. //-----------------------------------------------------------------------------------------------------------
  367. /**
  368. * Moves toward goal pos to get away from an enemy.
  369. */
  370. class AIMoveAwayFromRepulsorsState : public AIMoveAndTightenState
  371. {
  372. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIMoveAwayFromRepulsorsState, "AIMoveAwayFromRepulsorsState")
  373. public:
  374. AIMoveAwayFromRepulsorsState( StateMachine *machine ) : AIMoveAndTightenState( machine, "AIMoveAwayFromRepulsors" ) { }
  375. virtual StateReturnType onEnter();
  376. virtual StateReturnType update();
  377. virtual void onExit( StateExitType status );
  378. protected:
  379. virtual Bool computePath(); ///< compute the path
  380. };
  381. EMPTY_DTOR(AIMoveAwayFromRepulsorsState)
  382. //-----------------------------------------------------------------------------------------------------------
  383. /**
  384. * Compute a valid spot to fire on GoalObject, and move there.
  385. */
  386. class AIAttackApproachTargetState : public AIInternalMoveToState
  387. {
  388. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIAttackApproachTargetState, "AIAttackApproachTargetState")
  389. public:
  390. AIAttackApproachTargetState( StateMachine *machine, Bool follow, Bool attackingObject, Bool forceAttacking ) :
  391. AIInternalMoveToState( machine, "AIAttackApproachTargetState" ),
  392. m_follow(follow),
  393. m_isAttackingObject(attackingObject),
  394. m_isInitialApproach(true),
  395. m_isForceAttacking(forceAttacking)
  396. {
  397. // we're setting m_isInitialApproach to true in the constructor because we want the first pass
  398. // through this state to allow a unit to attack incidental targets (if it is turreted)
  399. }
  400. virtual StateReturnType onEnter();
  401. virtual void onExit( StateExitType status );
  402. virtual StateReturnType update();
  403. protected:
  404. virtual Bool computePath(); ///< compute the path
  405. protected:
  406. // snapshot interface
  407. virtual void crc( Xfer *xfer );
  408. virtual void xfer( Xfer *xfer );
  409. virtual void loadPostProcess();
  410. private:
  411. enum { MIN_RECOMPUTE_TIME = 10 };
  412. StateReturnType updateInternal( void );
  413. Coord3D m_prevVictimPos; ///< Where we think our victim is
  414. UnsignedInt m_approachTimestamp; ///< When we last computed an approach goal
  415. Bool m_follow; ///< If true, follow object until it dies
  416. Bool m_isAttackingObject; ///< If false, attacking position
  417. Bool m_stopIfInRange; ///< If true, we check and stop as soon we can fire. Used when we have to path to the object instead of to a firing position.
  418. Bool m_isInitialApproach; ///< If true, we can attack other units along the way. We will check for them every N frames (N specified in AI.ini)
  419. Bool m_isForceAttacking;
  420. };
  421. EMPTY_DTOR(AIAttackApproachTargetState)
  422. //-----------------------------------------------------------------------------------------------------------
  423. /**
  424. * Chases a moving GoalObject. If goal is not object, or not moving, or attacker lacks turret, exits with success.
  425. */
  426. class AIAttackPursueTargetState : public AIInternalMoveToState
  427. {
  428. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIAttackPursueTargetState, "AIAttackPursueTargetState")
  429. public:
  430. AIAttackPursueTargetState( StateMachine *machine, Bool follow, Bool attackingObject, Bool forceAttacking ) :
  431. AIInternalMoveToState( machine, "AIAttackPursueTargetState" ),
  432. m_follow(follow),
  433. m_isAttackingObject(attackingObject),
  434. m_isInitialApproach(true),
  435. m_isForceAttacking(forceAttacking),
  436. m_approachTimestamp(0),
  437. m_stopIfInRange(false)
  438. {
  439. // we're setting m_isInitialApproach to true in the constructor because we want the first pass
  440. // through this state to allow a unit to attack incidental targets (if it is turreted)
  441. }
  442. virtual StateReturnType onEnter();
  443. virtual void onExit( StateExitType status );
  444. virtual StateReturnType update();
  445. protected:
  446. virtual Bool computePath(); ///< compute the path
  447. protected:
  448. // snapshot interface
  449. virtual void crc( Xfer *xfer );
  450. virtual void xfer( Xfer *xfer );
  451. virtual void loadPostProcess();
  452. private:
  453. enum { MIN_RECOMPUTE_TIME = 10 };
  454. StateReturnType updateInternal( void );
  455. Coord3D m_prevVictimPos; ///< Where we think our victim is
  456. UnsignedInt m_approachTimestamp; ///< When we last computed an approach goal
  457. Bool m_follow; ///< If true, follow object until it dies
  458. Bool m_isAttackingObject; ///< If false, attacking position
  459. Bool m_stopIfInRange; ///< If true, we check and stop as soon we can fire. Used when we have to path to the object instead of to a firing position.
  460. Bool m_isInitialApproach; ///< If true, we can attack other units along the way. We will check for them every N frames (N specified in AI.ini)
  461. Bool m_isForceAttacking;
  462. };
  463. EMPTY_DTOR(AIAttackPursueTargetState)
  464. //-----------------------------------------------------------------------------------------------------------
  465. /**
  466. * Pick up an upgrade crate after a kill.
  467. */
  468. class AIPickUpCrateState : public AIInternalMoveToState
  469. {
  470. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIPickUpCrateState, "AIPickUpCrateState")
  471. public:
  472. AIPickUpCrateState( StateMachine *machine ) :
  473. AIInternalMoveToState( machine, "AIAttackPickUpCrateState" )
  474. {
  475. // we're setting m_isInitialApproach to true in the constructor because we want the first pass
  476. // through this state to allow a unit to attack incidental targets (if it is turreted)
  477. }
  478. virtual StateReturnType onEnter();
  479. virtual void onExit( StateExitType status );
  480. virtual StateReturnType update();
  481. protected:
  482. virtual Bool computePath(); ///< compute the path
  483. private:
  484. Int m_delayCounter;
  485. protected:
  486. // snapshot interface
  487. virtual void crc( Xfer *xfer );
  488. virtual void xfer( Xfer *xfer );
  489. virtual void loadPostProcess();
  490. };
  491. EMPTY_DTOR(AIPickUpCrateState)
  492. //-------------------------------------------------------------------------------------------------
  493. /**
  494. * Execute an Attack-Move
  495. */
  496. class AIAttackMoveToState : public AIMoveToState
  497. {
  498. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIAttackMoveToState, "AIAttackMoveToState")
  499. public:
  500. AIAttackMoveToState( StateMachine *machine );
  501. //virtual ~AIAttackMoveToState();
  502. virtual StateReturnType onEnter();
  503. virtual void onExit( StateExitType status );
  504. virtual StateReturnType update();
  505. #ifdef STATE_MACHINE_DEBUG
  506. virtual AsciiString getName() const ;
  507. #endif
  508. protected:
  509. enum {ATTACK_RETRY_COUNT=5};
  510. enum {ATTACK_CLOSE_ENOUGH_CELLS=8};
  511. CommandSourceType m_commandSrc; // Original command source. We switch to CMD_FROM_AI when auto-acquiring.
  512. StateMachine *m_attackMoveMachine;
  513. UnsignedInt m_frameToSleepUntil;
  514. Int m_retryCount;
  515. protected:
  516. // snapshot interface
  517. virtual void crc( Xfer *xfer );
  518. virtual void xfer( Xfer *xfer );
  519. virtual void loadPostProcess();
  520. };
  521. //-----------------------------------------------------------------------------------------------------------
  522. /**
  523. * Follow a waypoint path
  524. */
  525. class AIFollowWaypointPathState : public AIInternalMoveToState
  526. {
  527. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIFollowWaypointPathState, "AIFollowWaypointPathState")
  528. public:
  529. AIFollowWaypointPathState( StateMachine *machine, Bool asGroup ) : m_isFollowWaypointPathState(true),
  530. m_moveAsGroup(asGroup), AIInternalMoveToState( machine, "AIFollowWaypointPathState" )
  531. {
  532. m_angle = 0.0f;
  533. }
  534. AIFollowWaypointPathState( StateMachine *machine, Bool asGroup, Bool isFollow) :
  535. m_isFollowWaypointPathState(isFollow), m_moveAsGroup(asGroup), AIInternalMoveToState( machine,
  536. "AIFollowWaypointPathState" )
  537. {
  538. m_angle = 0.0f;
  539. }
  540. virtual StateReturnType onEnter();
  541. virtual void onExit( StateExitType status );
  542. virtual StateReturnType update();
  543. protected:
  544. // snapshot interface
  545. virtual void crc( Xfer *xfer );
  546. virtual void xfer( Xfer *xfer );
  547. virtual void loadPostProcess();
  548. protected:
  549. Coord2D m_groupOffset;
  550. Real m_angle;
  551. Int m_framesSleeping;
  552. const Waypoint *m_currentWaypoint;
  553. const Waypoint *m_priorWaypoint;
  554. Bool m_appendGoalPosition;
  555. const Bool m_moveAsGroup;
  556. // this is necessary because we derive from FollowWaypointPathState, but we do not want to incur the
  557. // expense of checking RTTI to determine whether we are actually a FollowWaypointPathState or not
  558. const Bool m_isFollowWaypointPathState; // derived classes should set this false.
  559. protected:
  560. void computeGoal(Bool useGroupOffsets);
  561. Real calcExtraPathDistance(void);
  562. const Waypoint *getNextWaypoint(void);
  563. Bool hasNextWaypoint(void);
  564. };
  565. EMPTY_DTOR(AIFollowWaypointPathState)
  566. //-----------------------------------------------------------------------------------------------------------
  567. /**
  568. * Follow a waypoint path exactly
  569. */
  570. class AIFollowWaypointPathExactState : public AIInternalMoveToState
  571. {
  572. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIFollowWaypointPathExactState, "AIFollowWaypointPathExactState")
  573. public:
  574. AIFollowWaypointPathExactState( StateMachine *machine, Bool asGroup ) : m_moveAsGroup(asGroup),
  575. m_lastWaypoint(NULL),
  576. AIInternalMoveToState( machine, "AIFollowWaypointPathExactState" ) { }
  577. virtual StateReturnType onEnter();
  578. virtual void onExit( StateExitType status );
  579. virtual StateReturnType update();
  580. protected:
  581. // snapshot interface
  582. virtual void crc( Xfer *xfer );
  583. virtual void xfer( Xfer *xfer );
  584. virtual void loadPostProcess();
  585. protected:
  586. const Waypoint *m_lastWaypoint;
  587. const Bool m_moveAsGroup;
  588. };
  589. EMPTY_DTOR(AIFollowWaypointPathExactState)
  590. //-----------------------------------------------------------------------------------------------------------
  591. /**
  592. * Follow a waypoint path, attacking targets encountered along the way
  593. */
  594. class AIAttackFollowWaypointPathState : public AIFollowWaypointPathState
  595. {
  596. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIAttackFollowWaypointPathState, "AIAttackFollowWaypointPathState")
  597. public:
  598. AIAttackFollowWaypointPathState( StateMachine *machine, Bool asGroup );
  599. //virtual ~AIAttackFollowWaypointPathState();
  600. virtual StateReturnType onEnter();
  601. virtual void onExit( StateExitType status );
  602. virtual StateReturnType update();
  603. #ifdef STATE_MACHINE_DEBUG
  604. virtual AsciiString getName() const ;
  605. #endif
  606. protected:
  607. // We can (and want to) use the attack-move-to logic for when to attack and when to do a normal attack.
  608. StateMachine *m_attackFollowMachine;
  609. protected:
  610. // snapshot interface
  611. virtual void crc( Xfer *xfer );
  612. virtual void xfer( Xfer *xfer );
  613. virtual void loadPostProcess();
  614. };
  615. //-----------------------------------------------------------------------------------------------------------
  616. /**
  617. * Wanders around following a waypoint path.
  618. */
  619. class AIWanderState : public AIFollowWaypointPathState
  620. {
  621. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIWanderState, "AIWanderState")
  622. public:
  623. AIWanderState( StateMachine *machine ) : AIFollowWaypointPathState( machine, false )
  624. {
  625. #ifdef STATE_MACHINE_DEBUG
  626. setName("AIWanderState");
  627. #endif
  628. m_timer = 0;
  629. m_waitFrames = 0;
  630. }
  631. virtual StateReturnType onEnter();
  632. virtual void onExit( StateExitType status );
  633. virtual StateReturnType update();
  634. protected:
  635. // snapshot interface
  636. virtual void crc( Xfer *xfer );
  637. virtual void xfer( Xfer *xfer );
  638. virtual void loadPostProcess();
  639. protected:
  640. Int m_waitFrames;
  641. Int m_timer;
  642. };
  643. EMPTY_DTOR(AIWanderState)
  644. //-----------------------------------------------------------------------------------------------------------
  645. /**
  646. * Wanders around a point.
  647. */
  648. class AIWanderInPlaceState : public AIInternalMoveToState
  649. {
  650. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIWanderInPlaceState, "AIWanderInPlaceState")
  651. public:
  652. AIWanderInPlaceState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIWanderInPlaceState" )
  653. {
  654. m_origin.zero();
  655. m_waitFrames = 0;
  656. m_timer = 0;
  657. }
  658. virtual StateReturnType onEnter();
  659. virtual void onExit( StateExitType status );
  660. virtual StateReturnType update();
  661. protected:
  662. // snapshot interface
  663. virtual void crc( Xfer *xfer );
  664. virtual void xfer( Xfer *xfer );
  665. virtual void loadPostProcess();
  666. protected:
  667. void computeWanderGoal();
  668. Coord3D m_origin; ///< The point we're wandering around.
  669. Int m_waitFrames;
  670. Int m_timer;
  671. };
  672. EMPTY_DTOR(AIWanderInPlaceState)
  673. //-----------------------------------------------------------------------------------------------------------
  674. /**
  675. * Runs around screaming following a waypoint path.
  676. */
  677. class AIPanicState : public AIFollowWaypointPathState
  678. {
  679. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIPanicState, "AIPanicState")
  680. public:
  681. AIPanicState( StateMachine *machine ) : AIFollowWaypointPathState( machine, false)
  682. {
  683. #ifdef STATE_MACHINE_DEBUG
  684. setName("AIPanicState");
  685. #endif
  686. }
  687. virtual StateReturnType onEnter();
  688. virtual StateReturnType update();
  689. virtual void onExit( StateExitType status );
  690. protected:
  691. // snapshot interface
  692. virtual void crc( Xfer *xfer );
  693. virtual void xfer( Xfer *xfer );
  694. virtual void loadPostProcess();
  695. protected:
  696. Int m_waitFrames;
  697. Int m_timer;
  698. };
  699. EMPTY_DTOR(AIPanicState)
  700. //-----------------------------------------------------------------------------------------------------------
  701. /**
  702. * Follow simple list of points.
  703. */
  704. class AIFollowPathState : public AIInternalMoveToState
  705. {
  706. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIFollowPathState, "AIFollowPathState")
  707. public:
  708. AIFollowPathState( StateMachine *machine, AsciiString name = "AIFollowPathState" ) :
  709. m_adjustFinal(true),
  710. m_adjustFinalOverride(false),
  711. m_index(0),
  712. m_retryCount(10),
  713. AIInternalMoveToState( machine, name ) { }
  714. virtual StateReturnType onEnter();
  715. virtual void onExit( StateExitType status );
  716. virtual StateReturnType update();
  717. protected:
  718. Int getCurPathIndex() const { return m_index; }
  719. void setAdjustFinalDestination(Bool b) { m_adjustFinal = b; }
  720. void setAdjustFinalDestinationEvenIfNotDoingGroundMovement(Bool b) { m_adjustFinalOverride = b; }
  721. protected:
  722. // snapshot interface
  723. virtual void crc( Xfer *xfer );
  724. virtual void xfer( Xfer *xfer );
  725. virtual void loadPostProcess();
  726. private:
  727. Int m_index; ///< current path index
  728. Bool m_adjustFinal;
  729. Bool m_adjustFinalOverride;
  730. Int m_retryCount;
  731. };
  732. EMPTY_DTOR(AIFollowPathState)
  733. //-----------------------------------------------------------------------------------------------------------
  734. /**
  735. * Move to and unload transport.
  736. */
  737. class AIMoveAndEvacuateState : public AIInternalMoveToState
  738. {
  739. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIMoveAndEvacuateState, "AIMoveAndEvacuateState")
  740. public:
  741. AIMoveAndEvacuateState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIMoveAndEvacuateState" )
  742. {
  743. m_origin.zero();
  744. }
  745. virtual StateReturnType onEnter();
  746. virtual void onExit( StateExitType status );
  747. virtual StateReturnType update();
  748. protected:
  749. // snapshot interface
  750. virtual void crc( Xfer *xfer );
  751. virtual void xfer( Xfer *xfer );
  752. virtual void loadPostProcess();
  753. private:
  754. Coord3D m_origin; ///< current position - set as goal on exit in case we follow with MoveToAndDelete.
  755. };
  756. EMPTY_DTOR(AIMoveAndEvacuateState)
  757. //-----------------------------------------------------------------------------------------------------------
  758. /**
  759. * Move to and delete self. Used for removing reinforcement transports.
  760. */
  761. class AIMoveAndDeleteState : public AIInternalMoveToState
  762. {
  763. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIMoveAndDeleteState, "AIMoveAndDeleteState")
  764. public:
  765. AIMoveAndDeleteState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIMoveAndDeleteState" )
  766. {
  767. m_appendGoalPosition = FALSE;
  768. }
  769. virtual StateReturnType onEnter();
  770. virtual void onExit( StateExitType status );
  771. virtual StateReturnType update();
  772. protected:
  773. // snapshot interface
  774. virtual void crc( Xfer *xfer );
  775. virtual void xfer( Xfer *xfer );
  776. virtual void loadPostProcess();
  777. protected:
  778. Bool m_appendGoalPosition;
  779. };
  780. EMPTY_DTOR(AIMoveAndDeleteState)
  781. //-----------------------------------------------------------------------------------------------------------
  782. class AIAttackAimAtTargetState : public State
  783. {
  784. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIAttackAimAtTargetState, "AIAttackAimAtTargetState")
  785. public:
  786. AIAttackAimAtTargetState( StateMachine *machine, Bool attackingObject, Bool forceAttacking ) :
  787. State( machine, "AIAttackAimAtTargetState" ),
  788. m_isAttackingObject(attackingObject),
  789. m_canTurnInPlace(false),
  790. m_isForceAttacking(forceAttacking),
  791. m_setLocomotor(false)
  792. {
  793. }
  794. virtual StateReturnType onEnter();
  795. virtual void onExit( StateExitType status );
  796. virtual StateReturnType update();
  797. protected:
  798. // snapshot interface
  799. virtual void crc( Xfer *xfer );
  800. virtual void xfer( Xfer *xfer );
  801. virtual void loadPostProcess();
  802. private:
  803. const Bool m_isAttackingObject;
  804. Bool m_canTurnInPlace;
  805. Bool m_setLocomotor;
  806. Bool m_isForceAttacking;
  807. };
  808. EMPTY_DTOR(AIAttackAimAtTargetState)
  809. //-----------------------------------------------------------------------------------------------------------
  810. class AIWaitState : public State
  811. {
  812. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIWaitState, "AIWaitState")
  813. public:
  814. AIWaitState( StateMachine *machine ) : State( machine,"AIWaitState" ) { }
  815. virtual StateReturnType update();
  816. protected:
  817. // snapshot interface STUBBED.
  818. virtual void crc( Xfer *xfer ){};
  819. virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
  820. virtual void loadPostProcess(){};
  821. };
  822. EMPTY_DTOR(AIWaitState)
  823. //-----------------------------------------------------------------------------------------------------------
  824. class NotifyWeaponFiredInterface // an ABC
  825. {
  826. public:
  827. virtual void notifyFired() = 0;
  828. virtual void notifyNewVictimChosen(Object* victim) = 0;
  829. virtual Bool isWeaponSlotOkToFire(WeaponSlotType wslot) const = 0;
  830. virtual Bool isAttackingObject() const = 0;
  831. virtual const Coord3D* getOriginalVictimPos() const = 0;
  832. };
  833. //-----------------------------------------------------------------------------------------------------------
  834. class AIAttackFireWeaponState : public State
  835. {
  836. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIAttackFireWeaponState, "AIAttackFireWeaponState")
  837. public:
  838. AIAttackFireWeaponState( StateMachine *machine, NotifyWeaponFiredInterface* att ) :
  839. State( machine, "AIAttackFireWeaponState" ),
  840. m_att(att)
  841. {
  842. }
  843. virtual StateReturnType update();
  844. virtual void onExit( StateExitType status );
  845. virtual StateReturnType onEnter();
  846. protected:
  847. // snapshot interface STUBBED.
  848. virtual void crc( Xfer *xfer ){};
  849. virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
  850. virtual void loadPostProcess(){};
  851. private:
  852. NotifyWeaponFiredInterface *const m_att; // this is NOT owned by us and should not be freed
  853. };
  854. EMPTY_DTOR(AIAttackFireWeaponState)
  855. //-----------------------------------------------------------------------------------------------------------
  856. class AttackExitConditionsInterface
  857. {
  858. public:
  859. virtual Bool shouldExit(const StateMachine* machine) const = 0;
  860. };
  861. //-----------------------------------------------------------------------------------------------------------
  862. class AIAttackState : public State, public NotifyWeaponFiredInterface
  863. {
  864. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIAttackState, "AIAttackState")
  865. public:
  866. AIAttackState( StateMachine *machine, Bool follow, Bool attackingObject, Bool forceAttacking, AttackExitConditionsInterface* attackParameters);
  867. //~AIAttackState();
  868. virtual StateReturnType onEnter();
  869. virtual void onExit( StateExitType status );
  870. virtual StateReturnType update();
  871. virtual void notifyFired() { /* nothing */ }
  872. virtual void notifyNewVictimChosen(Object* victim);
  873. virtual const Coord3D* getOriginalVictimPos() const { return &m_originalVictimPos; }
  874. virtual Bool isWeaponSlotOkToFire(WeaponSlotType wslot) const { return true; }
  875. virtual Bool isAttackingObject() const { return m_isAttackingObject; }
  876. virtual Bool isForceAttacking() const { return m_isForceAttacking; }
  877. #ifdef STATE_MACHINE_DEBUG
  878. virtual AsciiString getName() const ;
  879. #endif
  880. virtual Bool isAttack() const { return TRUE; }
  881. protected:
  882. // snapshot interface
  883. virtual void crc( Xfer *xfer );
  884. virtual void xfer( Xfer *xfer );
  885. virtual void loadPostProcess();
  886. private:
  887. void chooseWeapon();
  888. AttackStateMachine* m_attackMachine; ///< state sub-machine for attack behavior
  889. AttackExitConditionsInterface* m_attackParameters; ///< these are not owned by this, and will not be deleted on destruction
  890. Team* m_victimTeam; ///< recorded onEnter because if it changes during attack , it may no longer be a valid target.
  891. Coord3D m_originalVictimPos; ///< position of first obj/pos attacked... used for ContinueAttackRange.
  892. const Weapon* m_lockedWeaponOnEnter;
  893. const Bool m_follow;
  894. const Bool m_isAttackingObject; // if false, attacking position
  895. const Bool m_isForceAttacking;
  896. };
  897. //-----------------------------------------------------------------------------------------------------------
  898. class AIAttackSquadState : public State
  899. {
  900. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIAttackSquadState, "AIAttackSquadState")
  901. public:
  902. AIAttackSquadState( StateMachine *machine, AttackExitConditionsInterface *attackParameters = NULL) :
  903. State( machine , "AIAttackSquadState") { }
  904. //~AIAttackSquadState();
  905. virtual StateReturnType onEnter( void );
  906. virtual void onExit( StateExitType status );
  907. virtual StateReturnType update( void );
  908. Object *chooseVictim(void);
  909. #ifdef STATE_MACHINE_DEBUG
  910. virtual AsciiString getName() const ;
  911. #endif
  912. protected:
  913. // snapshot interface
  914. virtual void crc( Xfer *xfer );
  915. virtual void xfer( Xfer *xfer );
  916. virtual void loadPostProcess();
  917. private:
  918. StateMachine *m_attackSquadMachine; ///< state sub-machine for attack behavior
  919. };
  920. //-----------------------------------------------------------------------------------------------------------
  921. class AIDeadState : public State
  922. {
  923. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIDeadState, "AIDeadState")
  924. public:
  925. AIDeadState( StateMachine *machine ) : State( machine, "AIDeadState" ) { }
  926. virtual StateReturnType onEnter();
  927. virtual StateReturnType update();
  928. virtual void onExit( StateExitType status );
  929. protected:
  930. // snapshot interface STUBBED.
  931. virtual void crc( Xfer *xfer ){};
  932. virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
  933. virtual void loadPostProcess(){};
  934. };
  935. EMPTY_DTOR(AIDeadState)
  936. //-----------------------------------------------------------------------------------------------------------
  937. class AIDockState : public State
  938. {
  939. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIDockState, "AIDockState")
  940. public:
  941. AIDockState( StateMachine *machine ) : State( machine, "AIDockState" ), m_dockMachine(NULL), m_usingPrecisionMovement(FALSE) { }
  942. //~AIDockState();
  943. virtual StateReturnType onEnter();
  944. virtual void onExit( StateExitType status );
  945. virtual StateReturnType update();
  946. #ifdef STATE_MACHINE_DEBUG
  947. virtual AsciiString getName() const ;
  948. #endif
  949. protected:
  950. // snapshot interface
  951. virtual void crc( Xfer *xfer );
  952. virtual void xfer( Xfer *xfer );
  953. virtual void loadPostProcess();
  954. private:
  955. StateMachine *m_dockMachine; ///< state sub-machine for docking behavior
  956. Bool m_usingPrecisionMovement; ///< keep a record of precision movement so we can restore the right state on exit
  957. };
  958. //-----------------------------------------------------------------------------------------------------------
  959. /**
  960. * Move close to GoalObject and enter it.
  961. */
  962. class AIEnterState : public AIInternalMoveToState
  963. {
  964. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIEnterState, "AIEnterState")
  965. protected:
  966. ObjectID m_entryToClear;
  967. protected:
  968. // snapshot interface
  969. virtual void crc( Xfer *xfer );
  970. virtual void xfer( Xfer *xfer );
  971. virtual void loadPostProcess();
  972. public:
  973. AIEnterState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIEnterState" ) { }
  974. virtual StateReturnType onEnter();
  975. virtual StateReturnType update();
  976. virtual void onExit( StateExitType status );
  977. };
  978. EMPTY_DTOR(AIEnterState)
  979. //-----------------------------------------------------------------------------------------------------------
  980. class AIExitState : public State
  981. {
  982. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIExitState, "AIExitState")
  983. protected:
  984. ObjectID m_entryToClear;
  985. protected:
  986. // snapshot interface
  987. virtual void crc( Xfer *xfer );
  988. virtual void xfer( Xfer *xfer );
  989. virtual void loadPostProcess();
  990. public:
  991. AIExitState( StateMachine *machine ) : State( machine, "AIExitState" ) { }
  992. virtual StateReturnType onEnter();
  993. virtual StateReturnType update();
  994. virtual void onExit( StateExitType status );
  995. };
  996. EMPTY_DTOR(AIExitState)
  997. //-----------------------------------------------------------------------------------------------------------
  998. /**
  999. * Guard location
  1000. */
  1001. class AIGuardState : public State
  1002. {
  1003. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIGuardState, "AIGuardState")
  1004. public:
  1005. AIGuardState( StateMachine *machine ) : State( machine, "AIGuardState" ), m_guardMachine(NULL)
  1006. {
  1007. m_guardMachine = NULL;
  1008. }
  1009. //~AIGuardState();
  1010. virtual StateReturnType onEnter();
  1011. virtual void onExit( StateExitType status );
  1012. virtual StateReturnType update();
  1013. #ifdef STATE_MACHINE_DEBUG
  1014. virtual AsciiString getName() const ;
  1015. #endif
  1016. protected:
  1017. // snapshot interface
  1018. virtual void crc( Xfer *xfer );
  1019. virtual void xfer( Xfer *xfer );
  1020. virtual void loadPostProcess();
  1021. private:
  1022. AIGuardMachine *m_guardMachine; ///< state sub-machine for guard behavior
  1023. };
  1024. //-----------------------------------------------------------------------------------------------------------
  1025. /**
  1026. * Guard from inside a tunnel network.
  1027. */
  1028. class AITunnelNetworkGuardState : public State
  1029. {
  1030. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AITunnelNetworkGuardState, "AITunnelNetworkGuardState")
  1031. public:
  1032. AITunnelNetworkGuardState( StateMachine *machine ) : State( machine, "AITunnelNetworkGuardState" ), m_guardMachine(NULL)
  1033. {
  1034. m_guardMachine = NULL;
  1035. }
  1036. //~AIGuardState();
  1037. virtual StateReturnType onEnter();
  1038. virtual void onExit( StateExitType status );
  1039. virtual StateReturnType update();
  1040. #ifdef STATE_MACHINE_DEBUG
  1041. virtual AsciiString getName() const ;
  1042. #endif
  1043. protected:
  1044. // snapshot interface
  1045. virtual void crc( Xfer *xfer );
  1046. virtual void xfer( Xfer *xfer );
  1047. virtual void loadPostProcess();
  1048. private:
  1049. AITNGuardMachine *m_guardMachine; ///< state sub-machine for guard behavior
  1050. };
  1051. //-----------------------------------------------------------------------------------------------------------
  1052. /**
  1053. * Seek and destroy behavior
  1054. */
  1055. class AIHuntState : public State
  1056. {
  1057. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIHuntState, "AIHuntState")
  1058. public:
  1059. AIHuntState( StateMachine *machine ) : State( machine, "AIHuntState" ), m_huntMachine(NULL)
  1060. {
  1061. m_nextEnemyScanTime = 0;
  1062. }
  1063. //~AIHuntState();
  1064. virtual StateReturnType onEnter();
  1065. virtual void onExit( StateExitType status );
  1066. virtual StateReturnType update();
  1067. #ifdef STATE_MACHINE_DEBUG
  1068. virtual AsciiString getName() const ;
  1069. #endif
  1070. protected:
  1071. // snapshot interface
  1072. virtual void crc( Xfer *xfer );
  1073. virtual void xfer( Xfer *xfer );
  1074. virtual void loadPostProcess();
  1075. private:
  1076. StateMachine* m_huntMachine; ///< state sub-machine for hunt behavior
  1077. UnsignedInt m_nextEnemyScanTime; ///< time of last enemy scan
  1078. enum { ENEMY_SCAN_RATE = LOGICFRAMES_PER_SECOND };
  1079. };
  1080. //-----------------------------------------------------------------------------------------------------------
  1081. /**
  1082. * Seek and destroy in area
  1083. */
  1084. class AIAttackAreaState : public State
  1085. {
  1086. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIAttackAreaState, "AIAttackAreaState")
  1087. public:
  1088. AIAttackAreaState( StateMachine *machine ) : State( machine, "AIAttackAreaState" ), m_attackMachine(NULL),
  1089. m_nextEnemyScanTime(0) { }
  1090. //~AIAttackAreaState();
  1091. virtual StateReturnType onEnter();
  1092. virtual void onExit( StateExitType status );
  1093. virtual StateReturnType update();
  1094. #ifdef STATE_MACHINE_DEBUG
  1095. virtual AsciiString getName() const ;
  1096. #endif
  1097. protected:
  1098. // snapshot interface
  1099. virtual void crc( Xfer *xfer );
  1100. virtual void xfer( Xfer *xfer );
  1101. virtual void loadPostProcess();
  1102. private:
  1103. StateMachine *m_attackMachine; ///< state sub-machine for attack behavior
  1104. UnsignedInt m_nextEnemyScanTime; ///< time of last enemy scan
  1105. enum { ENEMY_SCAN_RATE = LOGICFRAMES_PER_SECOND };
  1106. };
  1107. //-----------------------------------------------------------------------------------------------------------
  1108. // Faces a position or an object (depending on goal)
  1109. //-----------------------------------------------------------------------------------------------------------
  1110. class AIFaceState : public State
  1111. {
  1112. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIFaceState, "AIFaceState")
  1113. public:
  1114. AIFaceState( StateMachine *machine, Bool obj ) : State( machine, "AIFaceState" ), m_canTurnInPlace(false), m_obj(obj) { }
  1115. virtual StateReturnType onEnter();
  1116. virtual void onExit( StateExitType status );
  1117. virtual StateReturnType update();
  1118. protected:
  1119. // snapshot interface .
  1120. virtual void crc( Xfer *xfer );
  1121. virtual void xfer( Xfer *xfer );
  1122. virtual void loadPostProcess();
  1123. protected:
  1124. const Bool m_obj;
  1125. Bool m_canTurnInPlace;
  1126. };
  1127. EMPTY_DTOR(AIFaceState)
  1128. #endif