DozerAIUpdate.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  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. // FILE: DozerAIUpdate.h //////////////////////////////////////////////////////////////////////////
  24. // Author: Colin Day, February 2002
  25. // Desc: Dozer AI behavior
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. #pragma once
  28. #ifndef __DOZERAIUPDATE_H_
  29. #define __DOZERAIUPDATE_H_
  30. // USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
  31. #include "GameLogic/Module/AIUpdate.h"
  32. // FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
  33. class AudioEventRTS;
  34. //-------------------------------------------------------------------------------------------------
  35. /** The Dozer primary state machine */
  36. //-------------------------------------------------------------------------------------------------
  37. class DozerPrimaryStateMachine : public StateMachine
  38. {
  39. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DozerPrimaryStateMachine, "DozerPrimaryStateMachine" );
  40. public:
  41. DozerPrimaryStateMachine( Object *owner );
  42. // virtual destructor prototypes provided by memory pool object
  43. //-----------------------------------------------------------------------------------------------
  44. // state transition conditions
  45. static Bool isBuildMostImportant( State *thisState, void* userData );
  46. static Bool isRepairMostImportant( State *thisState, void* userData );
  47. static Bool isFortifyMostImportant( State *thisState, void* userData );
  48. protected:
  49. // snapshot interface
  50. virtual void crc( Xfer *xfer );
  51. virtual void xfer( Xfer *xfer );
  52. virtual void loadPostProcess();
  53. };
  54. //-------------------------------------------------------------------------------------------------
  55. /** Dozer behaviors that use action sub state machines */
  56. //-------------------------------------------------------------------------------------------------
  57. enum DozerTask // These enums are saved in the game save file, so DO NOT renumber them. jba.
  58. {
  59. DOZER_TASK_INVALID = -1,
  60. DOZER_TASK_FIRST = 0,
  61. DOZER_TASK_BUILD = DOZER_TASK_FIRST, ///< go build something
  62. DOZER_TASK_REPAIR = 1, ///< go repair something
  63. DOZER_TASK_FORTIFY = 2, ///< go fortify something
  64. DOZER_NUM_TASKS // keep this last
  65. };
  66. // ------------------------------------------------------------------------------------------------
  67. // ------------------------------------------------------------------------------------------------
  68. enum DozerDockPoint // These enums are saved in the game save file, so DO NOT renumber them. jba.
  69. {
  70. DOZER_DOCK_POINT_START = 0,
  71. DOZER_DOCK_POINT_ACTION = 1,
  72. DOZER_DOCK_POINT_END = 2,
  73. DOZER_NUM_DOCK_POINTS // keep this one last
  74. };
  75. // ------------------------------------------------------------------------------------------------
  76. // ------------------------------------------------------------------------------------------------
  77. enum DozerBuildSubTask // These enums are saved in the game save file, so DO NOT renumber them. jba.
  78. {
  79. DOZER_SELECT_BUILD_DOCK_LOCATION = 0,
  80. DOZER_MOVING_TO_BUILD_DOCK_LOCATION = 1,
  81. DOZER_DO_BUILD_AT_DOCK = 2
  82. };
  83. // ------------------------------------------------------------------------------------------------
  84. /** This is no longer a leaf behavior. Someone else needs to combine this
  85. * with another major AIUpdate. So provide an interface to satisfy the people
  86. * who look this up by name. */
  87. // ------------------------------------------------------------------------------------------------
  88. class DozerAIInterface
  89. {
  90. // This is no longer a leaf behavior. Someone else needs to combine this
  91. // with another major AIUpdate. So provide an interface to satisfy the people
  92. // who look this up by name.
  93. public:
  94. virtual void onDelete( void ) = 0;
  95. virtual Real getRepairHealthPerSecond( void ) const = 0; ///< get health to repair per second
  96. virtual Real getBoredTime( void ) const = 0; ///< how long till we're bored
  97. virtual Real getBoredRange( void ) const = 0; ///< when we're bored, we look this far away to do things
  98. // methods to override for the dozer behaviors
  99. virtual Object *construct( const ThingTemplate *what,
  100. const Coord3D *pos, Real angle,
  101. Player *owningPlayer,
  102. Bool isRebuild ) = 0;
  103. // get task information
  104. virtual DozerTask getMostRecentCommand( void ) = 0; ///< return task that was most recently issued
  105. virtual Bool isTaskPending( DozerTask task ) = 0; ///< is there a desire to do the requested task
  106. virtual ObjectID getTaskTarget( DozerTask task ) = 0; ///< get target of task
  107. virtual Bool isAnyTaskPending( void ) = 0; ///< is there any dozer task pending
  108. virtual DozerTask getCurrentTask( void ) const = 0; ///< return the current task we're doing
  109. // the following should only be used from inside the Dozer state machine!
  110. // !!! *DO NOT CALL THIS AND SET THE TASK DIRECTLY TO AFFECT BEHAVIOR* !!! ///
  111. virtual void setCurrentTask( DozerTask task ) = 0; ///< set the current task of the dozer
  112. virtual Bool getIsRebuild( void ) = 0; ///< get whether or not this is a rebuild.
  113. // task actions
  114. virtual void newTask( DozerTask task, Object *target ) = 0; ///< set a desire to do the requrested task
  115. virtual void cancelTask( DozerTask task ) = 0; ///< cancel this task from the queue, if it's the current task the dozer will stop working on it
  116. // internal methods to manage behavior from within the dozer state machine
  117. virtual void internalTaskComplete( DozerTask task ) = 0; ///< set a dozer task as successfully completed
  118. virtual void internalCancelTask( DozerTask task ) = 0; ///< cancel this task from the dozer
  119. virtual void internalTaskCompleteOrCancelled( DozerTask task ) = 0; ///< this is called when tasks are cancelled or completed
  120. /** return a dock point for the action and task (if valid) ... note it can return NULL
  121. if no point has been set for the combination of task and point */
  122. virtual const Coord3D* getDockPoint( DozerTask task, DozerDockPoint point ) = 0;
  123. virtual void setBuildSubTask( DozerBuildSubTask subTask ) = 0;
  124. virtual DozerBuildSubTask getBuildSubTask( void ) = 0;
  125. // repairing
  126. virtual Bool canAcceptNewRepair( Object *obj ) = 0;
  127. virtual void createBridgeScaffolding( Object *bridgeTower ) = 0;
  128. virtual void removeBridgeScaffolding( Object *bridgeTower ) = 0;
  129. virtual void startBuildingSound( const AudioEventRTS *sound, ObjectID constructionSiteID ) = 0;
  130. virtual void finishBuildingSound() = 0;
  131. };
  132. // ------------------------------------------------------------------------------------------------
  133. /** NOTE: If you edit module data you must do it in both the Dozer *AND* the Worker */
  134. // ------------------------------------------------------------------------------------------------
  135. class DozerAIUpdateModuleData : public AIUpdateModuleData
  136. {
  137. public:
  138. DozerAIUpdateModuleData( void );
  139. // !!!
  140. // !!! NOTE: If you edit module data you must do it in both the Dozer *AND* the Worker !!!
  141. // !!!
  142. Real m_repairHealthPercentPerSecond; ///< how many health points per second the dozer repairs at
  143. Real m_boredTime; ///< after this many frames, a dozer will try to find something to do on its own
  144. Real m_boredRange; ///< range the dozers try to auto repair when they're bored
  145. static void buildFieldParse( MultiIniFieldParse &p );
  146. };
  147. //-------------------------------------------------------------------------------------------------
  148. /** The Dozer AI Update interface. Dozers are workers that are capable of building all the
  149. * structures available to a player, as well as repairing building, and fortifying
  150. * civilian structures */
  151. //-------------------------------------------------------------------------------------------------
  152. class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface
  153. {
  154. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DozerAIUpdate, "DozerAIUpdate" )
  155. MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DozerAIUpdate, DozerAIUpdateModuleData )
  156. public:
  157. static Bool findGoodBuildOrRepairPosition(const Object* me, const Object* target, Coord3D& positionOut);
  158. static Object* findGoodBuildOrRepairPositionAndTarget(Object* me, Object* target, Coord3D& positionOut);
  159. public:
  160. DozerAIUpdate( Thing *thing, const ModuleData* moduleData );
  161. // virtual destructor prototype provided by memory pool declaration
  162. virtual DozerAIInterface* getDozerAIInterface() {return this;}
  163. virtual const DozerAIInterface* getDozerAIInterface() const {return this;}
  164. virtual void onDelete( void );
  165. //
  166. // module data methods ... this is LAME, multiple inheritance off an interface with replicated
  167. // data and code, ick!
  168. // NOTE: If you edit module data you must do it in both the Dozer *AND* the Worker
  169. //
  170. virtual Real getRepairHealthPerSecond( void ) const; ///< get health to repair per second
  171. virtual Real getBoredTime( void ) const; ///< how long till we're bored
  172. virtual Real getBoredRange( void ) const; ///< when we're bored, we look this far away to do things
  173. // methods to override for the dozer behaviors
  174. virtual Object* construct( const ThingTemplate *what,
  175. const Coord3D *pos, Real angle,
  176. Player *owningPlayer,
  177. Bool isRebuild ); ///< construct an object
  178. // get task information
  179. virtual DozerTask getMostRecentCommand( void ); ///< return task that was most recently issued
  180. virtual Bool isTaskPending( DozerTask task ); ///< is there a desire to do the requested task
  181. virtual ObjectID getTaskTarget( DozerTask task ); ///< get target of task
  182. virtual Bool isAnyTaskPending( void ); ///< is there any dozer task pending
  183. virtual DozerTask getCurrentTask( void ) const { return m_currentTask; } ///< return the current task we're doing
  184. virtual void setCurrentTask( DozerTask task ) { m_currentTask = task; } ///< set the current task of the dozer
  185. virtual Bool getIsRebuild( void ) { return m_isRebuild; } ///< get whether or not this building is a rebuild.
  186. // task actions
  187. virtual void newTask( DozerTask task, Object *target ); ///< set a desire to do the requrested task
  188. virtual void cancelTask( DozerTask task ); ///< cancel this task from the queue, if it's the current task the dozer will stop working on it
  189. // internal methods to manage behavior from within the dozer state machine
  190. virtual void internalTaskComplete( DozerTask task ); ///< set a dozer task as successfully completed
  191. virtual void internalCancelTask( DozerTask task ); ///< cancel this task from the dozer
  192. virtual void internalTaskCompleteOrCancelled( DozerTask task ); ///< this is called when tasks are cancelled or completed
  193. /** return a dock point for the action and task (if valid) ... note it can return NULL
  194. if no point has been set for the combination of task and point */
  195. virtual const Coord3D* getDockPoint( DozerTask task, DozerDockPoint point );
  196. virtual void setBuildSubTask( DozerBuildSubTask subTask ) { m_buildSubTask = subTask; };
  197. virtual DozerBuildSubTask getBuildSubTask( void ) { return m_buildSubTask; }
  198. virtual UpdateSleepTime update( void ); ///< the update entry point
  199. // repairing
  200. virtual Bool canAcceptNewRepair( Object *obj );
  201. virtual void createBridgeScaffolding( Object *bridgeTower );
  202. virtual void removeBridgeScaffolding( Object *bridgeTower );
  203. virtual void startBuildingSound( const AudioEventRTS *sound, ObjectID constructionSiteID );
  204. virtual void finishBuildingSound();
  205. //
  206. // the following methods must be overridden so that if a player issues a command the dozer
  207. // can exit the internal state machine and do whatever the player says
  208. //
  209. virtual void aiDoCommand(const AICommandParms* parms);
  210. protected:
  211. virtual void privateRepair( Object *obj, CommandSourceType cmdSource ); ///< repair the target
  212. virtual void privateResumeConstruction( Object *obj, CommandSourceType cmdSource ); ///< resume construction on obj
  213. struct DozerTaskInfo
  214. {
  215. ObjectID m_targetObjectID; ///< target object ID of task
  216. UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task
  217. } m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask
  218. DozerPrimaryStateMachine *m_dozerMachine; ///< the custom state machine for Dozer behavior
  219. DozerTask m_currentTask; ///< current task the dozer is attending to (if any)
  220. AudioEventRTS m_buildingSound; ///< sound is pulled from the object we are building!
  221. Bool m_isRebuild; ///< is this a rebuild of a previous building?
  222. //
  223. // the following info array can be used if we want to have more complicated approaches
  224. // to our target depending on our task
  225. //
  226. struct DozerDockPointInfo
  227. {
  228. Bool valid; ///< this point has been set and is valid
  229. Coord3D location; ///< WORLD location
  230. } m_dockPoint[ DOZER_NUM_TASKS ][ DOZER_NUM_DOCK_POINTS ];
  231. DozerBuildSubTask m_buildSubTask; ///< for building and actually docking for the build
  232. private:
  233. void createMachines( void ); ///< create our behavior machines we need
  234. };
  235. #endif // __DOZERAIUPDATE_H_