SupplyTruckAIUpdate.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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. // SupplyTruckAIUpdate.h ////////////
  24. // Author: Graham Smallwood, February 2002
  25. // Desc: State machine that controls when and with who a Truck docks
  26. #pragma once
  27. #ifndef _SUPPLY_TRUCK_AI_UPDATE_H_
  28. #define _SUPPLY_TRUCK_AI_UPDATE_H_
  29. #include "Common/StateMachine.h"
  30. #include "GameLogic/Module/AIUpdate.h"
  31. //-------------------------------------------------------------------------------------------------
  32. class SupplyTruckStateMachine : public StateMachine
  33. {
  34. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( SupplyTruckStateMachine, "SupplyTruckStateMachine" );
  35. public:
  36. SupplyTruckStateMachine( Object *owner );
  37. // state transition conditions
  38. static Bool ownerDocking( State *thisState, void* userData );
  39. static Bool ownerIdle( State *thisState, void* userData );
  40. static Bool ownerAvailableForSupplying( State *thisState, void* userData );
  41. static Bool ownerNotDockingOrIdle( State *thisState, void* userData );
  42. static Bool isForcedIntoWantingState( State *thisState, void* userData );
  43. static Bool isForcedIntoBusyState( State *thisState, void* userData );
  44. static Bool ownerPlayerCommanded( State *thisState, void* userData );
  45. protected:
  46. // snapshot interface
  47. virtual void crc( Xfer *xfer );
  48. virtual void xfer( Xfer *xfer );
  49. virtual void loadPostProcess();
  50. };
  51. //-------------------------------------------------------------------------------------------------
  52. class SupplyTruckWantsToPickUpOrDeliverBoxesState : public State
  53. {
  54. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(SupplyTruckWantsToPickUpOrDeliverBoxesState, "SupplyTruckWantsToPickUpOrDeliverBoxesState")
  55. protected:
  56. // snapshot interface STUBBED.
  57. virtual void crc( Xfer *xfer ){};
  58. virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
  59. virtual void loadPostProcess(){};
  60. public:
  61. SupplyTruckWantsToPickUpOrDeliverBoxesState( StateMachine *machine ) : State( machine, "SupplyTruckWantsToPickUpOrDeliverBoxesState" ) {}
  62. virtual StateReturnType update();
  63. virtual StateReturnType onEnter();
  64. virtual void onExit(StateExitType status);
  65. };
  66. EMPTY_DTOR(SupplyTruckWantsToPickUpOrDeliverBoxesState)
  67. //-------------------------------------------------------------------------------------------------
  68. class RegroupingState : public State
  69. {
  70. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(RegroupingState, "RegroupingState")
  71. protected:
  72. // snapshot interface STUBBED.
  73. virtual void crc( Xfer *xfer ){};
  74. virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
  75. virtual void loadPostProcess(){};
  76. public:
  77. RegroupingState( StateMachine *machine ) : State( machine, "RegroupingState" ) {}
  78. virtual StateReturnType update();
  79. virtual StateReturnType onEnter();// Will tell me to aiMove back to base.
  80. virtual void onExit(StateExitType status);
  81. };
  82. EMPTY_DTOR(RegroupingState)
  83. //-------------------------------------------------------------------------------------------------
  84. class DockingState : public State
  85. {
  86. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(DockingState, "DockingState")
  87. protected:
  88. // snapshot interface STUBBED.
  89. virtual void crc( Xfer *xfer ){};
  90. virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
  91. virtual void loadPostProcess(){};
  92. public:
  93. DockingState( StateMachine *machine ) :State( machine, "DockingState" ) {}
  94. virtual StateReturnType update();
  95. virtual StateReturnType onEnter();
  96. virtual void onExit(StateExitType status);
  97. };
  98. EMPTY_DTOR(DockingState)
  99. //-------------------------------------------------------------------------------------------------
  100. enum
  101. {
  102. ST_IDLE, ///< Not doing anything. Should I autopilot?
  103. ST_BUSY, ///< Direct player involvement (move) has taken me off autopilot
  104. ST_WANTING, ///< Search for warehouse or center and dock with it
  105. ST_REGROUPING, ///< Wanting failed, so hang out at base until something changes. Autopilot will turn off.
  106. ST_DOCKING ///< Docking substates are running, wait for them to finish
  107. };
  108. //-------------------------------------------------------------------------------------------------
  109. class SupplyTruckAIUpdateModuleData : public AIUpdateModuleData
  110. {
  111. public:
  112. Int m_maxBoxesData;
  113. UnsignedInt m_centerDelay;
  114. UnsignedInt m_warehouseDelay;
  115. Real m_warehouseScanDistance;
  116. AudioEventRTS m_suppliesDepletedVoice; ///< Sound played when I take the last box.
  117. SupplyTruckAIUpdateModuleData()
  118. {
  119. m_maxBoxesData = 0;
  120. m_centerDelay = 0;
  121. m_warehouseDelay = 0;
  122. m_warehouseScanDistance = 100;
  123. }
  124. static void buildFieldParse(MultiIniFieldParse& p)
  125. {
  126. AIUpdateModuleData::buildFieldParse(p);
  127. static const FieldParse dataFieldParse[] =
  128. {
  129. { "MaxBoxes", INI::parseInt, NULL, offsetof( SupplyTruckAIUpdateModuleData, m_maxBoxesData ) },
  130. { "SupplyCenterActionDelay", INI::parseDurationUnsignedInt, NULL, offsetof( SupplyTruckAIUpdateModuleData, m_centerDelay ) },
  131. { "SupplyWarehouseActionDelay", INI::parseDurationUnsignedInt, NULL, offsetof( SupplyTruckAIUpdateModuleData, m_warehouseDelay ) },
  132. { "SupplyWarehouseScanDistance", INI::parseReal, NULL, offsetof( SupplyTruckAIUpdateModuleData, m_warehouseScanDistance ) },
  133. { "SuppliesDepletedVoice", INI::parseAudioEventRTS, NULL, offsetof( SupplyTruckAIUpdateModuleData, m_suppliesDepletedVoice) },
  134. { 0, 0, 0, 0 }
  135. };
  136. p.add(dataFieldParse);
  137. }
  138. };
  139. //-------------------------------------------------------------------------------------------------
  140. class SupplyTruckAIInterface
  141. {
  142. // This is no longer a leaf behavior. Someone else needs to combine this
  143. // with another major AIUpdate. So provide an interface to satisfy the people
  144. // who look this up by name.
  145. public:
  146. virtual Int getNumberBoxes() const = 0;
  147. virtual Bool loseOneBox() = 0;
  148. virtual Bool gainOneBox( Int remainingStock ) = 0;
  149. // returns true if we can fetch/deliver supplies. normally returns true
  150. // if the AI is idle, but subclasses might add further restrictions.
  151. virtual Bool isAvailableForSupplying() const = 0;
  152. virtual Bool isCurrentlyFerryingSupplies() const = 0;
  153. virtual Real getWarehouseScanDistance() const = 0; ///< How far can I look for a warehouse?
  154. virtual void setForceWantingState(Bool v) = 0;
  155. virtual Bool isForcedIntoWantingState() const = 0;
  156. virtual void setForceBusyState(Bool v) = 0;
  157. virtual Bool isForcedIntoBusyState() const = 0;
  158. virtual ObjectID getPreferredDockID() const = 0;
  159. virtual UnsignedInt getActionDelayForDock( Object *dock ) = 0;
  160. virtual Int getUpgradedSupplyBoost() const = 0;
  161. };
  162. //-------------------------------------------------------------------------------------------------
  163. class SupplyTruckAIUpdate : public AIUpdateInterface, public SupplyTruckAIInterface
  164. {
  165. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( SupplyTruckAIUpdate, "SupplyTruckAIUpdate" )
  166. MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( SupplyTruckAIUpdate, SupplyTruckAIUpdateModuleData )
  167. private:
  168. public:
  169. SupplyTruckAIUpdate( Thing *thing, const ModuleData* moduleData );
  170. // virtual destructor prototype provided by memory pool declaration
  171. virtual SupplyTruckAIInterface* getSupplyTruckAIInterface() {return this;}
  172. virtual const SupplyTruckAIInterface* getSupplyTruckAIInterface() const {return this;}
  173. virtual Int getNumberBoxes() const { return m_numberBoxes; }
  174. virtual Bool loseOneBox();
  175. virtual Bool gainOneBox( Int remainingStock );
  176. // this is present for subclasses (eg, Chinook) to override, to
  177. // prevent supply-ferry behavior in some cases (eg, when toting passengers)
  178. virtual Bool isAvailableForSupplying() const;
  179. virtual Bool isCurrentlyFerryingSupplies() const;
  180. virtual Real getWarehouseScanDistance() const; ///< How far can I look for a warehouse?
  181. virtual void setForceWantingState(Bool v) { m_forcePending = v; } // When a Supply Center creates us (or maybe other sources later), we need to hop into autopilot mode.
  182. virtual Bool isForcedIntoWantingState() const { return m_forcePending; }
  183. virtual void setForceBusyState(Bool v) { m_forcedBusyPending = v; }
  184. virtual Bool isForcedIntoBusyState() const { return m_forcedBusyPending; }
  185. virtual ObjectID getPreferredDockID() const { return m_preferredDock; }
  186. virtual UnsignedInt getActionDelayForDock( Object *dock );
  187. virtual Int getUpgradedSupplyBoost() const { return 0; }
  188. virtual UpdateSleepTime update();
  189. protected:
  190. virtual AIStateMachine* makeStateMachine();
  191. virtual void privateDock( Object *obj, CommandSourceType cmdSource );
  192. virtual void privateIdle(CommandSourceType cmdSource); ///< Enter idle state.
  193. private:
  194. SupplyTruckStateMachine* m_supplyTruckStateMachine;
  195. ObjectID m_preferredDock; ///< Instead of searching, try this one first
  196. Int m_numberBoxes;
  197. Bool m_forcePending; // To prevent a function from doing a setState,
  198. // forceWanting will latch into here until serviced.
  199. Bool m_forcedBusyPending; // A supply truck can't tell the difference between Idle since
  200. // I'm between docking states, or a Stop command without help.
  201. AudioEventRTS m_suppliesDepletedVoice; ///< Sound played when I take the last box.
  202. };
  203. #endif