AIPlayer.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  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. // AIPlayer.h
  24. // Computerized opponent
  25. // Author: Michael S. Booth, January 2002
  26. #pragma once
  27. #ifndef _AI_PLAYER_H_
  28. #define _AI_PLAYER_H_
  29. #include "Common/GameMemory.h"
  30. #include "Common/Snapshot.h"
  31. enum { INVALID_SKILLSET_SELECTION = -1 };
  32. class BuildListInfo;
  33. /**
  34. * When a team is selected for training, a list of these
  35. * "work orders" are created, one for each member of the team.
  36. * This pairs team members with production buildings to keep
  37. * track of who is building what, and allows us to track if
  38. * a building was destroyed while in the process of training a unit.
  39. */
  40. class WorkOrder : public MemoryPoolObject,
  41. public Snapshot
  42. {
  43. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( WorkOrder, "WorkOrder" )
  44. public:
  45. WorkOrder():m_thing(NULL), m_factoryID(INVALID_ID), m_isResourceGatherer(false), m_numCompleted(0), m_numRequired(1), m_next(NULL) {};
  46. Bool isWaitingToBuild( void ); ///< return true if nothing is yet building this unit
  47. void validateFactory( Player *thisPlayer ); ///< verify factoryID still refers to an active object
  48. public:
  49. const ThingTemplate *m_thing; ///< thing to build
  50. ObjectID m_factoryID; ///< ID of object that is building this, or zero if no-one is
  51. WorkOrder *m_next;
  52. Int m_numCompleted; ///< Number built.
  53. Int m_numRequired; ///< Number needed.
  54. Bool m_required; ///< True if part of minimum requirement.
  55. Bool m_isResourceGatherer; ///< True if resource gatherer.
  56. protected:
  57. // snapshot methods
  58. virtual void crc( Xfer *xfer );
  59. virtual void xfer( Xfer *xfer );
  60. virtual void loadPostProcess( void );
  61. };
  62. inline Bool WorkOrder::isWaitingToBuild( void )
  63. {
  64. if (m_factoryID!=INVALID_ID)
  65. return false;
  66. if (m_numCompleted >= m_numRequired)
  67. return false;
  68. return true;
  69. }
  70. // ------------------------------------------------------------------------------------------------
  71. // ------------------------------------------------------------------------------------------------
  72. class TeamInQueue : public MemoryPoolObject,
  73. public Snapshot
  74. {
  75. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( TeamInQueue, "TeamInQueue" )
  76. private:
  77. MAKE_DLINK(TeamInQueue, TeamBuildQueue) ///< the instances of our prototype
  78. MAKE_DLINK(TeamInQueue, TeamReadyQueue) ///< the instances of our prototype
  79. protected:
  80. // snapshot methods
  81. virtual void crc( Xfer *xfer );
  82. virtual void xfer( Xfer *xfer );
  83. virtual void loadPostProcess( void );
  84. public:
  85. TeamInQueue() :
  86. m_workOrders(NULL),
  87. m_team(NULL),
  88. m_nextTeamInQueue(NULL),
  89. m_sentToStartLocation(false),
  90. m_reinforcement(false),
  91. m_stopQueueing(false),
  92. m_reinforcementID(INVALID_ID),
  93. //Added By Sadullah Nader
  94. //Initialization(s) inserted
  95. m_frameStarted(0),
  96. m_priorityBuild(FALSE)
  97. //
  98. {
  99. }
  100. Bool isAllBuilt( void ); ///< Returns true if the team is finished building.
  101. Bool isBuildTimeExpired( void );///< Returns true if the team has run out of build time.
  102. Bool isMinimumBuilt( void ); ///< Returns true if the team has started building at least the minimum number of units.
  103. Bool includesADozer( void ); ///< Returns true if the team includes a dozer unit.
  104. Bool areBuildsComplete( void ); ///< Returns true if all units in factories have finished building.
  105. void disband( void ); ///< Disbands the team (moves units into the default team).
  106. void stopQueueing(void) {m_stopQueueing=true;} ///< Stops building new units, just finishes current.
  107. public:
  108. WorkOrder *m_workOrders; ///< list of work orders
  109. Bool m_priorityBuild; ///< True if the team is specifically requested.
  110. Team *m_team; ///< the team that units built by the m_workOrders go into
  111. TeamInQueue *m_nextTeamInQueue; ///< next
  112. Int m_frameStarted; ///< Frame we started building.
  113. Bool m_sentToStartLocation; ///< Has it been sent to it's start location?
  114. Bool m_stopQueueing; ///< True if we are to quit queueing units (usually because we ran out of build time.)
  115. Bool m_reinforcement; ///< True if it is a unit to reinforce an existing team.
  116. ObjectID m_reinforcementID; ///< True if it is a unit to reinforce an existing team.
  117. };
  118. /**
  119. * The computer-controlled opponent.
  120. */
  121. class AIPlayer : public MemoryPoolObject,
  122. public Snapshot
  123. {
  124. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AIPlayer, "AIPlayer" )
  125. public:
  126. AIPlayer( Player *p ); ///< constructor
  127. virtual Bool computeSuperweaponTarget(const SpecialPowerTemplate *power, Coord3D *pos, Int playerNdx, Real weaponRadius); ///< Calculates best pos for weapon given radius.
  128. public: // AIPlayer interface, may be overridden by AISkirmishPlayer. jba.
  129. virtual void update(); ///< simulates the behavior of a player
  130. virtual void newMap(); ///< New map loaded call.
  131. /// Invoked when a unit I am training comes into existence
  132. virtual void onUnitProduced( Object *factory, Object *unit );
  133. /// Invoked when a structure I am building comes into existence
  134. virtual void onStructureProduced( Object *factory, Object *structure );
  135. virtual void buildSpecificAITeam(TeamPrototype *teamProto, Bool priorityBuild); ///< Builds this team immediately.
  136. virtual void buildAIBaseDefense(Bool flank); ///< Builds base defense on front or flank of base.
  137. virtual void buildAIBaseDefenseStructure(const AsciiString &thingName, Bool flank); ///< Builds base defense on front or flank of base.
  138. virtual void buildSpecificAIBuilding(const AsciiString &thingName); ///< Builds this building as soon as possible.
  139. virtual void recruitSpecificAITeam(TeamPrototype *teamProto, Real recruitRadius); ///< Builds this team immediately.
  140. virtual Bool isSkirmishAI(void) {return false;}
  141. virtual Player *getAiEnemy(void) {return NULL;} ///< Solo AI attacks based on scripting. Only skirmish auto-acquires an enemy at this point. jba.
  142. virtual Bool checkBridges(Object *unit, Waypoint *way) {return false;}
  143. virtual void repairStructure(ObjectID structure);
  144. virtual void selectSkillset(Int skillset);
  145. public:
  146. Bool getBaseCenter(Coord3D *pos) const {*pos = m_baseCenter; return m_baseCenterSet;}
  147. /// Difficulty level for this player.
  148. GameDifficulty getAIDifficulty(void) const;
  149. void setAIDifficulty(GameDifficulty difficulty) {m_difficulty = difficulty;}
  150. void buildBySupplies(Int minimumCash, const AsciiString &thingName ); ///< Builds a building by supplies.
  151. void buildSpecificBuildingNearestTeam( const AsciiString &thingName, const Team *team );
  152. void buildUpgrade(const AsciiString &upgrade ); ///< Builds an upgrade.
  153. /// A team is about to be destroyed.
  154. void aiPreTeamDestroy( const Team *team );
  155. /// Is the nearest supply source safe?
  156. Bool isSupplySourceSafe( Int minSupplies );
  157. /// Is a supply source attacked?
  158. Bool isSupplySourceAttacked( void );
  159. Bool isLocationSafe( const Coord3D *pos, const ThingTemplate *tthing);
  160. /// Have the team guard a supply center.
  161. void guardSupplyCenter( Team *team, Int minSupplies );
  162. void setTeamDelaySeconds(Int delay) {m_teamSeconds = delay;}
  163. /// Calculates the closest construction zone location based on a template.
  164. Bool calcClosestConstructionZoneLocation( const ThingTemplate *constructTemplate, Coord3D *location );
  165. protected:
  166. // snapshot methods
  167. virtual void crc( Xfer *xfer );
  168. virtual void xfer( Xfer *xfer );
  169. virtual void loadPostProcess( void );
  170. virtual void doBaseBuilding(void);
  171. virtual void checkReadyTeams(void);
  172. virtual void checkQueuedTeams(void);
  173. virtual void doTeamBuilding(void);
  174. virtual void doUpgradesAndSkills(void);
  175. virtual Object *findDozer(const Coord3D *pos);
  176. virtual void queueDozer(void);
  177. virtual Bool selectTeamToBuild( void ); ///< determine the next team to build
  178. virtual Bool selectTeamToReinforce( Int minPriority ); ///< determine the next team to reinforce
  179. virtual Bool startTraining( WorkOrder *order, Bool busyOK, AsciiString teamName); ///< find a production building that can handle the order, and start building
  180. virtual Bool isAGoodIdeaToBuildTeam( TeamPrototype *proto ); ///< return true if team should be built
  181. virtual void processBaseBuilding( void ); ///< do base-building behaviors
  182. virtual void processTeamBuilding( void ); ///< do team-building behaviors
  183. static Int getPlayerSuperweaponValue( Coord3D *center, Int playerNdx, Real radius, Bool includeMilitaryUnits = TRUE );
  184. // End of aiplayer interface.
  185. protected:
  186. MAKE_DLINK_HEAD(TeamInQueue, TeamBuildQueue); ///< List of teams being build
  187. MAKE_DLINK_HEAD(TeamInQueue, TeamReadyQueue); ///< List of teams built, waiting to reach rally point.
  188. protected:
  189. Bool isPossibleToBuildTeam( TeamPrototype *proto, Bool requireIdleFactory, Bool &needMoney ); ///< return true if team can be considered for building
  190. Object *buildStructureNow(const ThingTemplate *bldgPlan, BuildListInfo *info ); ///< Build a base buiding.
  191. Object *buildStructureWithDozer(const ThingTemplate *bldgPlan, BuildListInfo *info ); ///< Build a base buiding.
  192. void clearTeamsInQueue( void ); ///< Delete all teams in the build queue.
  193. void computeCenterAndRadiusOfBase(Coord3D *center, Real *radius);
  194. Object *findFactory(const ThingTemplate *thing, Bool busyOK); ///< Find a factory to build a unit. If force is true, may return a busy factory.
  195. void queueUnits( void ); ///< Check the team build list, & queue up units at any idle factories.
  196. void checkForSupplyCenter( BuildListInfo *info, Object *bldg);
  197. void queueSupplyTruck(void);
  198. void updateBridgeRepair(void);
  199. Bool dozerInQueue(void);
  200. Object *findSupplyCenter(Int minSupplies);
  201. static void getPlayerStructureBounds(Region2D *bounds, Int playerNdx, Bool conservative = FALSE );
  202. protected:
  203. Player *m_player; ///< the Player we represent
  204. Bool m_readyToBuildTeam; ///< True if the team select timer has expired.
  205. Bool m_readyToBuildStructure; ///< True if the buildDelay timer has expired.
  206. Int m_teamTimer; ///< Counts out the time between teams, as specified by ini.
  207. Int m_structureTimer; ///< Counts out the time between structures, as specified by ini.
  208. Int m_teamSeconds; ///< How many seconds to delay between teams.
  209. Int m_buildDelay; ///< Delay for building in case we are resource or prereq. limited.
  210. Int m_teamDelay; ///< Delay for teams in case we are resource or factory prereq. limited.
  211. Int m_frameLastBuildingBuilt; ///< When we built the last building.
  212. GameDifficulty m_difficulty;
  213. Int m_skillsetSelector;
  214. Coord3D m_baseCenter; // Center of the initial build list of structures.
  215. Bool m_baseCenterSet; // True if baseCenter is valid.
  216. Real m_baseRadius; // Radius of the initial build list of structures.
  217. // Bridge repair info.
  218. enum {MAX_STRUCTURES_TO_REPAIR = 2};
  219. ObjectID m_structuresToRepair[MAX_STRUCTURES_TO_REPAIR];
  220. ObjectID m_repairDozer;
  221. Coord3D m_repairDozerOrigin;
  222. Int m_structuresInQueue;
  223. Bool m_dozerQueuedForRepair;
  224. Bool m_dozerIsRepairing; ///< the repair dozer is trying to repair the bridge.
  225. Int m_bridgeTimer;
  226. UnsignedInt m_supplySourceAttackCheckFrame;
  227. ObjectID m_attackedSupplyCenter;
  228. ObjectID m_curWarehouseID;
  229. };
  230. #endif // _AI_PLAYER_H_