Team.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  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: Team.h ///////////////////////////////////////////////////////////////
  24. // Team interface definition
  25. // Author: Michael S. Booth, Steven Johnson, March 2001
  26. #pragma once
  27. #ifndef _TEAM_H_
  28. #define _TEAM_H_
  29. #include "Common/GameType.h"
  30. #include "Common/Snapshot.h"
  31. #include "Common/Thing.h"
  32. #include "GameLogic/Object.h"
  33. // ------------------------------------------------------------------------------------------------
  34. typedef UnsignedInt TeamID;
  35. #define TEAM_ID_INVALID 0
  36. // ------------------------------------------------------------------------------------------------
  37. typedef UnsignedInt TeamPrototypeID;
  38. #define TEAM_PROTOTYPE_ID_INVALID 0
  39. // ------------------------------------------------------------------------------------------------
  40. typedef std::hash_map< TeamID, Relationship, std::hash<TeamID>, std::equal_to<TeamID> > TeamRelationMapType;
  41. class TeamRelationMap : public MemoryPoolObject,
  42. public Snapshot
  43. {
  44. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( TeamRelationMap, "TeamRelationMapPool" )
  45. public:
  46. TeamRelationMap( void );
  47. // virtual destructor provided by memory pool object
  48. /** @todo I'm jsut wrappign this up in a nice snapshot object, we really should isolate
  49. * m_map from public access and make access methods for our operations */
  50. TeamRelationMapType m_map;
  51. protected:
  52. virtual void crc( Xfer *xfer );
  53. virtual void xfer( Xfer *xfer );
  54. virtual void loadPostProcess( void );
  55. };
  56. // ------------------------------------------------------------------------------------------------
  57. typedef void (*ObjectIterateFunc)( Object *obj, void *userData ); ///< callback type for iterating objects
  58. // ------------------------------------------------------------------------
  59. /**
  60. How are teams represented in mapfiles?
  61. -- All Players always have at least one top-level team, with the name "team<playername>"
  62. (WB will enforce this in mapfiles.)
  63. -- We'll have a TeamDict list that is parallel to the PlayerDict list
  64. -- All Teams (toplevel and subteams) are in the list
  65. -- Each TeamDict contains:
  66. -- Team Name (an internal ascii str)
  67. -- Owning Team (or Player), by Name
  68. -- Misc Flags
  69. -- Teams we are allies with, by name (only for toplevel teams)
  70. -- Teams we are enemies with, by name (only for toplevel teams)
  71. -- Note that Players and Teams share the same namespace, so you cannot have a team
  72. with the same name as a player (or vice versa).
  73. -- MapObject Dicts will be revised to have an "owning team" rather than "owning player" entry
  74. -- BuildLists must also have a way to assign units to Teams, as appropriate
  75. */
  76. // ------------------------------------------------------------------------
  77. class AIGroup;
  78. class Dict;
  79. class Player;
  80. class PolygonTrigger;
  81. class Script;
  82. class SidesList;
  83. class TeamFactory;
  84. class TeamPrototype;
  85. class Team;
  86. class ThingTemplate;
  87. class Waypoint;
  88. class PlayerRelationMap;
  89. enum AttitudeType;
  90. typedef struct {
  91. Int minUnits;
  92. Int maxUnits;
  93. AsciiString unitThingName;
  94. } TCreateUnitsInfo;
  95. enum { MAX_GENERIC_SCRIPTS = 16 };
  96. // ------------------------------------------------------------------------
  97. /// This is the info for creating reinforcement and AI teams.
  98. class TeamTemplateInfo : public Snapshot
  99. {
  100. public:
  101. TeamTemplateInfo(Dict *d);
  102. enum {MAX_UNIT_TYPES = 7};
  103. typedef enum {NORMAL=0, IGNORE_DISTRACTIONS=1, DEAL_AGGRESSIVELY=2} TBehavior;
  104. TCreateUnitsInfo m_unitsInfo[MAX_UNIT_TYPES]; ///< Quantity of units to create or build.
  105. Int m_numUnitsInfo; ///< Number of entries in m_unitsInfo
  106. Coord3D m_homeLocation; ///< Spawn location for team.
  107. Bool m_hasHomeLocation; ///< True is m_homeLocation is valid.
  108. AsciiString m_scriptOnCreate; ///< Script executed when team is created.
  109. AsciiString m_scriptOnIdle; ///< Script executed when team is idle.
  110. Int m_initialIdleFrames; ///< Number of frames to continue recruiting after the minimum team size is achieved.
  111. AsciiString m_scriptOnEnemySighted; ///< Script executed when enemy is sighted.
  112. AsciiString m_scriptOnAllClear; ///< Script executed when enemy is sighted.
  113. AsciiString m_scriptOnUnitDestroyed; ///< Script executed each time a unit on this team dies.
  114. AsciiString m_scriptOnDestroyed; ///< Script executed m_destroyedThreshold of member units are destroyed.
  115. Real m_destroyedThreshold; ///< OnDestroyed threshold - 1.0 = 100% = all destroyed, .5 = 50% = half of the units destroyed, 0 = useless.
  116. Bool m_isAIRecruitable; ///< True if other ai teams can recruit.
  117. Bool m_isBaseDefense; ///< True if is base defense team.
  118. Bool m_isPerimeterDefense; ///< True if is a perimeter base defense team.
  119. Bool m_automaticallyReinforce; ///< True is team automatically tries to reinforce.
  120. Bool m_transportsReturn; ///< True if transports return to base after unloading.
  121. Bool m_avoidThreats; ///< True if the team avoids threats.
  122. Bool m_attackCommonTarget; ///< True if the team attacks the same target unit.
  123. Int m_maxInstances; ///< Maximum number of instances of a team that is not singleton.
  124. mutable Int m_productionPriority; ///< Production priority.
  125. Int m_productionPrioritySuccessIncrease; ///< Production priority increase on success.
  126. Int m_productionPriorityFailureDecrease; ///< Production priority decrease on failure.
  127. AttitudeType m_initialTeamAttitude; ///< The initial team attitude
  128. AsciiString m_transportUnitType; ///< Unit used to transport the team.
  129. AsciiString m_startReinforceWaypoint; ///< Waypoint where the reinforcement team starts.
  130. Bool m_teamStartsFull; ///< If true, team loads into member transports.
  131. Bool m_transportsExit; ///< True if the transports leave after deploying team.
  132. VeterancyLevel m_veterancy; ///< Veterancy level;
  133. // Production scripts stuff
  134. AsciiString m_productionCondition; ///< Script that contains the production conditions.
  135. Bool m_executeActions; ///< If this is true, then when the production condition becomes true, we also execute the actions.
  136. AsciiString m_teamGenericScripts[MAX_GENERIC_SCRIPTS];
  137. protected:
  138. // snapshot methods
  139. virtual void crc( Xfer *xfer );
  140. virtual void xfer( Xfer *xfer );
  141. virtual void loadPostProcess( void );
  142. };
  143. // ------------------------------------------------------------------------
  144. class Team : public MemoryPoolObject,
  145. public Snapshot
  146. {
  147. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(Team, "TeamPool" )
  148. private:
  149. TeamPrototype *m_proto; ///< the prototype used to create this Team
  150. TeamID m_id; ///< unique team id
  151. // lists we own
  152. /// @todo srj -- convert to non-DLINK list, after it is once again possible to test the change
  153. MAKE_DLINK_HEAD(Object, TeamMemberList) ///< the members of this team
  154. // lists we are members of
  155. /// @todo srj -- convert to non-DLINK list, after it is once again possible to test the change
  156. MAKE_DLINK(Team, TeamInstanceList) ///< the instances of our prototype
  157. AsciiString m_state; ///< Name of the current AI state.
  158. Bool m_enteredOrExited; ///< True if a team member entered or exited a trigger area this frame.
  159. Bool m_active; ///< True if a team is complete. False while members are being added.
  160. Bool m_created; ///< True when first activated.
  161. // Enemy sighted & All Clear:
  162. Bool m_checkEnemySighted;///< True if we have an on enemy sighted or all clear script.
  163. Bool m_seeEnemy; ///< True if we see an enemy.
  164. Bool m_prevSeeEnemy; ///< Last value.
  165. // Idle flag.
  166. Bool m_wasIdle; ///< True if idle last frame.
  167. // On %Destroyed
  168. Int m_destroyThreshold;
  169. Int m_curUnits;
  170. // Following waypoint paths as a team.
  171. const Waypoint *m_currentWaypoint;
  172. // Should check/Execute generic script
  173. Bool m_shouldAttemptGenericScript[MAX_GENERIC_SCRIPTS];
  174. // Recruitablity.
  175. Bool m_isRecruitablitySet; ///< If false, recruitability is team proto value. If true, m_isRecruitable.
  176. Bool m_isRecruitable;
  177. // Attack target.
  178. ObjectID m_commonAttackTarget;
  179. TeamRelationMap *m_teamRelations; ///< override allies & enemies
  180. PlayerRelationMap *m_playerRelations; ///< override allies & enemies
  181. std::list< ObjectID > m_xferMemberIDList; ///< list for post processing and restoring object pointers after a load
  182. protected:
  183. // snapshot methods
  184. virtual void crc( Xfer *xfer );
  185. virtual void xfer( Xfer *xfer );
  186. virtual void loadPostProcess( void );
  187. public:
  188. Team( TeamPrototype *proto, TeamID id );
  189. // ~Team();
  190. /// return the prototype used to create this team
  191. const TeamPrototype *getPrototype( void ) { return m_proto; }
  192. void setID( TeamID id ) { m_id = id; }
  193. TeamID getID() const { return m_id; }
  194. /**
  195. Set the attack priority name for a team.
  196. */
  197. void setAttackPriorityName(AsciiString name);
  198. /**
  199. return the player currently controlling this team (backtracking up if necessary)
  200. */
  201. Player *getControllingPlayer() const;
  202. /**
  203. set the team's owner. (NULL is not allowed)
  204. */
  205. void setControllingPlayer(Player *newController);
  206. /**
  207. Get the team's state
  208. */
  209. const AsciiString& getState(void) const {return m_state;}
  210. /**
  211. fill pAIGroup (which must be NONNULL) with the members of this team as a Group.
  212. */
  213. void getTeamAsAIGroup(AIGroup *pAIGroup);
  214. /**
  215. Get the team's state
  216. */
  217. inline const AsciiString& getName() const;
  218. /**
  219. Get the count of live things that are either alive or are buildings.
  220. */
  221. Int getTargetableCount() const;
  222. /**
  223. Set the team's AI state.
  224. */
  225. void setState(const AsciiString& state) {m_state = state;}
  226. /**
  227. Set the team's AI recruitablity.
  228. */
  229. void setRecruitable(Bool recruitable) {m_isRecruitablitySet = true; m_isRecruitable = recruitable;}
  230. /**
  231. Set the team's target object.
  232. */
  233. void setTeamTargetObject(const Object *target) ;
  234. /**
  235. Set the team's target object.
  236. */
  237. Object *getTeamTargetObject(void);
  238. /**
  239. Set the team as active. A team is considered created when set active.
  240. */
  241. void setActive(void) {if (!m_active) { m_created = true;m_active = true;}}
  242. /**
  243. Is this team active?
  244. */
  245. Bool isActive(void) {return m_active;}
  246. /**
  247. Is this team just createc? (stays true one logic frame.)
  248. */
  249. Bool isCreated(void) {return m_created;}
  250. /**
  251. Note that a team member entered or exited a trigger area.
  252. */
  253. void setEnteredExited(void) {m_enteredOrExited = true;}
  254. /**
  255. Did a team member enter or exit a trigger area.
  256. */
  257. Bool didEnterOrExit(void) {return m_enteredOrExited;}
  258. /**
  259. Clear the flag that a team member entered or exited a trigger area.
  260. Also checks and executes any onCreate scripts, and clears the created flag.
  261. */
  262. void updateState(void);
  263. void notifyTeamOfObjectDeath( void );
  264. Bool didAllEnter(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< All members entered the area
  265. Bool didPartialEnter(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< One member entered the area
  266. Bool didAllExit(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< All members exited the area
  267. Bool didPartialExit(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< One member exited the area
  268. Bool allInside(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< All members are inside the area
  269. Bool someInsideSomeOutside(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const;///< One or more in, one or more out.
  270. Bool noneInside(PolygonTrigger *pTrigger, UnsignedInt whichToConsider) const; ///< No members are in the area.
  271. Object * tryToRecruit(const ThingTemplate *, const Coord3D *teamHome, Real maxDist); ///< Try to recruit the closest unit of this thing type. Return true if successful.
  272. /**
  273. return our relationship with the other team.
  274. this is done as follows:
  275. -- if there's a TeamRelationship between this team and that team, return it.
  276. -- otherwise, we use the relationship between our players.
  277. */
  278. Relationship getRelationship(const Team *that) const;
  279. /**
  280. set a special relationship between this team and that team, that overrides
  281. the one between our Players. (note that this doesn't imply anything about the
  282. relation of that to this.)
  283. */
  284. void setOverrideTeamRelationship( TeamID teamID, Relationship r );
  285. /**
  286. remove the special relation (if any) between this and that.
  287. remove all special relations for 'this' if that==null.
  288. return true if anything removed.
  289. */
  290. Bool removeOverrideTeamRelationship( TeamID teamID );
  291. /**
  292. set a special relationship between this team and that Player, that overrides
  293. the one between our Players. (note that this doesn't imply anything about the
  294. relation of that to this.) Note that override-team relationships take precedence
  295. over override-player relationships.
  296. */
  297. void setOverridePlayerRelationship( Int playerIndex, Relationship r );
  298. /**
  299. remove the special relation (if any) between this and that.
  300. remove all special relations for 'this' if that==null.
  301. return true if anything removed.
  302. */
  303. Bool removeOverridePlayerRelationship( Int playerIndex );
  304. /**
  305. a convenience routine to count the number of owned objects that match a set of ThingTemplates.
  306. You input the count and an array of ThingTemplate*, and provide an array of Int of the same
  307. size. It fills in the array to the correct counts. This is handy because we must traverse
  308. the team's list-of-objects only once.
  309. */
  310. void countObjectsByThingTemplate(Int numTmplates, const ThingTemplate* const* things, Bool ignoreDead, Int *counts, Bool ignoreUnderConstruction = TRUE ) const;
  311. /**
  312. returns the number of buildings on this team, by checking each things' template kindof against KINDOF_STRUCTURE
  313. */
  314. Int countBuildings(void);
  315. /**
  316. simply returns the number of objects on this team with a specific KindOfMaskType
  317. */
  318. Int countObjects(KindOfMaskType setMask, KindOfMaskType clearMask);
  319. /**
  320. This Team will heal all its members
  321. */
  322. void healAllObjects();
  323. /**
  324. * Iterate all members of the team
  325. */
  326. void iterateObjects( ObjectIterateFunc func, void *userData );
  327. /**
  328. a convenience routine to quickly check if any buildings are owned.
  329. */
  330. Bool hasAnyBuildings(void) const;
  331. /**
  332. a convenience routine to quickly check if any buildings with a specific KindOfType flag are owned.
  333. */
  334. Bool hasAnyBuildings(KindOfMaskType kindOf) const;
  335. /**
  336. a convenience routine to quickly check if any units are owned.
  337. */
  338. Bool hasAnyUnits(void) const;
  339. /**
  340. a convenience routine to quickly check if any objects are owned.
  341. */
  342. Bool hasAnyObjects(void) const;
  343. /**
  344. a convenience routine to quickly check if all the units are idle.
  345. */
  346. Bool isIdle(void) const;
  347. /**
  348. a convenience routine to quickly check if any objects are in a trigger area.
  349. */
  350. Bool unitsEntered(PolygonTrigger *pTrigger) const;
  351. /**
  352. a convenience routine to quickly check if any buildfacilities are owned.
  353. */
  354. Bool hasAnyBuildFacility(void) const;
  355. /**
  356. Move team to destination.
  357. */
  358. void moveTeamTo(Coord3D destination);
  359. /**
  360. a convenience routine to quickly destroy a team.
  361. */
  362. Bool damageTeamMembers(Real amount);
  363. /**
  364. a convenience routine to destroy this team. The team goes through all shutdown stuff.
  365. Note that this doesn't actually call deleteInstance, the team will actually be
  366. deleted on the next update, if it is a deletable team.
  367. IgnoreDead lets you not delete people who are dying anyway. Needed for scripts.
  368. */
  369. void deleteTeam(Bool ignoreDead = FALSE);
  370. /**
  371. a convenience routine used to estimate the team's position by just returning the position
  372. of the first member of the team
  373. */
  374. const Coord3D* getEstimateTeamPosition(void) const;
  375. /**
  376. a convenience routine to move a team's units to another team.
  377. */
  378. void transferUnitsTo(Team *newTeam);
  379. /**
  380. a function to kill all members of a team
  381. */
  382. void killTeam(void);
  383. /**
  384. a function to make all containers on a team to dump contents
  385. */
  386. void evacuateTeam(void);
  387. /**
  388. the current waypoint for a team following a waypoint path.
  389. */
  390. const Waypoint *getCurrentWaypoint(void) {return m_currentWaypoint;}
  391. void setCurrentWaypoint(const Waypoint *way) {m_currentWaypoint = way;}
  392. /**
  393. Update the generic scripts, allow them to see if they should run, etc.
  394. */
  395. void updateGenericScripts(void);
  396. };
  397. // ------------------------------------------------------------------------
  398. /**
  399. Note that TeamPrototype is used to hold information that is invariant between
  400. multiple instances of a given Team (e.g., alliance info).
  401. However, a TeamPrototype doesn't contain any build-list style info; that is handled
  402. by the BuildList stuff.
  403. */
  404. class TeamPrototype : public MemoryPoolObject,
  405. public Snapshot
  406. {
  407. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(TeamPrototype, "TeamPrototypePool" )
  408. public:
  409. TeamPrototype( TeamFactory *tf,
  410. const AsciiString& name,
  411. Player *ownerPlayer,
  412. Bool isSingleton,
  413. Dict *d,
  414. TeamPrototypeID id );
  415. // virtual destructor prototype provided by memory pool object
  416. inline TeamPrototypeID getID() const { return m_id; }
  417. inline const AsciiString& getName() const { return m_name; }
  418. inline Bool getIsSingleton() const { return (m_flags & TEAM_SINGLETON) != 0; }
  419. inline const TeamTemplateInfo *getTemplateInfo(void) const {return &m_teamTemplate;}
  420. /**
  421. return the team's owner (backtracking up if necessary)
  422. */
  423. Player *getControllingPlayer() const;
  424. /**
  425. * Return a team with matching team ID if present
  426. */
  427. Team *findTeamByID( TeamID teamID );
  428. /**
  429. set the team's owner. (NULL is not allowed)
  430. */
  431. void setControllingPlayer(Player *newController);
  432. /**
  433. Evaluate team's production condition.
  434. */
  435. Bool evaluateProductionCondition(void);
  436. /**
  437. count for all the team instances belonging to this prototype.
  438. */
  439. void countObjectsByThingTemplate(Int numTmplates, const ThingTemplate* const* things, Bool ignoreDead, Int *counts, Bool ignoreUnderConstruction = TRUE ) const;
  440. /**
  441. count the buildings owned by this Team template
  442. */
  443. Int countBuildings(void);
  444. /**
  445. simply returns the number of objects on this team with a specific KindOfMaskType
  446. */
  447. Int countObjects(KindOfMaskType setMask, KindOfMaskType clearMask);
  448. /**
  449. This TeamProtoType will heal all objects in all its instances
  450. */
  451. void healAllObjects();
  452. /**
  453. * Iterate all members of the team
  454. */
  455. void iterateObjects( ObjectIterateFunc func, void *userData );
  456. /// count the number of teams that have been instanced by this prototype
  457. Int countTeamInstances( void );
  458. /**
  459. Checks & clears the flags that a team member entered or exited a trigger area, or was created.
  460. */
  461. void updateState(void);
  462. /**
  463. a convenience routine to quickly check if any buildings are owned.
  464. */
  465. Bool hasAnyBuildings(void) const;
  466. /**
  467. a convenience routine to quickly check if any buildings with a specific KindOfType flag are owned.
  468. */
  469. Bool hasAnyBuildings(KindOfMaskType kindOf) const;
  470. /**
  471. a convenience routine to quickly check if any units are owned.
  472. */
  473. Bool hasAnyUnits(void) const;
  474. /**
  475. a convenience routine to quickly check if any objects are owned.
  476. */
  477. Bool hasAnyObjects(void) const;
  478. /**
  479. a convenience routine to quickly check if any buildfacilities are owned.
  480. */
  481. Bool hasAnyBuildFacility(void) const;
  482. /**
  483. a convenience routine to quickly destroy a team.
  484. */
  485. void damageTeamMembers(Real amount);
  486. /**
  487. Move team to destination.
  488. */
  489. void moveTeamTo(Coord3D destination);
  490. // this is intended for use ONLY by class Player.
  491. void friend_setOwningPlayer(Player* p) { m_owningPlayer = p; }
  492. void teamAboutToBeDeleted(Team* team);
  493. Script *getGenericScript(Int scriptToRetrieve);
  494. // Make a team more likely to be selected by the ai for building due to success.
  495. void increaseAIPriorityForSuccess(void) const;
  496. // Make a team less likely to be selected by the ai for building due to failure.
  497. void decreaseAIPriorityForFailure(void) const;
  498. void setAttackPriorityName(const AsciiString &name) { m_attackPriorityName = name;}
  499. AsciiString getAttackPriorityName(void) const { return m_attackPriorityName;}
  500. protected:
  501. // snapshot methods
  502. virtual void crc( Xfer *xfer );
  503. virtual void xfer( Xfer *xfer );
  504. virtual void loadPostProcess( void );
  505. private:
  506. enum TeamPrototypeFlags
  507. {
  508. /**
  509. if set, this prototype should only produce one team. if there's already a team
  510. by this name, newly produced team members are added to it, rather than
  511. put into a new team of the same name.
  512. */
  513. TEAM_SINGLETON = 0x01
  514. };
  515. TeamFactory *m_factory; ///< the factory that created us
  516. Player *m_owningPlayer; ///< the Player that currently controls the team-proto (null if NOT a top-level team)
  517. TeamPrototypeID m_id; ///< unique prototype ID
  518. AsciiString m_name; ///< name of the team(s) produced
  519. Int m_flags; ///< misc team flags
  520. Bool m_productionConditionAlwaysFalse; ///< Flag set to true if we don't have a production condition.
  521. Script *m_productionConditionScript; ///< Script to evaluate for production condition.
  522. Bool m_retrievedGenericScripts;
  523. Script *m_genericScriptsToRun[MAX_GENERIC_SCRIPTS];
  524. TeamTemplateInfo m_teamTemplate; ///< Team template info.
  525. AsciiString m_attackPriorityName;
  526. // lists we own
  527. /// @todo srj -- convert to non-DLINK list, after it is once again possible to test the change
  528. MAKE_DLINK_HEAD(Team, TeamInstanceList) ///< the instances of this prototype
  529. };
  530. // ------------------------------------------------------------------------
  531. class TeamFactory : public SubsystemInterface,
  532. public Snapshot
  533. {
  534. public:
  535. TeamFactory();
  536. ~TeamFactory();
  537. // subsystem methods
  538. virtual void init( void );
  539. virtual void reset( void );
  540. virtual void update( void );
  541. void clear();
  542. void initFromSides(SidesList *sides);
  543. /// create a new TeamPrototype and if singleton, a team.
  544. void initTeam(const AsciiString& name, const AsciiString& owner, Bool isSingleton, Dict *d);
  545. /// return the TeamPrototype with the given name. if none exists, return null.
  546. TeamPrototype *findTeamPrototype(const AsciiString& name);
  547. /// return TeamPrototype with matching ID. if none exists NULL is returned
  548. TeamPrototype *findTeamPrototypeByID( TeamPrototypeID id );
  549. /// search all prototypes for the team with the matching id, if none found NULL is returned
  550. Team *findTeamByID( TeamID teamID );
  551. // note that there is no way to directly destroy a specific TeamPrototype (or a Team); the only
  552. // way to do this is to call TeamFactory::reset(), which destroys all of them.
  553. // ------ routines for dealing with Teams
  554. /// create a team. there must be a TeamPrototype with the given name, or an exception is thrown.
  555. Team *createTeam(const AsciiString& name);
  556. /// create a team given an explicity team prototype rather than a prototype name
  557. Team *createTeamOnPrototype( TeamPrototype *prototype );
  558. /// create a team. there must be a TeamPrototype with the given name, or an exception is thrown.
  559. Team *createInactiveTeam(const AsciiString& name);
  560. /// return the team with the given name, or null if none exists. if multiple instances exist, return one arbitrarily.
  561. Team *findTeam(const AsciiString& name);
  562. void addTeamPrototypeToList(TeamPrototype* team);
  563. void removeTeamPrototypeFromList(TeamPrototype* team);
  564. void teamAboutToBeDeleted(Team* team);
  565. protected:
  566. // snapshot methods
  567. virtual void crc( Xfer *xfer );
  568. virtual void xfer( Xfer *xfer );
  569. virtual void loadPostProcess( void );
  570. private:
  571. typedef std::map< NameKeyType, TeamPrototype*, std::less<NameKeyType> > TeamPrototypeMap;
  572. TeamPrototypeMap m_prototypes;
  573. TeamPrototypeID m_uniqueTeamPrototypeID; ///< used to assign unique ids to each team prototype
  574. TeamID m_uniqueTeamID; ///< used to assign unique team ids to each team instance
  575. };
  576. extern TeamFactory *TheTeamFactory;
  577. // inline function ------------------------------------------------------------------------
  578. const AsciiString& Team::getName(void) const
  579. {
  580. return m_proto->getName();
  581. }
  582. // ------------------------------------------------------------------------
  583. #endif // _TEAM_H_