TEAMTYPE.CPP 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: /CounterStrike/TEAMTYPE.CPP 1 3/03/97 10:25a Joe_bostic $ */
  15. /***********************************************************************************************
  16. *** 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 ***
  17. ***********************************************************************************************
  18. * *
  19. * Project Name : Command & Conquer *
  20. * *
  21. * File Name : TEAMTYPE.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : 06/28/96 *
  26. * *
  27. * Last Update : July 30, 1996 [JLB] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * TeamMissionClass::Description -- Compose a text description of team mi *
  32. * TeamMissionClass::Draw_It -- Draws a team mission list box entry. *
  33. * TeamMission_Needs -- Determines what extra data is needed by team miss *
  34. * TeamTypeClass::As_Pointer -- gets ptr for team type with given name *
  35. * TeamTypeClass::Build_INI_Entry -- Builds the INI entry for this team type. *
  36. * TeamTypeClass::Create_One_Of -- Creates a team of this type. *
  37. * TeamTypeClass::Description -- Builds a description of the team. *
  38. * TeamTypeClass::Destroy_All_Of -- Destroy all teams of this type. *
  39. * TeamTypeClass::Detach -- Detach the specified target from this team type. *
  40. * TeamTypeClass::Draw_It -- Display the team type in a list box. *
  41. * TeamTypeClass::Edit -- Edit the team type. *
  42. * TeamTypeClass::Fill_In -- fills in trigger from the given INI entry *
  43. * TeamTypeClass::From_Name -- Converts a name into a team type pointer. *
  44. * TeamTypeClass::Init -- pre-scenario initialization *
  45. * TeamTypeClass::Member_Description -- Builds a member description string *
  46. * TeamTypeClass::Mission_From_Name -- returns mission for given name *
  47. * TeamTypeClass::Name_From_Mission -- returns name for given mission *
  48. * TeamTypeClass::Read_INI -- reads INI data *
  49. * TeamTypeClass::Suggested_New_Team -- Suggests a new team to create. *
  50. * TeamTypeClass::TeamTypeClass -- class constructor *
  51. * TeamTypeClass::Write_INI -- Write out the team types to the INI database. *
  52. * TeamTypeClass::operator delete -- 'delete' operator *
  53. * TeamTypeClass::operator new -- 'new' operator *
  54. * TeamTypeClass::~TeamTypeClass -- class destructor *
  55. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  56. #include "function.h"
  57. TeamMissionClass TeamMissions[TMISSION_COUNT] = {
  58. {TMISSION_ATTACK},
  59. {TMISSION_ATT_WAYPT},
  60. {TMISSION_FORMATION},
  61. {TMISSION_MOVE},
  62. {TMISSION_MOVECELL},
  63. {TMISSION_GUARD},
  64. {TMISSION_LOOP},
  65. {TMISSION_ATTACKTARCOM},
  66. {TMISSION_UNLOAD},
  67. {TMISSION_DEPLOY},
  68. {TMISSION_HOUND_DOG},
  69. {TMISSION_DO},
  70. {TMISSION_SET_GLOBAL},
  71. {TMISSION_LOAD},
  72. {TMISSION_SPY},
  73. {TMISSION_PATROL},
  74. };
  75. int atoh(char * str);
  76. #if defined(CHEAT_KEYS) || defined(SCENARIO_EDITOR)
  77. /***********************************************************************************************
  78. * TeamTypeClass::Draw_It -- Display the team type in a list box. *
  79. * *
  80. * This is a helper routine that is used when this team type is stored into a list box *
  81. * and must be displayed. It will display the team type as a single line of text. *
  82. * *
  83. * INPUT: see below... *
  84. * *
  85. * OUTPUT: none *
  86. * *
  87. * WARNINGS: none *
  88. * *
  89. * HISTORY: *
  90. * 07/30/1996 JLB : Created. *
  91. *=============================================================================================*/
  92. void TeamTypeClass::Draw_It(int , int x, int y, int width, int height, bool selected, TextPrintType flags) const
  93. {
  94. RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
  95. static int _tabs[] = {35, 60, 80, 100};
  96. if ((flags & 0x0F) == TPF_6PT_GRAD || (flags & 0x0F) == TPF_EFNT) {
  97. if (selected) {
  98. flags = flags | TPF_BRIGHT_COLOR;
  99. LogicPage->Fill_Rect(x, y, x + width - 1, y + height - 1, scheme->Shadow);
  100. } else {
  101. if (!(flags & TPF_USE_GRAD_PAL)) {
  102. flags = flags | TPF_MEDIUM_COLOR;
  103. }
  104. }
  105. Conquer_Clip_Text_Print(Description(), x, y, scheme, TBLACK, flags, width, _tabs);
  106. } else {
  107. Conquer_Clip_Text_Print(Description(), x, y, (selected ? &ColorRemaps[PCOLOR_DIALOG_BLUE] : &ColorRemaps[PCOLOR_GREY]), TBLACK, flags, width, _tabs);
  108. }
  109. }
  110. #endif
  111. /*
  112. ********************************** Globals **********************************
  113. */
  114. char const * TeamTypeClass::TMissions[TMISSION_COUNT] = {
  115. "Attack...",
  116. "Attack Waypoint...",
  117. "Change Formation to...",
  118. "Move to waypoint...",
  119. "Move to Cell...",
  120. "Guard area (1/10th min)...",
  121. "Jump to line #...",
  122. "Attack Tarcom",
  123. "Unload",
  124. "Deploy",
  125. "Follow friendlies",
  126. "Do this...",
  127. "Set global...",
  128. "Invulnerable",
  129. "Load onto Transport",
  130. "Spy on bldg @ waypt...",
  131. "Patrol to waypoint..."
  132. };
  133. /***************************************************************************
  134. * TeamTypeClass::TeamTypeClass -- class constructor *
  135. * *
  136. * INPUT: *
  137. * *
  138. * OUTPUT: *
  139. * *
  140. * WARNINGS: *
  141. * *
  142. * HISTORY: *
  143. * 12/07/1994 BR : Created. *
  144. * 11/22/1995 JLB : Uses initializer constructor method. *
  145. *=========================================================================*/
  146. TeamTypeClass::TeamTypeClass(void) :
  147. AbstractTypeClass(RTTI_TEAMTYPE, TeamTypes.ID(this), TXT_NONE, ""),
  148. IsRoundAbout(false),
  149. IsSuicide(false),
  150. IsAutocreate(false),
  151. IsPrebuilt(true),
  152. IsReinforcable(true),
  153. IsTransient(false),
  154. RecruitPriority(7),
  155. InitNum(0),
  156. MaxAllowed(0),
  157. Fear(0),
  158. House(HOUSE_NONE),
  159. Trigger(0),
  160. Origin(-1),
  161. Number(0),
  162. MissionCount(0),
  163. ClassCount(0)
  164. {
  165. for (int i = 0; i < MAX_TEAM_CLASSCOUNT; i++) {
  166. Members[i].Class = NULL;
  167. Members[i].Quantity = 0;
  168. }
  169. }
  170. /***************************************************************************
  171. * TeamTypeClass::Init -- pre-scenario initialization *
  172. * *
  173. * INPUT: *
  174. * *
  175. * OUTPUT: *
  176. * *
  177. * WARNINGS: *
  178. * *
  179. * HISTORY: *
  180. * 12/07/1994 BR : Created. *
  181. *=========================================================================*/
  182. void TeamTypeClass::Init(void)
  183. {
  184. TeamTypes.Free_All();
  185. }
  186. /***************************************************************************
  187. * TeamTypeClass::As_Pointer -- gets ptr for team type with given name *
  188. * *
  189. * INPUT: *
  190. * name name of teamtype *
  191. * *
  192. * OUTPUT: *
  193. * ptr to TeamType with that name *
  194. * *
  195. * WARNINGS: *
  196. * none. *
  197. * *
  198. * HISTORY: *
  199. * 12/07/1994 BR : Created. *
  200. *=========================================================================*/
  201. TeamTypeClass * TeamTypeClass::As_Pointer(char const * name)
  202. {
  203. if (name) {
  204. for (int index = 0; index < TeamTypes.Count(); index++) {
  205. if (!stricmp(name, TeamTypes.Ptr(index)->IniName)) {
  206. return(TeamTypes.Ptr(index));
  207. }
  208. }
  209. }
  210. return(NULL);
  211. }
  212. /***************************************************************************
  213. * TeamTypeClass::Mission_From_Name -- returns team mission for given name *
  214. * *
  215. * INPUT: *
  216. * name name to compare *
  217. * *
  218. * OUTPUT: *
  219. * mission for that name *
  220. * *
  221. * WARNINGS: *
  222. * none. *
  223. * *
  224. * HISTORY: *
  225. * 12/13/1994 BR : Created. *
  226. *=========================================================================*/
  227. TeamMissionType TeamTypeClass::Mission_From_Name(char const * name)
  228. {
  229. if (name) {
  230. for (TeamMissionType order = TMISSION_FIRST; order < TMISSION_COUNT; order++) {
  231. if (stricmp(TMissions[order], name) == 0) {
  232. return(order);
  233. }
  234. }
  235. }
  236. return(TMISSION_NONE);
  237. }
  238. /***************************************************************************
  239. * TeamTypeClass::Name_From_Mission -- returns name for given mission *
  240. * *
  241. * INPUT: *
  242. * order mission to get name for *
  243. * *
  244. * OUTPUT: *
  245. * name of mission *
  246. * *
  247. * WARNINGS: *
  248. * none. *
  249. * *
  250. * HISTORY: *
  251. * 12/13/1994 BR : Created. *
  252. *=========================================================================*/
  253. char const * TeamTypeClass::Name_From_Mission(TeamMissionType order)
  254. {
  255. assert((unsigned)order < TMISSION_COUNT);
  256. return(TMissions[order]);
  257. }
  258. /***************************************************************************
  259. * TeamTypeClass::operator new -- 'new' operator *
  260. * *
  261. * INPUT: *
  262. * none. *
  263. * *
  264. * OUTPUT: *
  265. * pointer to new TeamType *
  266. * *
  267. * WARNINGS: *
  268. * none. *
  269. * *
  270. * HISTORY: *
  271. * 11/28/1994 BR : Created. *
  272. *=========================================================================*/
  273. void * TeamTypeClass::operator new(size_t )
  274. {
  275. void * ptr = TeamTypes.Allocate();
  276. if (ptr) {
  277. ((TeamTypeClass *)ptr)->IsActive = true;
  278. }
  279. return(ptr);
  280. }
  281. /***************************************************************************
  282. * TeamTypeClass::operator delete -- 'delete' operator *
  283. * *
  284. * INPUT: *
  285. * ptr pointer to delete *
  286. * *
  287. * OUTPUT: *
  288. * none. *
  289. * *
  290. * WARNINGS: *
  291. * none. *
  292. * *
  293. * HISTORY: *
  294. * 11/28/1994 BR : Created. *
  295. *=========================================================================*/
  296. void TeamTypeClass::operator delete(void * ptr)
  297. {
  298. if (ptr) {
  299. ((TeamTypeClass *)ptr)->IsActive = false;
  300. }
  301. TeamTypes.Free((TeamTypeClass *)ptr);
  302. }
  303. /***********************************************************************************************
  304. * TeamTypeClass::Create_One_Of -- Creates a team of this type. *
  305. * *
  306. * Use this routine to create a team object from this team type. *
  307. * *
  308. * INPUT: none *
  309. * *
  310. * OUTPUT: Returns with a pointer to the newly created team object. If one could not be *
  311. * created, then NULL is returned. *
  312. * *
  313. * WARNINGS: none *
  314. * *
  315. * HISTORY: *
  316. * 09/21/1995 JLB : Created. *
  317. *=============================================================================================*/
  318. TeamClass * TeamTypeClass::Create_One_Of(void) const
  319. {
  320. if (ScenarioInit || Number < MaxAllowed) {
  321. // if (ScenarioInit || TeamClass::Number[ID] < MaxAllowed) {
  322. return(new TeamClass(this, HouseClass::As_Pointer(House)));
  323. }
  324. return(NULL);
  325. }
  326. /***********************************************************************************************
  327. * TeamTypeClass::Destroy_All_Of -- Destroy all teams of this type. *
  328. * *
  329. * This routine will destroy all teams of this type. Typical use of this is from a trigger *
  330. * event. *
  331. * *
  332. * INPUT: none *
  333. * *
  334. * OUTPUT: none *
  335. * *
  336. * WARNINGS: none *
  337. * *
  338. * HISTORY: *
  339. * 09/21/1995 JLB : Created. *
  340. *=============================================================================================*/
  341. void TeamTypeClass::Destroy_All_Of(void) const
  342. {
  343. for (int index = 0; index < Teams.Count(); index++) {
  344. TeamClass * team = Teams.Ptr(index);
  345. if (team->Class == this) {
  346. delete team;
  347. index--;
  348. }
  349. }
  350. }
  351. /***********************************************************************************************
  352. * TeamTypeClass::Suggested_New_Team -- Suggests a new team to create. *
  353. * *
  354. * This routine will scan through the team types available and create teams of the *
  355. * type that can best utilize the existing unit mix. *
  356. * *
  357. * INPUT: house -- Pointer to the house that this team is to be created for. *
  358. * *
  359. * atypes -- A bit mask of the aircraft types available for this house. *
  360. * *
  361. * utypes -- A bit mask of the unit types available for this house. *
  362. * *
  363. * itypes -- A bit mask of the infantry types available for this house. *
  364. * *
  365. * vtypes -- A bit mask of the vessel types available for this house. *
  366. * *
  367. * alerted -- Is this house alerted? If true, then the Autocreate teams will be *
  368. * considered in the selection process. *
  369. * *
  370. * OUTPUT: Returns with a pointer to the team type that should be created. If no team should *
  371. * be created, then it returns NULL. *
  372. * *
  373. * WARNINGS: none *
  374. * *
  375. * HISTORY: *
  376. * 07/13/1995 JLB : Created. *
  377. * 07/21/1995 JLB : Will autocreate team even if no members in field. *
  378. *=============================================================================================*/
  379. TeamTypeClass const * TeamTypeClass::Suggested_New_Team(HouseClass * house, long , long , long , long , bool alerted)
  380. //TeamTypeClass const * TeamTypeClass::Suggested_New_Team(HouseClass * house, long atypes, long utypes, long itypes, long vtypes, bool alerted)
  381. {
  382. // TeamTypeClass const * best = NULL;
  383. // int bestvalue = 0;
  384. TeamTypeClass const * choices[20];
  385. int choicecount = 0;
  386. for (int index = 0; index < TeamTypes.Count(); index++) {
  387. TeamTypeClass const * ttype = TeamTypes.Ptr(index);
  388. assert(ttype != NULL);
  389. int maxnum = ttype->MaxAllowed;
  390. if ((alerted && !ttype->IsAutocreate) || (!alerted && ttype->IsAutocreate)) {
  391. maxnum = 0;
  392. }
  393. if (choicecount >= ARRAY_SIZE(choices)) break;
  394. if (ttype != NULL && ttype->House == house->Class->House && ttype->Number < maxnum) {
  395. choices[choicecount++] = ttype;
  396. #ifdef OBSOLETE
  397. /*
  398. ** Determine what kind of units this team requires.
  399. */
  400. long uneeded = 0;
  401. long ineeded = 0;
  402. long vneeded = 0;
  403. long aneeded = 0;
  404. for (int ctype = 0; ctype < ttype->ClassCount; ctype++) {
  405. switch (ttype->Members[ctype].Class->What_Am_I()) {
  406. case RTTI_INFANTRYTYPE:
  407. ineeded |= (1 << ((InfantryTypeClass *)ttype->Members[ctype].Class)->Type);
  408. break;
  409. case RTTI_UNITTYPE:
  410. uneeded |= (1 << ((UnitTypeClass *)ttype->Members[ctype].Class)->Type);
  411. break;
  412. case RTTI_VESSELTYPE:
  413. vneeded |= (1 << ((VesselTypeClass *)ttype->Members[ctype].Class)->Type);
  414. break;
  415. case RTTI_AIRCRAFTTYPE:
  416. aneeded |= (1 << ((AircraftTypeClass *)ttype->Members[ctype].Class)->Type);
  417. break;
  418. }
  419. }
  420. /*
  421. ** If this team can use the types required, then consider it a possible
  422. ** team type to create.
  423. */
  424. int value = 0;
  425. if ((aneeded & atypes) != 0 || (ineeded & itypes) != 0 || (uneeded & utypes) != 0 || (vneeded & vtypes) != 0) {
  426. value = ttype->RecruitPriority;
  427. } else {
  428. value = ttype->RecruitPriority/2;
  429. }
  430. if (best == NULL || bestvalue < value) {
  431. bestvalue = value;
  432. best = ttype;
  433. }
  434. #endif
  435. }
  436. }
  437. if (choicecount > 0) {
  438. return(choices[Random_Pick(0, choicecount-1)]);
  439. }
  440. return(NULL);
  441. // return(best);
  442. }
  443. /***********************************************************************************************
  444. * TeamTypeClass::From_Name -- Converts a name into a team type pointer. *
  445. * *
  446. * This routine is used to convert an ASCII name of a team type into the corresponding *
  447. * team type pointer. *
  448. * *
  449. * INPUT: name -- Pointer to the ASCII name of the team type. *
  450. * *
  451. * OUTPUT: Returns with a pointer to the team type that this ASCII name represents. If there *
  452. * is no match, the NULL is returned. *
  453. * *
  454. * WARNINGS: none *
  455. * *
  456. * HISTORY: *
  457. * 01/26/1996 JLB : Created. *
  458. *=============================================================================================*/
  459. TeamTypeClass * TeamTypeClass::From_Name(char const * name)
  460. {
  461. if (name) {
  462. for (int index = 0; index < TeamTypes.Count(); index++) {
  463. if (stricmp(name, TeamTypes.Ptr(index)->IniName) == 0) {
  464. return(TeamTypes.Ptr(index));
  465. }
  466. }
  467. }
  468. return(0);
  469. }
  470. /***********************************************************************************************
  471. * TeamMission_Needs -- Determines what extra data is needed by team mission. *
  472. * *
  473. * This routine will return the required extra data that the specified team mission will *
  474. * need. *
  475. * *
  476. * INPUT: tmtype -- The team mission type to check. *
  477. * *
  478. * OUTPUT: Returns with the data type needed for this team mission. *
  479. * *
  480. * WARNINGS: none *
  481. * *
  482. * HISTORY: *
  483. * 01/26/1996 JLB : Created. *
  484. *=============================================================================================*/
  485. NeedType TeamMission_Needs(TeamMissionType tmtype)
  486. {
  487. switch (tmtype) {
  488. /*
  489. ** Requires a formation type.
  490. */
  491. case TMISSION_FORMATION:
  492. return(NEED_FORMATION);
  493. /*
  494. ** Team mission requires a target quarry value.
  495. */
  496. case TMISSION_ATTACK:
  497. return(NEED_QUARRY);
  498. /*
  499. ** Team mission requires a data value.
  500. */
  501. case TMISSION_MOVECELL:
  502. return(NEED_HEX_NUMBER);
  503. case TMISSION_SET_GLOBAL:
  504. case TMISSION_GUARD:
  505. case TMISSION_LOOP:
  506. return(NEED_NUMBER);
  507. /*
  508. ** Team mission requires a waypoint.
  509. */
  510. case TMISSION_PATROL:
  511. case TMISSION_MOVE:
  512. case TMISSION_ATT_WAYPT:
  513. case TMISSION_SPY:
  514. return(NEED_WAYPOINT);
  515. /*
  516. ** Team mission requires a general mission type.
  517. */
  518. case TMISSION_DO:
  519. return(NEED_MISSION);
  520. default:
  521. break;
  522. }
  523. return(NEED_NONE);
  524. }
  525. #ifdef SCENARIO_EDITOR
  526. /***********************************************************************************************
  527. * TeamMissionClass::Draw_It -- Draws a team mission list box entry. *
  528. * *
  529. * This routine will display a team mission list box entry. It converts the index number *
  530. * into the appropriate text string and then displays the text at the coordinates *
  531. * specified. *
  532. * *
  533. * INPUT: index -- The index number to use when rendering the team mission. *
  534. * *
  535. * x,y -- The X,Y coordinate to use when drawing the team mission entry. *
  536. * *
  537. * width, height -- The dimensions of the area that the description can be *
  538. * rendered into. *
  539. * *
  540. * selected -- Is this entry currently selected? If so, then it should be rendered *
  541. * differently. *
  542. * *
  543. * flags -- Text print control flags used for when the text is printed. *
  544. * *
  545. * OUTPUT: none *
  546. * *
  547. * WARNINGS: none *
  548. * *
  549. * HISTORY: *
  550. * 01/05/1996 JLB : Created. *
  551. *=============================================================================================*/
  552. void TeamMissionClass::Draw_It(int index, int x, int y, int width, int height, bool selected, TextPrintType flags)
  553. {
  554. RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
  555. static int _tabs[] = {13,40};
  556. if ((flags & 0x0F) == TPF_6PT_GRAD || (flags & 0x0F) == TPF_EFNT) {
  557. if (selected) {
  558. flags = flags | TPF_BRIGHT_COLOR;
  559. LogicPage->Fill_Rect(x, y, x + width - 1, y + height - 1,
  560. scheme->Shadow);
  561. } else {
  562. if (!(flags & TPF_USE_GRAD_PAL)) {
  563. flags = flags | TPF_MEDIUM_COLOR;
  564. }
  565. }
  566. Conquer_Clip_Text_Print(Description(index), x, y, scheme, TBLACK, flags, width, _tabs);
  567. } else {
  568. Conquer_Clip_Text_Print(Description(index), x, y,
  569. (selected ? &ColorRemaps[PCOLOR_DIALOG_BLUE] : &ColorRemaps[PCOLOR_GREY]), TBLACK, flags, width, _tabs);
  570. }
  571. }
  572. /***********************************************************************************************
  573. * TeamTypeClass::Edit -- Edit the team type. *
  574. * *
  575. * This routine handles the editing dialog box for the team type. *
  576. * *
  577. * INPUT: none *
  578. * *
  579. * OUTPUT: Was the team type edited? A FALSE indicates that the dialog was canceled. *
  580. * *
  581. * WARNINGS: none *
  582. * *
  583. * HISTORY: *
  584. * 01/05/1996 JLB : Created. *
  585. *=============================================================================================*/
  586. bool TeamTypeClass::Edit(void)
  587. {
  588. /*
  589. ** Dialog & button dimensions
  590. */
  591. enum {
  592. D_DIALOG_W = 400,
  593. D_DIALOG_H = 250,
  594. D_DIALOG_X = 0,
  595. D_DIALOG_Y = 0,
  596. D_NAME_X=D_DIALOG_X+35,
  597. D_NAME_Y=D_DIALOG_Y+27,
  598. ED_WIDTH=40,
  599. D_CHECK_X=D_DIALOG_X+35, // Start of check box attribute list.
  600. D_CHECK_Y=D_NAME_Y+25,
  601. CB_SPACING_Y=9, // Vertical spacing between check box lines.
  602. CB_SPACING_X=8, // Horizontal spacing for check box description text.
  603. D_SPACING_X=9, // Horizontal spacing between data entry fields.
  604. D_CANCEL_W = 50,
  605. D_CANCEL_H = 9,
  606. D_CANCEL_X = D_DIALOG_X + D_DIALOG_W - (D_CANCEL_W+35),
  607. D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - (D_CANCEL_H+20),
  608. D_OK_W = 50,
  609. D_OK_H = 9,
  610. D_OK_X = D_DIALOG_X + D_DIALOG_W - (D_OK_W+18)*2,
  611. D_OK_Y = D_CANCEL_Y
  612. };
  613. /*
  614. ** Button enumerations:
  615. */
  616. enum {
  617. BUTTON_NAME=100,
  618. BUTTON_RECRUIT,
  619. BUTTON_MAXNUM,
  620. BUTTON_INITNUM,
  621. BUTTON_HOUSE,
  622. BUTTON_ROUNDABOUT,
  623. BUTTON_LEARNING,
  624. BUTTON_SUICIDE,
  625. BUTTON_AUTO,
  626. BUTTON_PREBUILT,
  627. BUTTON_REINFORCE,
  628. BUTTON_MISSION1,
  629. BUTTON_MISSION2,
  630. BUTTON_ADD,
  631. BUTTON_INSERT,
  632. BUTTON_DELETE,
  633. BUTTON_REPLACE,
  634. BUTTON_ARG,
  635. BUTTON_FORMATION,
  636. BUTTON_MEMBERS,
  637. BUTTON_MISSION,
  638. BUTTON_TRIGGER,
  639. BUTTON_ORIGIN,
  640. BUTTON_OK,
  641. BUTTON_CANCEL,
  642. BUTTON_QUARRY,
  643. };
  644. /*
  645. ** Dialog variables:
  646. */
  647. ControlClass * commands = 0;
  648. RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
  649. /*
  650. ** Team name edit field.
  651. */
  652. char name_buf[10];
  653. EditClass name_edt(BUTTON_NAME, name_buf, sizeof(name_buf),
  654. TPF_EFNT | TPF_NOSHADOW,
  655. D_NAME_X, D_NAME_Y, ED_WIDTH, 9, EditClass::ALPHANUMERIC);
  656. strcpy(name_buf, IniName);
  657. commands = &name_edt;
  658. /*
  659. ** House ownership of this team.
  660. */
  661. char housetext[25] = "";
  662. DropListClass housebtn(BUTTON_HOUSE, housetext, sizeof(housetext),
  663. TPF_EFNT | TPF_NOSHADOW,
  664. name_edt.X+name_edt.Width+D_SPACING_X, name_edt.Y, 55, 8*5,
  665. MFCD::Retrieve("EBTN-UP.SHP"),
  666. MFCD::Retrieve("EBTN-DN.SHP"));
  667. for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) {
  668. housebtn.Add_Item(HouseTypeClass::As_Reference(house).IniName);
  669. }
  670. if (House == HOUSE_NONE) House = HOUSE_GOOD;
  671. housebtn.Set_Selected_Index(House);
  672. housebtn.Add(*commands);
  673. /*
  674. ** Recruit priority for this team.
  675. */
  676. char recr_buf[4];
  677. EditClass recr_edt(BUTTON_RECRUIT, recr_buf, sizeof(recr_buf),
  678. TPF_EFNT | TPF_NOSHADOW,
  679. housebtn.X+housebtn.Width+5+D_SPACING_X, housebtn.Y, ED_WIDTH, 9, EditClass::NUMERIC);
  680. sprintf(recr_buf, "%d", RecruitPriority);
  681. recr_edt.Add(*commands);
  682. /*
  683. ** Maximum allowed for this team type.
  684. */
  685. char maxnum_buf[4];
  686. EditClass maxnum_edt(BUTTON_MAXNUM, maxnum_buf, sizeof(maxnum_buf),
  687. TPF_EFNT | TPF_NOSHADOW,
  688. recr_edt.X+recr_edt.Width+D_SPACING_X, recr_edt.Y, ED_WIDTH, 9, EditClass::NUMERIC);
  689. sprintf(maxnum_buf, "%d", MaxAllowed);
  690. maxnum_edt.Add(*commands);
  691. /*
  692. ** Initial number for this team type.
  693. */
  694. char initnum_buf[4];
  695. EditClass initnum_edt(BUTTON_INITNUM, initnum_buf, sizeof(initnum_buf),
  696. TPF_EFNT | TPF_NOSHADOW,
  697. maxnum_edt.X+maxnum_edt.Width+D_SPACING_X, maxnum_edt.Y, ED_WIDTH, 9, EditClass::NUMERIC);
  698. sprintf(initnum_buf, "%d", InitNum);
  699. initnum_edt.Add(*commands);
  700. /*
  701. ** Waypoint preference to create/reinforce this team.
  702. */
  703. char origin[4];
  704. EditClass originbtn(BUTTON_ORIGIN, origin, sizeof(origin),
  705. TPF_EFNT | TPF_NOSHADOW,
  706. initnum_edt.X+initnum_edt.Width+D_SPACING_X, initnum_edt.Y, 20, 9, EditClass::ALPHA);
  707. *originbtn.Get_Text() = '\0';
  708. if (Origin != -1) {
  709. if (Origin < 26) {
  710. sprintf(originbtn.Get_Text(), "%c", Origin + 'A');
  711. } else {
  712. sprintf(originbtn.Get_Text(), "%c%c", (Origin/26) + 'A'-1, Origin % 26 + 'A');
  713. }
  714. }
  715. originbtn.Add(*commands);
  716. /*
  717. ** Members of this team control button.
  718. */
  719. TextButtonClass membersbtn(BUTTON_MEMBERS, "Members", TPF_EBUTTON, name_edt.X, name_edt.Y+12, 50);
  720. membersbtn.Add(*commands);
  721. /*
  722. ** Trigger to assign to each member of this team (when object joins team).
  723. */
  724. char trigtext[25] = "";
  725. DropListClass triggerbtn(BUTTON_TRIGGER, trigtext, sizeof(trigtext),
  726. TPF_EFNT | TPF_NOSHADOW,
  727. D_DIALOG_X+D_DIALOG_W-95, membersbtn.Y, 60, 8*5,
  728. MFCD::Retrieve("EBTN-UP.SHP"),
  729. MFCD::Retrieve("EBTN-DN.SHP"));
  730. triggerbtn.Add_Item("<NONE>");
  731. for (int index = 0; index < TriggerTypes.Count(); index++) {
  732. triggerbtn.Add_Item(TriggerTypes.Ptr(index)->IniName);
  733. }
  734. if (Trigger.Is_Valid()) {
  735. triggerbtn.Set_Selected_Index(Trigger->Name());
  736. } else {
  737. triggerbtn.Set_Selected_Index(0);
  738. }
  739. triggerbtn.Add(*commands);
  740. /*
  741. ** Roundabout travel logic attribute for this team.
  742. */
  743. CheckBoxClass roundbtn(BUTTON_ROUNDABOUT, D_CHECK_X, D_CHECK_Y);
  744. if (IsRoundAbout) {
  745. roundbtn.Turn_On();
  746. } else {
  747. roundbtn.Turn_Off();
  748. }
  749. roundbtn.Add(*commands);
  750. /*
  751. ** Suicide travel to target attribute.
  752. */
  753. CheckBoxClass suicidebtn(BUTTON_SUICIDE, D_CHECK_X, roundbtn.Y+CB_SPACING_Y);
  754. if (IsSuicide) {
  755. suicidebtn.Turn_On();
  756. } else {
  757. suicidebtn.Turn_Off();
  758. }
  759. suicidebtn.Add(*commands);
  760. /*
  761. ** Autocreate attribute for this team.
  762. */
  763. CheckBoxClass autocreatebtn(BUTTON_AUTO, D_CHECK_X, suicidebtn.Y+CB_SPACING_Y);
  764. if (IsAutocreate) {
  765. autocreatebtn.Turn_On();
  766. } else {
  767. autocreatebtn.Turn_Off();
  768. }
  769. autocreatebtn.Add(*commands);
  770. /*
  771. ** Prebuild team members attribute for this team.
  772. */
  773. CheckBoxClass prebuildbtn(BUTTON_PREBUILT, D_CHECK_X, autocreatebtn.Y+CB_SPACING_Y);
  774. if (IsPrebuilt) {
  775. prebuildbtn.Turn_On();
  776. } else {
  777. prebuildbtn.Turn_Off();
  778. }
  779. prebuildbtn.Add(*commands);
  780. /*
  781. ** Reinforce this team in progress attribute.
  782. */
  783. CheckBoxClass reinforcebtn(BUTTON_REINFORCE, D_CHECK_X, prebuildbtn.Y+CB_SPACING_Y);
  784. if (IsReinforcable) {
  785. reinforcebtn.Turn_On();
  786. } else {
  787. reinforcebtn.Turn_Off();
  788. }
  789. reinforcebtn.Add(*commands);
  790. /*
  791. ** Create drop box of possible team missions. This is used when building/editing the
  792. ** team mission list.
  793. */
  794. char droptext[45];
  795. DropListClass missionlist1(BUTTON_MISSION1, droptext, sizeof(droptext),
  796. TPF_EFNT | TPF_NOSHADOW,
  797. reinforcebtn.X, reinforcebtn.Y+15, 170, 8*8,
  798. MFCD::Retrieve("EBTN-UP.SHP"),
  799. MFCD::Retrieve("EBTN-DN.SHP"));
  800. for (TeamMissionType tm = TMISSION_FIRST; tm < TMISSION_COUNT; tm++) {
  801. missionlist1.Add_Item(TeamTypeClass::Name_From_Mission(tm));
  802. }
  803. missionlist1.Set_Selected_Index(0);
  804. missionlist1.Add_Tail(*commands);
  805. /*
  806. ** Optional mission argument entry field.
  807. */
  808. char arg_buf[6] = {0};
  809. EditClass arg_edt(BUTTON_ARG, arg_buf, sizeof(arg_buf),
  810. TPF_EFNT | TPF_NOSHADOW,
  811. missionlist1.X + missionlist1.Width + 15, missionlist1.Y, 60, -1, EditClass::ALPHANUMERIC);
  812. // arg_edt.Add(*commands);
  813. char qtext[55];
  814. DropListClass qlist(BUTTON_QUARRY, qtext, sizeof(qtext),
  815. TPF_EFNT | TPF_NOSHADOW,
  816. missionlist1.X + missionlist1.Width + 15, missionlist1.Y, 100, 5*8,
  817. MFCD::Retrieve("EBTN-UP.SHP"),
  818. MFCD::Retrieve("EBTN-DN.SHP"));
  819. for (QuarryType q = QUARRY_FIRST; q < QUARRY_COUNT; q++) {
  820. qlist.Add_Item(QuarryName[q]);
  821. }
  822. qlist.Set_Selected_Index(0);
  823. qlist.Add_Tail(*commands);
  824. char ftext[55];
  825. DropListClass flist(BUTTON_FORMATION, ftext, sizeof(ftext),
  826. TPF_EFNT | TPF_NOSHADOW,
  827. missionlist1.X + missionlist1.Width + 15, missionlist1.Y, 100, 5*8,
  828. MFCD::Retrieve("EBTN-UP.SHP"),
  829. MFCD::Retrieve("EBTN-DN.SHP"));
  830. for (FormationType f = FORMATION_FIRST; f < FORMATION_COUNT; f++) {
  831. flist.Add_Item(FormationName[f]);
  832. }
  833. flist.Set_Selected_Index(0);
  834. flist.Add_Tail(*commands);
  835. char mtext[55];
  836. DropListClass mlist(BUTTON_MISSION, mtext, sizeof(mtext),
  837. TPF_EFNT | TPF_NOSHADOW,
  838. missionlist1.X + missionlist1.Width + 15, missionlist1.Y, 100, 5*8,
  839. MFCD::Retrieve("EBTN-UP.SHP"),
  840. MFCD::Retrieve("EBTN-DN.SHP"));
  841. for (MissionType m = MISSION_FIRST; m < MISSION_COUNT; m++) {
  842. mlist.Add_Item(MissionClass::Mission_Name(m));
  843. }
  844. mlist.Set_Selected_Index(0);
  845. mlist.Add_Tail(*commands);
  846. TListClass<TeamMissionClass *> missionlist2(BUTTON_MISSION2, missionlist1.X+60, missionlist1.Y+22, 240, 8*7,
  847. TPF_EFNT | TPF_NOSHADOW,
  848. MFCD::Retrieve("EBTN-UP.SHP"),
  849. MFCD::Retrieve("EBTN-DN.SHP"));
  850. for (index = 0; index < MissionCount; index++) {
  851. missionlist2.Add_Item(new TeamMissionClass(MissionList[index]));
  852. // missionlist2.Add_Item(&TeamMissions[MissionList[index].Mission]);
  853. }
  854. static int tabs[] = {13, 40}; // list box tab stops
  855. missionlist2.Set_Tabs(tabs);
  856. missionlist2.Add_Tail(*commands);
  857. /*
  858. ** Mission editing command buttons.
  859. */
  860. TextButtonClass addbtn(BUTTON_ADD, "Append", TPF_EBUTTON, D_NAME_X, missionlist1.Y+missionlist1.Height+1, 50);
  861. addbtn.Add(*commands);
  862. TextButtonClass insertbtn(BUTTON_INSERT, "Insert", TPF_EBUTTON, addbtn.X, addbtn.Y+10, 50);
  863. insertbtn.Add(*commands);
  864. TextButtonClass delbtn(BUTTON_DELETE, "Delete", TPF_EBUTTON, insertbtn.X, insertbtn.Y+10, 50);
  865. delbtn.Add(*commands);
  866. TextButtonClass repbtn(BUTTON_REPLACE, "Replace", TPF_EBUTTON, delbtn.X, delbtn.Y+10, 50);
  867. repbtn.Add(*commands);
  868. TextButtonClass okbtn(BUTTON_OK, TXT_OK, TPF_EBUTTON, D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
  869. TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_EBUTTON, D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
  870. /*
  871. ** Initialize
  872. */
  873. Set_Logic_Page(SeenBuff);
  874. /*
  875. ** Create the list
  876. */
  877. okbtn.Add(*commands);
  878. cancelbtn.Add_Tail(*commands);
  879. /*
  880. ** Main Processing Loop
  881. */
  882. int lastindex = -1;
  883. int lastcount = -1;
  884. int lastbutton = -1;
  885. bool cancel = false;
  886. bool display = true;
  887. bool process = true;
  888. while (process) {
  889. /*
  890. ** Invoke game callback
  891. */
  892. Call_Back();
  893. /*
  894. ** Refresh display if needed
  895. */
  896. if (display) {
  897. /*
  898. ** Add the optional data entry field as necessary.
  899. */
  900. arg_edt.Remove();
  901. qlist.Remove();
  902. flist.Remove();
  903. mlist.Remove();
  904. switch (TeamMission_Needs(TeamMissionType(missionlist1.Current_Index()))) {
  905. default:
  906. break;
  907. case NEED_MISSION:
  908. mlist.Add(*commands);
  909. break;
  910. case NEED_FORMATION:
  911. flist.Add(*commands);
  912. break;
  913. case NEED_WAYPOINT:
  914. case NEED_NUMBER:
  915. case NEED_HEX_NUMBER:
  916. arg_edt.Add(*commands);
  917. break;
  918. case NEED_QUARRY:
  919. qlist.Add(*commands);
  920. break;
  921. }
  922. /*
  923. ** Display the dialog box
  924. */
  925. Hide_Mouse();
  926. Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
  927. Draw_Caption(TXT_TEAM_EDIT, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
  928. /*
  929. ** Draw the captions
  930. */
  931. Fancy_Text_Print("Name:", name_edt.X, name_edt.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  932. Fancy_Text_Print("House:", housebtn.X, housebtn.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  933. Fancy_Text_Print("Pri:", recr_edt.X, recr_edt.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  934. Fancy_Text_Print("Max:", maxnum_edt.X, maxnum_edt.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  935. Fancy_Text_Print("Num:", initnum_edt.X, initnum_edt.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  936. Fancy_Text_Print("Loc:", originbtn.X, originbtn.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  937. Fancy_Text_Print("# Team Mission", missionlist2.X, missionlist2.Y-7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  938. Fancy_Text_Print("Trigger:", triggerbtn.X-4, triggerbtn.Y+1, scheme, TBLACK, TPF_RIGHT | TPF_EFNT | TPF_NOSHADOW);
  939. Fancy_Text_Print(Member_Description(), membersbtn.X + membersbtn.Width + 3, membersbtn.Y+1, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  940. Fancy_Text_Print("Use safest, possibly longer, route to target?", roundbtn.X+CB_SPACING_X, roundbtn.Y, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  941. Fancy_Text_Print("Charge toward target ignoring distractions?", suicidebtn.X+CB_SPACING_X, suicidebtn.Y, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  942. Fancy_Text_Print("Only 'Autocreate A.I.' uses this team type?", autocreatebtn.X+CB_SPACING_X, autocreatebtn.Y, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  943. Fancy_Text_Print("Prebuild team members before team is created?", prebuildbtn.X+CB_SPACING_X, prebuildbtn.Y, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  944. Fancy_Text_Print("Automatically reinforce team whenever possible?", reinforcebtn.X+CB_SPACING_X, reinforcebtn.Y, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW);
  945. /*
  946. ** Redraw the buttons
  947. */
  948. commands->Draw_All();
  949. Show_Mouse();
  950. display = false;
  951. }
  952. /*
  953. ** Get user input
  954. */
  955. KeyNumType input = commands->Input();
  956. /*
  957. ** Process input
  958. */
  959. switch (input) {
  960. /*
  961. ** Select a Mission on the right-hand mission list; update the Argument
  962. ** field to reflect the current value. This only serves as an aide to editing
  963. ** the team mission list.
  964. */
  965. case BUTTON_MISSION2 | KN_BUTTON:
  966. if (missionlist2.Count() && lastcount == missionlist2.Count() && lastbutton == BUTTON_MISSION2 && lastindex == missionlist2.Current_Index()) {
  967. missionlist1.Set_Selected_Index(missionlist2.Current_Item()->Mission);
  968. switch (TeamMission_Needs(missionlist2.Current_Item()->Mission)) {
  969. case NEED_MISSION:
  970. mlist.Set_Selected_Index(missionlist2.Current_Item()->Data.Mission);
  971. break;
  972. case NEED_FORMATION:
  973. flist.Set_Selected_Index(missionlist2.Current_Item()->Data.Formation);
  974. break;
  975. case NEED_NUMBER:
  976. sprintf(arg_edt.Get_Text(), "%d", missionlist2.Current_Item()->Data.Value);
  977. break;
  978. case NEED_HEX_NUMBER:
  979. sprintf(arg_edt.Get_Text(), "%x", missionlist2.Current_Item()->Data.Value);
  980. break;
  981. case NEED_QUARRY:
  982. strcpy(qlist.Get_Text(), QuarryName[missionlist2.Current_Item()->Data.Quarry]);
  983. break;
  984. case NEED_WAYPOINT:
  985. if (missionlist2.Current_Item()->Data.Value < 26) {
  986. sprintf(arg_edt.Get_Text(), "%c", missionlist2.Current_Item()->Data.Value + 'A');
  987. } else {
  988. sprintf(arg_edt.Get_Text(), "%c%c", (missionlist2.Current_Item()->Data.Value)/26 + 'A'-1, (missionlist2.Current_Item()->Data.Value % 26) + 'A');
  989. }
  990. break;
  991. }
  992. }
  993. lastindex = missionlist2.Current_Index();
  994. lastcount = missionlist2.Count();
  995. display = true;
  996. break;
  997. /*
  998. ** Add current mission data to current position of team mission list. Any
  999. ** subsequent missions get moved downward.
  1000. */
  1001. case BUTTON_INSERT | KN_BUTTON:
  1002. if (missionlist2.Count() < MAX_TEAM_MISSIONS) {
  1003. TeamMissionClass * tm = new TeamMissionClass;
  1004. tm->Mission = TeamMissionType(missionlist1.Current_Index());
  1005. tm->Data.Value = 0;
  1006. switch (TeamMission_Needs(tm->Mission)) {
  1007. case NEED_MISSION:
  1008. tm->Data.Mission = MissionType(mlist.Current_Index());
  1009. break;
  1010. case NEED_FORMATION:
  1011. tm->Data.Formation = FormationType(flist.Current_Index());
  1012. break;
  1013. case NEED_QUARRY:
  1014. tm->Data.Quarry = QuarryType(qlist.Current_Index());
  1015. break;
  1016. case NEED_NUMBER:
  1017. tm->Data.Value = atoi(arg_edt.Get_Text());
  1018. break;
  1019. case NEED_HEX_NUMBER:
  1020. tm->Data.Value = atoh(arg_edt.Get_Text());
  1021. break;
  1022. case NEED_WAYPOINT:
  1023. tm->Data.Value = toupper(*arg_edt.Get_Text()) - 'A';
  1024. if ( *((arg_edt.Get_Text())+1)) {
  1025. tm->Data.Value = (tm->Data.Value+1)*26;
  1026. tm->Data.Value += toupper(*((arg_edt.Get_Text())+1)) - 'A';;
  1027. }
  1028. if ((unsigned)tm->Data.Value >= WAYPT_HOME) {
  1029. tm->Data.Value = 0;
  1030. }
  1031. break;
  1032. default:
  1033. tm->Data.Value = 0;
  1034. break;
  1035. }
  1036. missionlist2.Insert_Item(tm);
  1037. }
  1038. display = true;
  1039. break;
  1040. /*
  1041. ** Add mission data to the end of the mission list.
  1042. */
  1043. case BUTTON_ADD | KN_BUTTON:
  1044. if (missionlist2.Count() < MAX_TEAM_MISSIONS) {
  1045. TeamMissionClass * tm = new TeamMissionClass;
  1046. tm->Mission = TeamMissionType(missionlist1.Current_Index());
  1047. tm->Data.Value = 0;
  1048. switch (TeamMission_Needs(tm->Mission)) {
  1049. case NEED_MISSION:
  1050. tm->Data.Mission = MissionType(mlist.Current_Index());
  1051. break;
  1052. case NEED_FORMATION:
  1053. tm->Data.Formation = FormationType(flist.Current_Index());
  1054. break;
  1055. case NEED_QUARRY:
  1056. tm->Data.Quarry = QuarryType(qlist.Current_Index());
  1057. break;
  1058. case NEED_NUMBER:
  1059. tm->Data.Value = atoi(arg_edt.Get_Text());
  1060. break;
  1061. case NEED_HEX_NUMBER:
  1062. tm->Data.Value = atoh(arg_edt.Get_Text());
  1063. break;
  1064. case NEED_WAYPOINT:
  1065. tm->Data.Value = toupper(*arg_edt.Get_Text()) - 'A';;
  1066. if ( *((arg_edt.Get_Text())+1)) {
  1067. tm->Data.Value = (tm->Data.Value+1)*26;
  1068. tm->Data.Value += toupper(*((arg_edt.Get_Text())+1)) - 'A';;
  1069. }
  1070. if ((unsigned)tm->Data.Value >= WAYPT_HOME) {
  1071. tm->Data.Value = 0;
  1072. }
  1073. break;
  1074. default:
  1075. tm->Data.Value = 0;
  1076. break;
  1077. }
  1078. missionlist2.Add_Item(tm);
  1079. display = true;
  1080. }
  1081. break;
  1082. /*
  1083. ** Replace the currently selected mission with the work mission data.
  1084. */
  1085. case BUTTON_REPLACE | KN_BUTTON:
  1086. if (missionlist2.Count()) {
  1087. TeamMissionClass * tm = missionlist2.Current_Item();
  1088. tm->Mission = TeamMissionType(missionlist1.Current_Index());
  1089. tm->Data.Value = 0;
  1090. switch (TeamMission_Needs(tm->Mission)) {
  1091. case NEED_MISSION:
  1092. tm->Data.Mission = MissionType(mlist.Current_Index());
  1093. break;
  1094. case NEED_FORMATION:
  1095. tm->Data.Formation = FormationType(flist.Current_Index());
  1096. break;
  1097. case NEED_QUARRY:
  1098. tm->Data.Quarry = QuarryType(qlist.Current_Index());
  1099. break;
  1100. case NEED_NUMBER:
  1101. tm->Data.Value = atoi(arg_edt.Get_Text());
  1102. break;
  1103. case NEED_HEX_NUMBER:
  1104. tm->Data.Value = atoh(arg_edt.Get_Text());
  1105. break;
  1106. case NEED_WAYPOINT:
  1107. tm->Data.Value = toupper(*arg_edt.Get_Text()) - 'A';
  1108. if ( *((arg_edt.Get_Text())+1)) {
  1109. tm->Data.Value = (tm->Data.Value+1)*26;
  1110. tm->Data.Value += toupper(*((arg_edt.Get_Text())+1)) - 'A';
  1111. }
  1112. if ((unsigned)tm->Data.Value >= WAYPT_HOME) {
  1113. tm->Data.Value = 0;
  1114. }
  1115. break;
  1116. default:
  1117. tm->Data.Value = 0;
  1118. break;
  1119. }
  1120. missionlist2[missionlist2.Current_Index()] = tm;
  1121. }
  1122. display = true;
  1123. break;
  1124. /*
  1125. ** Delete the currently selected mission.
  1126. */
  1127. case BUTTON_DELETE | KN_BUTTON:
  1128. if (missionlist2.Count()) {
  1129. TeamMissionClass * tm = missionlist2.Current_Item();
  1130. missionlist2.Remove_Index(missionlist2.Current_Index());
  1131. delete tm;
  1132. }
  1133. display = true;
  1134. break;
  1135. /*
  1136. ** Invoke the members dialog
  1137. */
  1138. case BUTTON_MEMBERS | KN_BUTTON:
  1139. /*
  1140. ** Take editor focus away
  1141. */
  1142. membersbtn.Turn_Off();
  1143. /*
  1144. ** Invoke the dialog
  1145. */
  1146. Map.Team_Members(HousesType(housebtn.Current_Index()));
  1147. /*
  1148. ** Redraw
  1149. */
  1150. display = true;
  1151. break;
  1152. /*
  1153. ** When the OK button is selected, lift the values from the dialog box
  1154. ** and place them into the team type object.
  1155. */
  1156. case BUTTON_OK | KN_BUTTON:
  1157. strtrim(name_edt.Get_Text());
  1158. if (strlen(name_edt.Get_Text()) != 0) {
  1159. strcpy(IniName, name_edt.Get_Text());
  1160. } else {
  1161. strcpy(IniName, "----");
  1162. }
  1163. IsRoundAbout = roundbtn.IsOn;
  1164. IsSuicide = suicidebtn.IsOn;
  1165. IsAutocreate = autocreatebtn.IsOn;
  1166. IsPrebuilt = prebuildbtn.IsOn;
  1167. IsReinforcable = reinforcebtn.IsOn;
  1168. RecruitPriority = atoi(recr_edt.Get_Text());
  1169. InitNum = atoi(initnum_edt.Get_Text());
  1170. MaxAllowed = atoi(maxnum_edt.Get_Text());
  1171. House = HousesType(housebtn.Current_Index());
  1172. Trigger = NULL;
  1173. if (triggerbtn.Current_Index() > 0) {
  1174. Trigger = TriggerTypes.Ptr(triggerbtn.Current_Index()-1);
  1175. }
  1176. MissionCount = missionlist2.Count();
  1177. for (index = 0; index < MissionCount; index++) {
  1178. MissionList[index].Data.Value = 0; // Clears extra bits.
  1179. MissionList[index] = *missionlist2[index];
  1180. }
  1181. #ifdef TOFIX
  1182. // the mission class objects pointed to in the list should be deleted?
  1183. #endif
  1184. if (strlen(originbtn.Get_Text())) {
  1185. if (strlen(originbtn.Get_Text()) == 1) {
  1186. Origin = toupper(*originbtn.Get_Text()) - 'A';
  1187. } else {
  1188. Origin = (toupper(*originbtn.Get_Text())+1 - 'A' ) * 26;
  1189. Origin += toupper(*(originbtn.Get_Text()+1)) - 'A';
  1190. }
  1191. } else {
  1192. Origin = -1;
  1193. }
  1194. cancel = false;
  1195. process = false;
  1196. break;
  1197. /*
  1198. ** Cancel: return
  1199. */
  1200. case BUTTON_CANCEL | KN_BUTTON:
  1201. cancel = true;
  1202. process = false;
  1203. break;
  1204. /*
  1205. ** Unrecognized events are ignored. If any button related event is
  1206. ** detected, then collapse any drop down list boxes. This keeps the
  1207. ** dialog box clean.
  1208. */
  1209. default:
  1210. if (input & KN_BUTTON) {
  1211. housebtn.Collapse();
  1212. missionlist1.Collapse();
  1213. triggerbtn.Collapse();
  1214. display = true;
  1215. }
  1216. break;
  1217. }
  1218. /*
  1219. ** Record the last dialog control touched so that a double click
  1220. ** can be detected.
  1221. */
  1222. if (input & KN_BUTTON) {
  1223. lastbutton = (input & ~KN_BUTTON);
  1224. }
  1225. }
  1226. return(!cancel);
  1227. }
  1228. int atoh(char * str)
  1229. {
  1230. int retval = 0;
  1231. while (*str) {
  1232. retval *= 16;
  1233. if (*str >= '0' && *str <= '9') {
  1234. retval += *str-'0';
  1235. } else {
  1236. if (*str >= 'a' && *str <= 'f') {
  1237. retval += 10 + (*str - 'a');
  1238. } else {
  1239. if (*str >= 'A' && *str <= 'F') {
  1240. retval += 10 + (*str - 'A');
  1241. }
  1242. }
  1243. }
  1244. str++;
  1245. }
  1246. return(retval);
  1247. }
  1248. #endif
  1249. #if defined(CHEAT_KEYS) || defined(SCENARIO_EDITOR)
  1250. /***********************************************************************************************
  1251. * TeamTypeClass::Member_Description -- Builds a member description string. *
  1252. * *
  1253. * This routine will build a team member description string. The string will be composed *
  1254. * of the team member type and quantity. As many team member types will be listed that *
  1255. * can fit within a reasonable size. *
  1256. * *
  1257. * INPUT: none *
  1258. * *
  1259. * OUTPUT: Returns with a pointer to the text string that contains a description of the team *
  1260. * type members. *
  1261. * *
  1262. * WARNINGS: The return string may be truncated if necessary to fit within reasonable size *
  1263. * limits. *
  1264. * *
  1265. * HISTORY: *
  1266. * 01/05/1996 JLB : Created. *
  1267. *=============================================================================================*/
  1268. char const * TeamTypeClass::Member_Description(void) const
  1269. {
  1270. static char buffer[128];
  1271. buffer[0] = '\0';
  1272. /*
  1273. ** Fill in class & count for all classes
  1274. */
  1275. for (int index = 0; index < ClassCount; index++) {
  1276. char txt[10];
  1277. strcat(buffer, Members[index].Class->IniName);
  1278. strcat(buffer, ":");
  1279. sprintf(txt, "%d", Members[index].Quantity);
  1280. strcat(buffer, txt);
  1281. if (index < ClassCount-1) {
  1282. strcat(buffer, ",");
  1283. }
  1284. }
  1285. if (strlen(buffer) > 25) {
  1286. strcpy(&buffer[25-3], "...");
  1287. }
  1288. return(buffer);
  1289. }
  1290. /***********************************************************************************************
  1291. * TeamTypeClass::Description -- Builds a description of the team. *
  1292. * *
  1293. * This routine will build a brief description of the team type. This description is used *
  1294. * in the team type list. *
  1295. * *
  1296. * INPUT: none *
  1297. * *
  1298. * OUTPUT: Returns with the composed text string that represents the team type. *
  1299. * *
  1300. * WARNINGS: none *
  1301. * *
  1302. * HISTORY: *
  1303. * 01/05/1996 JLB : Created. *
  1304. *=============================================================================================*/
  1305. char const * TeamTypeClass::Description(void) const
  1306. {
  1307. static char _buffer[128];
  1308. char extra = ' ';
  1309. char loc[3];
  1310. loc[0] = loc[1] = loc[2] = 0;
  1311. if (IsAutocreate) extra = '*';
  1312. if (Origin > -1) {
  1313. // if (Origin != -1) {
  1314. if (Origin < 26) {
  1315. loc[0] = 'A' + Origin;
  1316. } else {
  1317. loc[0] = Origin / 26 + 'A'-1;
  1318. loc[1] = Origin % 26 + 'A';
  1319. }
  1320. }
  1321. sprintf(_buffer, "%s\t%s\t%c%s\t%d\t%s", IniName, HouseTypeClass::As_Reference(House).Suffix, extra, loc, MissionCount, Member_Description());
  1322. return(_buffer);
  1323. }
  1324. /***********************************************************************************************
  1325. * TeamMissionClass::Description -- Compose a text description of team mission. *
  1326. * *
  1327. * This routine will create a text representation of a team mission. This description will *
  1328. * be used in the list of team missions for display purposes. *
  1329. * *
  1330. * INPUT: index -- The index to assign to this team. The index is used since some team *
  1331. * missions refer to the another team mission by index number. *
  1332. * *
  1333. * OUTPUT: Returns with a pointer to the team mission text. *
  1334. * *
  1335. * WARNINGS: none *
  1336. * *
  1337. * HISTORY: *
  1338. * 01/05/1996 JLB : Created. *
  1339. *=============================================================================================*/
  1340. char const * TeamMissionClass::Description(int index) const
  1341. {
  1342. static char buffer[64];
  1343. sprintf(buffer, "%d\t%s", index, TeamTypeClass::Name_From_Mission(Mission));
  1344. switch (TeamMission_Needs(Mission)) {
  1345. case NEED_MISSION:
  1346. strcat(buffer, MissionClass::Mission_Name(Data.Mission));
  1347. break;
  1348. case NEED_FORMATION:
  1349. strcat(buffer, FormationName[Data.Quarry]);
  1350. break;
  1351. case NEED_NUMBER:
  1352. sprintf(&buffer[strlen(buffer)], "%d", Data.Value);
  1353. break;
  1354. case NEED_HEX_NUMBER:
  1355. sprintf(&buffer[strlen(buffer)], "%x", Data.Value);
  1356. break;
  1357. case NEED_QUARRY:
  1358. strcat(buffer, QuarryName[Data.Quarry]);
  1359. break;
  1360. case NEED_WAYPOINT:
  1361. if (Data.Value < 26) {
  1362. sprintf(&buffer[strlen(buffer)], "%c", Data.Value + 'A');
  1363. } else {
  1364. sprintf(&buffer[strlen(buffer)], "%c%c", (Data.Value/26) + 'A'-1, (Data.Value % 26) + 'A');
  1365. }
  1366. break;
  1367. }
  1368. return(buffer);
  1369. }
  1370. #endif
  1371. /***********************************************************************************************
  1372. * TeamTypeClass::Detach -- Detach the specified target from this team type. *
  1373. * *
  1374. * This routine is called when some object is about to be removed from the game system and *
  1375. * all references to it must be severed. This will check to see if the specified object *
  1376. * is a trigger that this team refers to. If so, then the reference will be cleared. *
  1377. * *
  1378. * INPUT: target -- The target object to remove references to. *
  1379. * *
  1380. * OUTPUT: none *
  1381. * *
  1382. * WARNINGS: none *
  1383. * *
  1384. * HISTORY: *
  1385. * 07/30/1996 JLB : Created. *
  1386. *=============================================================================================*/
  1387. void TeamTypeClass::Detach(TARGET target, bool)
  1388. {
  1389. if (Is_Target_TriggerType(target) && Trigger.Is_Valid() && Trigger == As_TriggerType(target)) {
  1390. Trigger = NULL;
  1391. }
  1392. }
  1393. /***************************************************************************
  1394. * TeamTypeClass::Read_INI -- reads INI data *
  1395. * *
  1396. * INI entry format: *
  1397. * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, *
  1398. * RecruitPriority,MaxAllowed,InitNum,Fear, *
  1399. * ClassCount,Class:Num,Class:Num,..., *
  1400. * MissionCount,Mission:Arg,Mission:Arg,Mission:Arg,... *
  1401. * *
  1402. * INPUT: *
  1403. * buffer buffer to hold the INI data *
  1404. * *
  1405. * OUTPUT: *
  1406. * none. *
  1407. * *
  1408. * WARNINGS: *
  1409. * none. *
  1410. * *
  1411. * HISTORY: *
  1412. * 12/07/1994 BR : Created. *
  1413. * 02/01/1995 BR : No del team if no classes (editor needs empty teams!) *
  1414. *=========================================================================*/
  1415. void TeamTypeClass::Read_INI(CCINIClass & ini)
  1416. {
  1417. TeamTypeClass * team; // Working team pointer.
  1418. char buf[500]; // INI entry buffer
  1419. int len = ini.Entry_Count(INI_Name());
  1420. /*
  1421. ** Loop for all team entries, create and fill in.
  1422. */
  1423. for (int index = 0; index < len; index++) {
  1424. team = new TeamTypeClass();
  1425. if (team != NULL) {
  1426. char const * entry = ini.Get_Entry(INI_Name(), index);
  1427. ini.Get_String(INI_Name(), entry, NULL, buf, sizeof(buf));
  1428. team->Fill_In((char *)entry, buf);
  1429. }
  1430. }
  1431. }
  1432. /***********************************************************************************************
  1433. * TeamTypeClass::Fill_In -- fills in trigger from the given INI entry *
  1434. * *
  1435. * This routine fills in the given teamtype with the given name, and values from *
  1436. * the given INI entry. *
  1437. * *
  1438. * (This routine is used by the scenario editor, to import teams from the MASTER.INI file.) *
  1439. * *
  1440. * INI entry format: *
  1441. * TeamName = Housename,Roundabout,Learning,Suicide,Spy,Mercenary, *
  1442. * RecruitPriority,MaxAllowed,InitNum,Fear, *
  1443. * ClassCount,Class:Num,Class:Num,..., *
  1444. * MissionCount,Mission:Arg,Mission:Arg,Mission:Arg,... *
  1445. * *
  1446. * INPUT: *
  1447. * name mnemonic for the desired trigger *
  1448. * entry INI entry to parse *
  1449. * *
  1450. * OUTPUT: *
  1451. * none. *
  1452. * *
  1453. * WARNINGS: *
  1454. * none. *
  1455. * *
  1456. * HISTORY: *
  1457. * 11/28/1994 BR : Created. *
  1458. * 11/29/1995 JLB : Revamped to use new team class. *
  1459. *=============================================================================================*/
  1460. void TeamTypeClass::Fill_In(char * name, char * entry)
  1461. {
  1462. assert(TeamTypes.ID(this) == ID);
  1463. /*
  1464. ** Set its name
  1465. */
  1466. Set_Name(name);
  1467. House = HousesType(atoi(strtok(entry, ",")));
  1468. int code;
  1469. switch (NewINIFormat) {
  1470. default:
  1471. code = atoi(strtok(NULL, ","));
  1472. IsRoundAbout = ((code & 0x0001) != 0);
  1473. IsSuicide = ((code & 0x0002) != 0);
  1474. IsAutocreate = ((code & 0x0004) != 0);
  1475. IsPrebuilt = ((code & 0x0008) != 0);
  1476. IsReinforcable = ((code & 0x0010) != 0);
  1477. break;
  1478. case 0:
  1479. case 1:
  1480. IsRoundAbout = atoi(strtok(NULL, ","));
  1481. IsSuicide = atoi(strtok(NULL, ","));
  1482. IsAutocreate = atoi(strtok(NULL, ","));
  1483. IsPrebuilt = atoi(strtok(NULL, ","));
  1484. IsReinforcable = atoi(strtok(NULL, ","));
  1485. break;
  1486. }
  1487. RecruitPriority = atoi(strtok(NULL, ","));
  1488. InitNum = atoi(strtok(NULL, ","));
  1489. MaxAllowed = atoi(strtok(NULL, ","));
  1490. Origin = atoi(strtok(NULL, ","));
  1491. switch (NewINIFormat) {
  1492. default:
  1493. Trigger.Set_Raw(atoi(strtok(NULL, ",")));
  1494. break;
  1495. case 0:
  1496. case 1:
  1497. // Throw this token away -- it isn't used.
  1498. strtok(NULL, ",");
  1499. break;
  1500. }
  1501. /*
  1502. ** Fetch the team member types and quantity values.
  1503. */
  1504. ClassCount = atoi(strtok(NULL, ","));
  1505. for (int index = 0; index < ClassCount; index++) {
  1506. char * p1 = strtok(NULL, ",:");
  1507. char * p2 = strtok(NULL, ",:");
  1508. TechnoTypeClass const * otype = NULL;
  1509. /*
  1510. ** See if this is an infantry name
  1511. */
  1512. InfantryType i_id = InfantryTypeClass::From_Name(p1);
  1513. if (i_id != INFANTRY_NONE) {
  1514. otype = &InfantryTypeClass::As_Reference(i_id);
  1515. } else {
  1516. /*
  1517. ** See if this is a unit name
  1518. */
  1519. UnitType u_id = UnitTypeClass::From_Name(p1);
  1520. if (u_id != UNIT_NONE) {
  1521. otype = &UnitTypeClass::As_Reference(u_id);
  1522. } else {
  1523. /*
  1524. ** See if this is an aircraft name
  1525. */
  1526. AircraftType a_id = AircraftTypeClass::From_Name(p1);
  1527. if (a_id != AIRCRAFT_NONE) {
  1528. otype = &AircraftTypeClass::As_Reference(a_id);
  1529. } else {
  1530. /*
  1531. ** See if this is a vessel name.
  1532. */
  1533. VesselType v_id = VesselTypeClass::From_Name(p1);
  1534. if (v_id != VESSEL_NONE) {
  1535. otype = &VesselTypeClass::As_Reference(v_id);
  1536. }
  1537. }
  1538. }
  1539. }
  1540. /*
  1541. ** If the name was resolved, add this class
  1542. */
  1543. if (otype) {
  1544. if (index < MAX_TEAM_CLASSCOUNT) {
  1545. Members[index].Class = otype;
  1546. Members[index].Quantity = atoi(p2);
  1547. }
  1548. } else {
  1549. ClassCount--;
  1550. if (index == 0) break;
  1551. index--;
  1552. }
  1553. }
  1554. ClassCount = min(MAX_TEAM_CLASSCOUNT, ClassCount);
  1555. /*
  1556. ** Fetch the missions assigned to this team type.
  1557. */
  1558. MissionCount = atoi(strtok(NULL, ","));
  1559. for (int index = 0; index < MissionCount; index++) {
  1560. MissionList[index].Mission = TeamMissionType(atoi(strtok(NULL, ",:")));
  1561. MissionList[index].Data.Value = atoi(strtok(NULL, ",:"));
  1562. }
  1563. if (NewINIFormat < 2) {
  1564. /*
  1565. ** Fetch the trigger ID.
  1566. */
  1567. Trigger.Set_Raw(atoi(strtok(NULL, ",")));
  1568. }
  1569. }
  1570. /***********************************************************************************************
  1571. * TeamTypeClass::Write_INI -- Write out the team types to the INI database. *
  1572. * *
  1573. * This routine will take all team types and write them out to the INI database specified. *
  1574. * *
  1575. * INPUT: ini -- Reference to the INI database that will hold al the teams. *
  1576. * *
  1577. * OUTPUT: none *
  1578. * *
  1579. * WARNINGS: All preexisting team data in the database will be erased by this routine. *
  1580. * *
  1581. * HISTORY: *
  1582. * 07/30/1996 JLB : Created. *
  1583. *=============================================================================================*/
  1584. void TeamTypeClass::Write_INI(CCINIClass & ini)
  1585. {
  1586. ini.Clear("TeamTypes");
  1587. ini.Clear(INI_Name());
  1588. /*
  1589. ** Now write all the team data out
  1590. */
  1591. for (int index = 0; index < TeamTypes.Count(); index++) {
  1592. // for (int index = TeamTypes.Count()-1; index >= 0; index--) {
  1593. TeamTypeClass * team = TeamTypes.Ptr(index);
  1594. char buf[256];
  1595. buf[0] = 0;
  1596. team->Build_INI_Entry(buf);
  1597. ini.Put_String(INI_Name(), team->IniName, buf);
  1598. }
  1599. }
  1600. /***********************************************************************************************
  1601. * TeamTypeClass::Build_INI_Entry -- Builds the INI entry for this team type. *
  1602. * *
  1603. * This routine is used to build the text string that will go into the INI database for *
  1604. * a team of this type. This text string will be parsed back into a team object when the *
  1605. * scenario INI is read in. *
  1606. * *
  1607. * INPUT: buf -- Pointer to a buffer that will hold the team text entry. *
  1608. * *
  1609. * OUTPUT: none *
  1610. * *
  1611. * WARNINGS: Be sure that the buffer can hold the string build. A size of 80 or so is *
  1612. * usually sufficient. *
  1613. * *
  1614. * HISTORY: *
  1615. * 07/30/1996 JLB : Created. *
  1616. *=============================================================================================*/
  1617. void TeamTypeClass::Build_INI_Entry(char * buf)
  1618. {
  1619. int code = 0;
  1620. code |= IsRoundAbout ? 0x0001 : 0;
  1621. code |= IsSuicide ? 0x0002 : 0;
  1622. code |= IsAutocreate ? 0x0004 : 0;
  1623. code |= IsPrebuilt ? 0x0008 : 0;
  1624. code |= IsReinforcable ? 0x0010 : 0;
  1625. /*
  1626. ** Output the general data for this team type.
  1627. */
  1628. sprintf(buf, "%d,%d,%d,%d,%d,%d,%d",
  1629. House,
  1630. code,
  1631. RecruitPriority,
  1632. InitNum,
  1633. MaxAllowed,
  1634. Origin,
  1635. TriggerTypes.Logical_ID(Trigger)
  1636. );
  1637. buf += strlen(buf);
  1638. /*
  1639. ** For every class in the team, record the class's name & desired count
  1640. */
  1641. sprintf (buf, ",%d", ClassCount);
  1642. buf += strlen(buf);
  1643. for (int i = 0; i < ClassCount; i++) {
  1644. sprintf (buf, ",%s:%d", Members[i].Class->IniName, Members[i].Quantity);
  1645. buf += strlen(buf);
  1646. }
  1647. /*
  1648. ** Record the # of missions, and each mission name & argument value.
  1649. */
  1650. sprintf(buf, ",%d", MissionCount);
  1651. buf += strlen(buf);
  1652. for (int i = 0; i < MissionCount; i++) {
  1653. sprintf (buf, ",%d:%d", MissionList[i].Mission, MissionList[i].Data.Value);
  1654. buf += strlen(buf);
  1655. }
  1656. }