AIStateMachine.h 47 KB

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