TEAMTYPE.CPP 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. /*
  2. ** Command & Conquer(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. /* $Header: F:\projects\c&c\vcs\code\teamtype.cpv 2.17 16 Oct 1995 16:48:52 JOE_BOSTIC $ */
  19. /***************************************************************************
  20. ** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S **
  21. ***************************************************************************
  22. * *
  23. * Project Name : Command & Conquer *
  24. * *
  25. * File Name : TEAMTYPE.CPP *
  26. * *
  27. * Programmer : Bill Randolph *
  28. * *
  29. * Start Date : December 7, 1994 *
  30. * *
  31. * Last Update : July 21, 1995 [JLB] *
  32. * *
  33. *-------------------------------------------------------------------------*
  34. * Functions: *
  35. * TeamTypeClass::TeamTypeClass -- class constructor *
  36. * TeamTypeClass::~TeamTypeClass -- class destructor *
  37. * TeamTypeClass::Init -- pre-scenario initialization *
  38. * TeamTypeClass::Read_INI -- reads INI data *
  39. * TeamTypeClass::Write_INI -- writes INI data *
  40. * TeamTypeClass::Read_Old_INI -- reads old INI format *
  41. * TeamTypeClass::As_Pointer -- gets ptr for team type with given name *
  42. * TeamTypeClass::Remove -- removes this team from the system *
  43. * TeamTypeClass::Mission_From_Name -- returns mission for given name *
  44. * TeamTypeClass::Name_From_Mission -- returns name for given mission *
  45. * TeamTypeClass::operator new -- 'new' operator *
  46. * TeamTypeClass::operator delete -- 'delete' operator *
  47. * TeamTypeClass::Suggested_New_Team -- Suggests a new team to create. *
  48. * TeamTypeClass::Validate -- validates teamtype pointer *
  49. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  50. #include "function.h"
  51. /*
  52. ********************************** Globals **********************************
  53. */
  54. char const * TeamTypeClass::TMissions[TMISSION_COUNT] = {
  55. "Attack Base",
  56. "Attack Units",
  57. "Attack Civil.",
  58. "Rampage",
  59. "Defend Base",
  60. // "Harvest",
  61. "Move",
  62. "Move to Cell",
  63. "Retreat",
  64. "Guard",
  65. "Loop",
  66. "Attack Tarcom",
  67. "Unload",
  68. };
  69. /*
  70. ** This contains the value of the Virtual Function Table Pointer
  71. */
  72. void * TeamTypeClass::VTable;
  73. /***********************************************************************************************
  74. * TeamTypeClass::Validate -- validates teamtype pointer *
  75. * *
  76. * INPUT: *
  77. * none. *
  78. * *
  79. * OUTPUT: *
  80. * 1 = ok, 0 = error *
  81. * *
  82. * WARNINGS: *
  83. * none. *
  84. * *
  85. * HISTORY: *
  86. * 08/09/1995 BRR : Created. *
  87. *=============================================================================================*/
  88. #ifdef CHEAT_KEYS
  89. int TeamTypeClass::Validate(void) const
  90. {
  91. int num;
  92. num = TeamTypes.ID(this);
  93. if (num < 0 || num >= TEAMTYPE_MAX) {
  94. Validate_Error("TEAMTYPE");
  95. return (0);
  96. }
  97. else
  98. return (1);
  99. }
  100. #else
  101. #define Validate()
  102. #endif
  103. /***************************************************************************
  104. * TeamTypeClass::TeamTypeClass -- class constructor *
  105. * *
  106. * INPUT: *
  107. * *
  108. * OUTPUT: *
  109. * *
  110. * WARNINGS: *
  111. * *
  112. * HISTORY: *
  113. * 12/07/1994 BR : Created. *
  114. *=========================================================================*/
  115. TeamTypeClass::TeamTypeClass(void)
  116. {
  117. IsPrebuilt = true;
  118. IsReinforcable = true;
  119. IsRoundAbout = false;
  120. IsLearning = false;
  121. IsSuicide = false;
  122. IsAutocreate = false;
  123. IsTransient = false;
  124. IsMercenary = false;
  125. RecruitPriority = 7;
  126. MaxAllowed = 0;
  127. Fear = 0;
  128. InitNum = 0;
  129. House = HOUSE_NONE;
  130. MissionCount = 0;
  131. IniName[0] = '\0';
  132. ClassCount = 0;
  133. for (int i = 0; i < MAX_TEAM_CLASSCOUNT; i++) {
  134. Class[i] = NULL;
  135. DesiredNum[i] = 0;
  136. }
  137. }
  138. /***************************************************************************
  139. * TeamTypeClass::Init -- pre-scenario initialization *
  140. * *
  141. * INPUT: *
  142. * *
  143. * OUTPUT: *
  144. * *
  145. * WARNINGS: *
  146. * *
  147. * HISTORY: *
  148. * 12/07/1994 BR : Created. *
  149. *=========================================================================*/
  150. void TeamTypeClass::Init(void)
  151. {
  152. TeamTypeClass *ptr;
  153. TeamTypes.Free_All();
  154. ptr = new TeamTypeClass();
  155. VTable = ((void **)(((char *)ptr) + sizeof(AbstractTypeClass) - 4))[0];
  156. delete ptr;
  157. }
  158. /***************************************************************************
  159. * TeamTypeClass::Read_INI -- reads INI data *
  160. * *
  161. * INI entry format: *
  162. * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, *
  163. * RecruitPriority,MaxAllowed,InitNum,Fear, *
  164. * ClassCount,Class:Num,Class:Num,..., *
  165. * MissionCount,Mission:Arg,Mission:Arg,Mission:Arg,... *
  166. * *
  167. * INPUT: *
  168. * buffer buffer to hold the INI data *
  169. * *
  170. * OUTPUT: *
  171. * none. *
  172. * *
  173. * WARNINGS: *
  174. * none. *
  175. * *
  176. * HISTORY: *
  177. * 12/07/1994 BR : Created. *
  178. * 02/01/1995 BR : No del team if no classes (editor needs empty teams!) *
  179. *=========================================================================*/
  180. void TeamTypeClass::Read_INI(char *buffer)
  181. {
  182. TeamTypeClass * team; // Working team pointer.
  183. char *tbuffer; // Accumulation buffer of team names.
  184. int len; // Length of data in buffer.
  185. char buf[500]; // INI entry buffer
  186. /*------------------------------------------------------------------------
  187. Set 'tbuffer' to point just past the INI buffer
  188. ------------------------------------------------------------------------*/
  189. len = strlen(buffer) + 2;
  190. tbuffer = buffer + len;
  191. /*------------------------------------------------------------------------
  192. Read all TeamType entry names into 'tbuffer'
  193. ------------------------------------------------------------------------*/
  194. WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer);
  195. /*
  196. ----------------------- Loop for all team entries ------------------------
  197. */
  198. while (*tbuffer != '\0') {
  199. /*
  200. ....................... Create a new team type ........................
  201. */
  202. team = new TeamTypeClass();
  203. /*
  204. ......................... Get the team entry ..........................
  205. */
  206. WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer);
  207. /*
  208. .......................... Fill the team in ...........................
  209. */
  210. team->Fill_In(tbuffer, buf);
  211. /*
  212. ...................... Go to the next INI entry .......................
  213. */
  214. tbuffer += strlen(tbuffer)+1;
  215. }
  216. /*
  217. ** If no teams were read in, try reading the old INI format.
  218. */
  219. if (TeamTypes.Count()==0) {
  220. Read_Old_INI(buffer);
  221. }
  222. }
  223. /***********************************************************************************************
  224. * TeamTypeClass::Fill_In -- fills in trigger from the given INI entry *
  225. * *
  226. * This routine fills in the given teamtype with the given name, and values from *
  227. * the given INI entry. *
  228. * *
  229. * (This routine is used by the scenario editor, to import teams from the MASTER.INI file.) *
  230. * *
  231. * INI entry format: *
  232. * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, *
  233. * RecruitPriority,MaxAllowed,InitNum,Fear, *
  234. * ClassCount,Class:Num,Class:Num,..., *
  235. * MissionCount,Mission:Arg,Mission:Arg,Mission:Arg,... *
  236. * *
  237. * INPUT: *
  238. * name mnemonic for the desired trigger *
  239. * entry INI entry to parse *
  240. * *
  241. * OUTPUT: *
  242. * none. *
  243. * *
  244. * WARNINGS: *
  245. * none. *
  246. * *
  247. * HISTORY: *
  248. * 11/28/1994 BR : Created. *
  249. *=============================================================================================*/
  250. void TeamTypeClass::Fill_In(char * name, char *entry)
  251. {
  252. Validate();
  253. int num_classes;
  254. char *p1; // parsing pointer
  255. char *p2; // parsing pointer
  256. int i; // loop counter
  257. TechnoTypeClass const *otype; // ptr to type of object
  258. InfantryType i_id; // infantry ID
  259. UnitType u_id; // unit ID
  260. AircraftType a_id; // aircraft ID
  261. TeamMissionStruct mission;
  262. /*
  263. ------------------------------ Set its name ------------------------------
  264. */
  265. Set_Name(name);
  266. /*
  267. ---------------------------- 1st token: House ----------------------------
  268. */
  269. House = HouseTypeClass::From_Name(strtok(entry,","));
  270. /*
  271. -------------------------- 2nd token: RoundAbout -------------------------
  272. */
  273. IsRoundAbout = atoi(strtok(NULL,","));
  274. /*
  275. --------------------------- 3rd token: Learning --------------------------
  276. */
  277. IsLearning = atoi(strtok(NULL,","));
  278. /*
  279. --------------------------- 4th token: Suicide ---------------------------
  280. */
  281. IsSuicide = atoi(strtok(NULL,","));
  282. /*
  283. ----------------------------- 5th token: Spy -----------------------------
  284. */
  285. IsAutocreate = atoi(strtok(NULL,","));
  286. /*
  287. -------------------------- 6th token: Mercenary --------------------------
  288. */
  289. IsMercenary = atoi(strtok(NULL,","));
  290. /*
  291. ----------------------- 7th token: RecruitPriority -----------------------
  292. */
  293. RecruitPriority = atoi(strtok(NULL,","));
  294. /*
  295. -------------------------- 8th token: MaxAllowed -------------------------
  296. */
  297. MaxAllowed = atoi(strtok(NULL,","));
  298. /*
  299. --------------------------- 9th token: InitNum ---------------------------
  300. */
  301. InitNum = atoi(strtok(NULL,","));
  302. /*
  303. ------------------------- 10th token: Fear level -------------------------
  304. */
  305. Fear = atoi(strtok(NULL,","));
  306. /*
  307. ------------------------ 11th token: Class count -------------------------
  308. */
  309. num_classes = atoi(strtok(NULL,","));
  310. /*
  311. -------------- Loop through entries, setting class ptr & num -------------
  312. */
  313. ClassCount = 0;
  314. for (i = 0; i < num_classes; i++) {
  315. p1 = strtok(NULL,",:");
  316. p2 = strtok(NULL,",:");
  317. otype = NULL;
  318. /*
  319. ------------------- See if this is an infantry name -------------------
  320. */
  321. i_id = InfantryTypeClass::From_Name(p1);
  322. if (i_id != INFANTRY_NONE) {
  323. otype = &InfantryTypeClass::As_Reference(i_id);
  324. }
  325. /*
  326. ---------------------- See if this is a unit name ---------------------
  327. */
  328. u_id = UnitTypeClass::From_Name(p1);
  329. if (u_id != UNIT_NONE) {
  330. otype = &UnitTypeClass::As_Reference(u_id);
  331. }
  332. /*
  333. ------------------- See if this is an aircraft name -------------------
  334. */
  335. a_id = AircraftTypeClass::From_Name(p1);
  336. if (a_id != AIRCRAFT_NONE) {
  337. otype = &AircraftTypeClass::As_Reference(a_id);
  338. }
  339. /*
  340. --------------- If the name was resolved, add this class --------------
  341. */
  342. if (otype) {
  343. Class[ClassCount] = otype;
  344. DesiredNum[ClassCount] = atoi(p2);
  345. ClassCount++;
  346. }
  347. }
  348. /*
  349. ----------------------- next token: Mission count ------------------------
  350. */
  351. MissionCount = atoi(strtok(NULL,","));
  352. for (i = 0; i < MissionCount; i++) {
  353. p1 = strtok(NULL,",:");
  354. p2 = strtok(NULL,",:");
  355. mission.Mission = Mission_From_Name(p1);
  356. mission.Argument = atoi(p2);
  357. MissionList[i] = mission;
  358. }
  359. char * ptr = strtok(NULL, ",");
  360. if (ptr) {
  361. IsReinforcable = atoi(ptr);
  362. }
  363. ptr = strtok(NULL, ",");
  364. if (ptr) {
  365. IsPrebuilt = atoi(ptr);
  366. }
  367. }
  368. /***************************************************************************
  369. * TeamTypeClass::Write_INI -- writes INI data *
  370. * *
  371. * INI entry format: *
  372. * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, *
  373. * RecruitPriority,MaxAllowed,InitNum,Fear, *
  374. * ClassCount,Class:Num,Class:Num,..., *
  375. * MissionCount,Mission,Arg,Mission,Arg,Mission,Arg,... *
  376. * *
  377. * INPUT: *
  378. * buffer buffer to store INI data in *
  379. * *
  380. * OUTPUT: *
  381. * none. *
  382. * *
  383. * WARNINGS: *
  384. * none. *
  385. * *
  386. * HISTORY: *
  387. * 12/07/1994 BR : Created. *
  388. *=========================================================================*/
  389. void TeamTypeClass::Write_INI(char *buffer, bool refresh)
  390. {
  391. int index;
  392. int i;
  393. char buf[500];
  394. TeamTypeClass * team;
  395. char const *hname;
  396. /*------------------------------------------------------------------------
  397. First, clear out all existing teamtypes in the old-style format.
  398. ------------------------------------------------------------------------*/
  399. WWWritePrivateProfileString("Teams", NULL, NULL, buffer);
  400. /*------------------------------------------------------------------------
  401. Clear out all existing teamtype data from the INI file.
  402. ------------------------------------------------------------------------*/
  403. if (refresh) {
  404. WWWritePrivateProfileString(INI_Name(), NULL, NULL, buffer);
  405. }
  406. /*------------------------------------------------------------------------
  407. Now write all the team data out
  408. ------------------------------------------------------------------------*/
  409. buf[0] = 0;
  410. for (index = 0; index < TeamTypes.Count(); index++) {
  411. /*
  412. .................. Get ptr to next active teamtype ....................
  413. */
  414. team = TeamTypes.Ptr(index);
  415. /*
  416. .......................... Find house's name ..........................
  417. */
  418. if (team->House==HOUSE_NONE) {
  419. hname = "None";
  420. } else {
  421. hname = HouseClass::As_Pointer(team->House)->Class->IniName;
  422. }
  423. /*
  424. ......................... Generate INI entry ..........................
  425. */
  426. sprintf(buf,"%s,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
  427. hname,
  428. team->IsRoundAbout,
  429. team->IsLearning,
  430. team->IsSuicide,
  431. team->IsAutocreate,
  432. team->IsMercenary,
  433. team->RecruitPriority,
  434. team->MaxAllowed,
  435. team->InitNum,
  436. team->Fear,
  437. team->ClassCount);
  438. /*.....................................................................
  439. For every class in the team, record the class's name & desired count
  440. .....................................................................*/
  441. for (i = 0; i < team->ClassCount; i++) {
  442. sprintf (buf + strlen(buf), ",%s:%d",
  443. team->Class[i]->IniName,
  444. team->DesiredNum[i]);
  445. }
  446. /*.....................................................................
  447. Record the # of missions, and each mission name & argument value.
  448. .....................................................................*/
  449. sprintf(buf + strlen(buf),",%d",team->MissionCount);
  450. for (i = 0; i < team->MissionCount; i++) {
  451. sprintf (buf + strlen(buf), ",%s:%d",
  452. Name_From_Mission(team->MissionList[i].Mission),
  453. team->MissionList[i].Argument);
  454. }
  455. if (team->IsReinforcable) {
  456. strcat(buf, ",1");
  457. } else {
  458. strcat(buf, ",0");
  459. }
  460. if (team->IsPrebuilt) {
  461. strcat(buf, ",1");
  462. } else {
  463. strcat(buf, ",0");
  464. }
  465. WWWritePrivateProfileString(INI_Name(), team->IniName, buf, buffer);
  466. }
  467. }
  468. /***************************************************************************
  469. * TeamTypeClass::Read_Old_INI -- reads old INI format *
  470. * *
  471. * INI entry format: *
  472. * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, *
  473. * RecruitPriority,MaxAllowed,InitNum,Class:Num,Class:Num,...,Fear *
  474. * *
  475. * INPUT: *
  476. * buffer buffer to hold the INI data *
  477. * *
  478. * OUTPUT: *
  479. * none. *
  480. * *
  481. * WARNINGS: *
  482. * none. *
  483. * *
  484. * HISTORY: *
  485. * 12/07/1994 BR : Created. *
  486. * 02/01/1995 BR : No del team if no classes (editor needs empty teams!) *
  487. *=========================================================================*/
  488. void TeamTypeClass::Read_Old_INI(char *buffer)
  489. {
  490. TeamTypeClass * team; // Working team pointer.
  491. char *tbuffer; // Accumulation buffer of team names.
  492. int len; // Length of data in buffer.
  493. char buf[256]; // INI entry buffer
  494. char *p1; // parsing pointer
  495. char *p2; // parsing pointer
  496. int index;
  497. TechnoTypeClass const *otype; // ptr to type of object
  498. InfantryType i_id; // infantry ID
  499. UnitType u_id; // unit ID
  500. AircraftType a_id; // infantry ID
  501. /*------------------------------------------------------------------------
  502. Set 'tbuffer' to point just past the INI buffer
  503. ------------------------------------------------------------------------*/
  504. len = strlen(buffer) + 2;
  505. tbuffer = buffer + len;
  506. /*------------------------------------------------------------------------
  507. Read all TeamType entry names into 'tbuffer'
  508. ------------------------------------------------------------------------*/
  509. WWGetPrivateProfileString("Teams", NULL, NULL, tbuffer, ShapeBufferSize-len, buffer);
  510. /*
  511. ----------------------- Loop for all team entries ------------------------
  512. */
  513. while (*tbuffer != '\0') {
  514. /*
  515. ........................ Create a new trigger .........................
  516. */
  517. team = new TeamTypeClass();
  518. /*
  519. ............................ Set its name .............................
  520. */
  521. team->Set_Name(tbuffer);
  522. /*
  523. ......................... Get the team entry ..........................
  524. */
  525. WWGetPrivateProfileString("Teams", tbuffer, NULL, buf, sizeof(buf)-1, buffer);
  526. /*
  527. .......................... 1st token: House ...........................
  528. */
  529. team->House = HouseTypeClass::From_Name(strtok(buf,","));
  530. /*
  531. ........................ 2nd token: RoundAbout ........................
  532. */
  533. team->IsRoundAbout = atoi(strtok(NULL,","));
  534. /*
  535. ......................... 3rd token: Learning .........................
  536. */
  537. team->IsLearning = atoi(strtok(NULL,","));
  538. /*
  539. ......................... 4th token: Suicide ..........................
  540. */
  541. team->IsSuicide = atoi(strtok(NULL,","));
  542. /*
  543. ........................... 5th token: Spy ............................
  544. */
  545. team->IsAutocreate = atoi(strtok(NULL,","));
  546. /*
  547. ........................ 6th token: Mercenary .........................
  548. */
  549. team->IsMercenary = atoi(strtok(NULL,","));
  550. /*
  551. ..................... 7th token: RecruitPriority ......................
  552. */
  553. team->RecruitPriority = atoi(strtok(NULL,","));
  554. /*
  555. ........................ 8th token: MaxAllowed ........................
  556. */
  557. team->MaxAllowed = atoi(strtok(NULL,","));
  558. /*
  559. ......................... 9th token: InitNum ..........................
  560. */
  561. team->InitNum = atoi(strtok(NULL,","));
  562. /*
  563. ....................... 10th token: Mission name ......................
  564. */
  565. strtok(NULL,","); // just throw it away
  566. /*
  567. ............ Loop through entries, setting class ptr & num ............
  568. */
  569. index = 0;
  570. p1 = strtok(NULL,",:");
  571. p2 = strtok(NULL,",:");
  572. while (p1 && p2) {
  573. otype = NULL;
  574. /*
  575. ................. See if this is an infantry name ..................
  576. */
  577. i_id = InfantryTypeClass::From_Name(p1);
  578. if (i_id!=INFANTRY_NONE) {
  579. otype = &InfantryTypeClass::As_Reference(i_id);
  580. }
  581. /*
  582. .................... See if this is a unit name ....................
  583. */
  584. u_id = UnitTypeClass::From_Name(p1);
  585. if (u_id != UNIT_NONE) {
  586. otype = &UnitTypeClass::As_Reference(u_id);
  587. }
  588. /*
  589. ................. See if this is an aircraft name ..................
  590. */
  591. a_id = AircraftTypeClass::From_Name(p1);
  592. if (a_id != AIRCRAFT_NONE) {
  593. otype = &AircraftTypeClass::As_Reference(a_id);
  594. }
  595. /*
  596. ............. If the name was resolved, add this class .............
  597. */
  598. if (otype) {
  599. team->Class[index] = otype;
  600. team->DesiredNum[index] = atoi(p2);
  601. index++;
  602. team->ClassCount = index;
  603. }
  604. /*
  605. ................. Go to the next entry on the line .................
  606. */
  607. p1 = strtok(NULL,",:");
  608. p2 = strtok(NULL,",:");
  609. }
  610. team->Fear = 0;
  611. /*
  612. ...................... Go to the next INI entry .......................
  613. */
  614. tbuffer += strlen(tbuffer)+1;
  615. }
  616. }
  617. /***************************************************************************
  618. * TeamTypeClass::As_Pointer -- gets ptr for team type with given name *
  619. * *
  620. * INPUT: *
  621. * name name of teamtype *
  622. * *
  623. * OUTPUT: *
  624. * ptr to TeamType with that name *
  625. * *
  626. * WARNINGS: *
  627. * none. *
  628. * *
  629. * HISTORY: *
  630. * 12/07/1994 BR : Created. *
  631. *=========================================================================*/
  632. TeamTypeClass * TeamTypeClass::As_Pointer(char *name)
  633. {
  634. int i;
  635. if (name == NULL) {
  636. return(NULL);
  637. }
  638. for (i = 0; i < TeamTypes.Count(); i++) {
  639. if (!stricmp(name, TeamTypes.Ptr(i)->IniName)) {
  640. return(TeamTypes.Ptr(i));
  641. }
  642. }
  643. return(NULL);
  644. }
  645. /***************************************************************************
  646. * TeamTypeClass::Remove -- removes this team from the system *
  647. * *
  648. * INPUT: *
  649. * none. *
  650. * *
  651. * OUTPUT: *
  652. * none. *
  653. * *
  654. * WARNINGS: *
  655. * none. *
  656. * *
  657. * HISTORY: *
  658. * 12/09/1994 BR : Created. *
  659. *=========================================================================*/
  660. void TeamTypeClass::Remove(void)
  661. {
  662. Validate();
  663. int i;
  664. TriggerClass * trigger;
  665. /*
  666. ** Remove all trigger references to this team.
  667. */
  668. for (i = 0; i < Triggers.Count(); i++) {
  669. trigger = Triggers.Ptr(i);
  670. if (trigger->Team == this) {
  671. trigger->Team = NULL;
  672. }
  673. }
  674. /*
  675. ** Delete myself.
  676. */
  677. delete this;
  678. }
  679. /***************************************************************************
  680. * TeamTypeClass::Mission_From_Name -- returns team mission for given name *
  681. * *
  682. * INPUT: *
  683. * name name to compare *
  684. * *
  685. * OUTPUT: *
  686. * mission for that name *
  687. * *
  688. * WARNINGS: *
  689. * none. *
  690. * *
  691. * HISTORY: *
  692. * 12/13/1994 BR : Created. *
  693. *=========================================================================*/
  694. TeamMissionType TeamTypeClass::Mission_From_Name(char const *name)
  695. {
  696. int order;
  697. if (name) {
  698. for (order = TMISSION_FIRST; order < TMISSION_COUNT; order++) {
  699. if (stricmp(TMissions[order], name) == 0) {
  700. return((TeamMissionType) order);
  701. }
  702. }
  703. }
  704. return(TMISSION_NONE);
  705. }
  706. /***************************************************************************
  707. * TeamTypeClass::Name_From_Mission -- returns name for given mission *
  708. * *
  709. * INPUT: *
  710. * order mission to get name for *
  711. * *
  712. * OUTPUT: *
  713. * name of mission *
  714. * *
  715. * WARNINGS: *
  716. * none. *
  717. * *
  718. * HISTORY: *
  719. * 12/13/1994 BR : Created. *
  720. *=========================================================================*/
  721. char const * TeamTypeClass::Name_From_Mission(TeamMissionType order)
  722. {
  723. if (order <= TMISSION_NONE || order >= TMISSION_COUNT) {
  724. return("None");
  725. } else {
  726. return(TMissions[order]);
  727. }
  728. }
  729. /***************************************************************************
  730. * TeamTypeClass::operator new -- 'new' operator *
  731. * *
  732. * INPUT: *
  733. * none. *
  734. * *
  735. * OUTPUT: *
  736. * pointer to new TeamType *
  737. * *
  738. * WARNINGS: *
  739. * none. *
  740. * *
  741. * HISTORY: *
  742. * 11/28/1994 BR : Created. *
  743. *=========================================================================*/
  744. void * TeamTypeClass::operator new(size_t )
  745. {
  746. void * ptr = TeamTypes.Allocate();
  747. if (ptr) {
  748. ((TeamTypeClass *)ptr)->IsActive = true;
  749. }
  750. return(ptr);
  751. }
  752. /***************************************************************************
  753. * TeamTypeClass::operator delete -- 'delete' operator *
  754. * *
  755. * INPUT: *
  756. * ptr pointer to delete *
  757. * *
  758. * OUTPUT: *
  759. * none. *
  760. * *
  761. * WARNINGS: *
  762. * none. *
  763. * *
  764. * HISTORY: *
  765. * 11/28/1994 BR : Created. *
  766. *=========================================================================*/
  767. void TeamTypeClass::operator delete(void *ptr)
  768. {
  769. if (ptr) {
  770. ((TeamTypeClass *)ptr)->IsActive = false;
  771. }
  772. TeamTypes.Free((TeamTypeClass *)ptr);
  773. }
  774. TeamClass * TeamTypeClass::Create_One_Of(void) const
  775. {
  776. if (ScenarioInit || TeamClass::Number[TeamTypes.ID(this)] < MaxAllowed) {
  777. return(new TeamClass(this, HouseClass::As_Pointer(House)));
  778. }
  779. return(NULL);
  780. }
  781. TARGET TeamTypeClass::As_Target(void) const
  782. {
  783. Validate();
  784. return(Build_Target(KIND_TEAMTYPE, TeamTypes.ID(this)));
  785. }
  786. void TeamTypeClass::Destroy_All_Of(void) const
  787. {
  788. for (int index = 0; index < Teams.Count(); index++) {
  789. TeamClass * team = Teams.Ptr(index);
  790. if (team->Class == this) {
  791. delete team;
  792. index--;
  793. }
  794. }
  795. }
  796. /***********************************************************************************************
  797. * TeamTypeClass::Suggested_New_Team -- Suggests a new team to create. *
  798. * *
  799. * This routine will scan through the team types available and create teams of the *
  800. * type that can best utilize the existing unit mix. *
  801. * *
  802. * INPUT: house -- Pointer to the house that this team is to be created for. *
  803. * *
  804. * utype -- A bit mask of the unit types available for this house. *
  805. * *
  806. * itypes -- A bit mask of the infantry types available for this house. *
  807. * *
  808. * alerted -- Is this house alerted? If true, then the Autocreate teams will be *
  809. * considered in the selection process. *
  810. * *
  811. * OUTPUT: Returns with a pointer to the team type that should be created. If no team should *
  812. * be created, then it returns NULL. *
  813. * *
  814. * WARNINGS: none *
  815. * *
  816. * HISTORY: *
  817. * 07/13/1995 JLB : Created. *
  818. * 07/21/1995 JLB : Will autocreate team even if no members in field. *
  819. *=============================================================================================*/
  820. TeamTypeClass const * TeamTypeClass::Suggested_New_Team(HouseClass * house, long utypes, long itypes, bool alerted)
  821. {
  822. TeamTypeClass const * best = NULL;
  823. int bestvalue = 0;
  824. for (int index = 0; index < TeamTypes.Count(); index++) {
  825. TeamTypeClass const * ttype = TeamTypes.Ptr(index);
  826. if (ttype &&
  827. ttype->House == house->Class->House &&
  828. TeamClass::Number[index] < ((alerted || !ttype->IsAutocreate) ? ttype->MaxAllowed : 0)) {
  829. /*
  830. ** Determine what kind of units this team requires.
  831. */
  832. long uneeded = 0;
  833. long ineeded = 0;
  834. for (int ctype = 0; ctype < ttype->ClassCount; ctype++) {
  835. switch (ttype->Class[ctype]->What_Am_I()) {
  836. case RTTI_INFANTRYTYPE:
  837. ineeded |= (1 << ((InfantryTypeClass *)ttype->Class[ctype])->Type);
  838. break;
  839. case RTTI_UNITTYPE:
  840. uneeded |= (1 << ((UnitTypeClass *)ttype->Class[ctype])->Type);
  841. break;
  842. }
  843. }
  844. /*
  845. ** If this team can use the types required, then consider it a possible
  846. ** team type to create.
  847. */
  848. int value = 0;
  849. if ((ineeded & itypes) || (uneeded & utypes)) {
  850. value = ttype->RecruitPriority;
  851. } else {
  852. value = ttype->RecruitPriority/2;
  853. }
  854. if (!best || bestvalue < value) {
  855. bestvalue = value;
  856. best = ttype;
  857. }
  858. }
  859. }
  860. return(best);
  861. }