MAPEDTM.CPP 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  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/MAPEDTM.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 : MAPEDTM.CPP *
  22. * *
  23. * Programmer : Bill Randolph *
  24. * *
  25. * Start Date : December 7, 1994 *
  26. * *
  27. * Last Update : May 7, 1996 [JLB] *
  28. * *
  29. *-------------------------------------------------------------------------*
  30. * Functions: *
  31. * MapEditClass::Draw_Member -- Draws a member of the team dialog box. *
  32. * MapEditClass::Handle_Teams -- main team-dialog-handling function *
  33. * MapEditClass::Select_Team -- user selects a team from a list *
  34. * MapEditClass::Team_Members -- user picks makeup of a team *
  35. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  36. #include "function.h"
  37. #ifdef SCENARIO_EDITOR
  38. /***************************************************************************
  39. * MapEditClass::Handle_Teams -- main team-dialog-handling function *
  40. * *
  41. * INPUT: *
  42. * none. *
  43. * *
  44. * OUTPUT: *
  45. * none. *
  46. * *
  47. * WARNINGS: *
  48. * none. *
  49. * *
  50. * HISTORY: *
  51. * 12/08/1994 BR : Created. *
  52. *=========================================================================*/
  53. void MapEditClass::Handle_Teams(char const * caption)
  54. {
  55. int rc;
  56. /*
  57. ** Team dialog processing loop:
  58. ** - Invoke the team selection dialog. If a team's selected, break
  59. ** & return
  60. ** - If user wants to edit the current team, do so
  61. ** - If user wants to create new team, new a TeamTypeClass & edit it
  62. ** - If user wants to delete team, delete the current team
  63. ** - Keep looping until 'OK'
  64. */
  65. for (;;) {
  66. /*
  67. ** Select team
  68. */
  69. rc = Select_Team(caption);
  70. /*
  71. ** 'OK'; break
  72. */
  73. if (rc == 0) {
  74. break;
  75. } else {
  76. /*
  77. ** 'Edit'
  78. */
  79. if (rc == 1 && CurTeam) {
  80. if (CurTeam->Edit()) {
  81. Changed = 1;
  82. }
  83. HidPage.Clear();
  84. Flag_To_Redraw(true);
  85. Render();
  86. } else {
  87. /*
  88. ** 'New'
  89. */
  90. if (rc == 2) {
  91. /*
  92. ** Create a new team
  93. */
  94. CurTeam = new TeamTypeClass();
  95. if (CurTeam) {
  96. /*
  97. ** delete it if user cancels
  98. */
  99. if (!CurTeam->Edit()) {
  100. delete CurTeam;
  101. CurTeam = NULL;
  102. } else {
  103. Changed = 1;
  104. }
  105. HidPage.Clear();
  106. Flag_To_Redraw(true);
  107. Render();
  108. } else {
  109. /*
  110. ** Unable to create; issue warning
  111. */
  112. WWMessageBox().Process("No more teams available.");
  113. HidPage.Clear();
  114. Flag_To_Redraw(true);
  115. Render();
  116. }
  117. } else {
  118. /*
  119. ** 'Delete'
  120. */
  121. if (rc==3) {
  122. if (CurTeam) {
  123. Detach_This_From_All(CurTeam->As_Target(), true);
  124. delete CurTeam;
  125. //CurTeam->Remove();
  126. CurTeam = NULL;
  127. }
  128. }
  129. }
  130. }
  131. }
  132. }
  133. }
  134. /***************************************************************************
  135. * MapEditClass::Select_Team -- user selects a team from a list *
  136. * *
  137. * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ *
  138. * ³ Teams ³ *
  139. * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ *
  140. * ³ ³ Name House Class:Count,Class:Count ³³ ³ *
  141. * ³ ³ Name House Class:Count,Class:Count ÃÄ´ ³ *
  142. * ³ ³ Name House Class:Count,Class:Count ³ ³ ³ *
  143. * ³ ³ Name House Class:Count,Class:Count ³ ³ ³ *
  144. * ³ ³ ³ ³ ³ *
  145. * ³ ³ ³ ³ ³ *
  146. * ³ ³ ÃÄ´ ³ *
  147. * ³ ³ ³³ ³ *
  148. * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ *
  149. * ³ ³ *
  150. * ³ [Edit] [New] [Delete] [OK] ³ *
  151. * ³ ³ *
  152. * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ *
  153. * *
  154. * INPUT: *
  155. * none. *
  156. * *
  157. * OUTPUT: *
  158. * 0 = OK, 1 = Edit, 2 = New, 3 = Delete *
  159. * *
  160. * WARNINGS: *
  161. * Uses HIDBUFF. *
  162. * *
  163. * HISTORY: *
  164. * 12/08/1994 BR : Created. *
  165. * 05/07/1996 JLB : Streamlined and sorted team list. *
  166. *=========================================================================*/
  167. int MapEditClass::Select_Team(char const * )
  168. {
  169. /*
  170. ** Dialog & button dimensions
  171. */
  172. enum {
  173. D_DIALOG_W = 400, // dialog width
  174. D_DIALOG_H = 250, // dialog height
  175. D_DIALOG_X = 0, // centered x-coord
  176. D_DIALOG_Y = 0, // centered y-coord
  177. // D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center
  178. D_TXT8_H = 11, // ht of 8-pt text
  179. D_MARGIN = 25, // margin width/height
  180. D_LIST_W = (D_DIALOG_W-(D_MARGIN*2))-20,
  181. D_LIST_X = D_DIALOG_X + (D_DIALOG_W-D_LIST_W)/2,
  182. D_LIST_Y = D_DIALOG_Y + 20,
  183. D_LIST_H = (D_DIALOG_H-50)-D_LIST_Y,
  184. BUTTON_W = 45,
  185. BUTTON_H = 9,
  186. D_EDIT_W = BUTTON_W,
  187. D_EDIT_H = BUTTON_H,
  188. D_EDIT_X = D_DIALOG_X + D_DIALOG_W - (((D_EDIT_W+10)*4)+25),
  189. D_EDIT_Y = D_DIALOG_Y + D_DIALOG_H - 20 - D_EDIT_H,
  190. D_NEW_W = BUTTON_W,
  191. D_NEW_H = BUTTON_H,
  192. D_NEW_X = D_EDIT_X + D_EDIT_W + 10,
  193. D_NEW_Y = D_DIALOG_Y + D_DIALOG_H - 20 - D_NEW_H,
  194. D_DELETE_W = BUTTON_W,
  195. D_DELETE_H = BUTTON_H,
  196. D_DELETE_X = D_NEW_X + D_NEW_W + 10,
  197. D_DELETE_Y = D_DIALOG_Y + D_DIALOG_H - 20 - D_DELETE_H,
  198. D_OK_W = BUTTON_W,
  199. D_OK_H = BUTTON_H,
  200. D_OK_X = D_DELETE_X + D_DELETE_W + 10,
  201. D_OK_Y = D_DIALOG_Y + D_DIALOG_H - 20 - D_OK_H,
  202. TEAMTXT_LEN = 43, // max length of a team entry
  203. };
  204. /*
  205. ** Button enumerations:
  206. */
  207. enum {
  208. TEAM_LIST=100,
  209. BUTTON_EDIT,
  210. BUTTON_NEW,
  211. BUTTON_DELETE,
  212. BUTTON_OK,
  213. };
  214. /*
  215. ** Dialog variables
  216. */
  217. bool edit_team = false; // true = user wants to edit
  218. bool new_team = false; // true = user wants to new
  219. bool del_team = false; // true = user wants to new
  220. static int tabs[] = {35, 60, 80, 100}; // list box tab stops
  221. RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
  222. /*
  223. ** Buttons
  224. */
  225. GadgetClass * commands = NULL; // the button list
  226. TListClass<CCPtr<TeamTypeClass> > teamlist (TEAM_LIST,
  227. D_LIST_X, D_LIST_Y, D_LIST_W, D_LIST_H,
  228. TPF_EFNT | TPF_NOSHADOW,
  229. MFCD::Retrieve("EBTN-UP.SHP"),
  230. MFCD::Retrieve("EBTN-DN.SHP"));
  231. TextButtonClass editbtn (BUTTON_EDIT, "Edit", TPF_EBUTTON, D_EDIT_X, D_EDIT_Y, D_EDIT_W);
  232. TextButtonClass newbtn (BUTTON_NEW, "New", TPF_EBUTTON, D_NEW_X, D_NEW_Y, D_NEW_W);
  233. TextButtonClass deletebtn (BUTTON_DELETE, "Delete", TPF_EBUTTON, D_DELETE_X, D_DELETE_Y, D_DELETE_W);
  234. TextButtonClass okbtn (BUTTON_OK, "OK", TPF_EBUTTON, D_OK_X, D_OK_Y, D_OK_W);
  235. /*
  236. ** Initialize
  237. */
  238. Set_Logic_Page(SeenBuff);
  239. /*
  240. ** Fill in team names
  241. */
  242. for (int index = 0; index < TeamTypes.Count(); index++) {
  243. teamlist.Add_Item(TeamTypes.Ptr(index));
  244. }
  245. PNBubble_Sort(&teamlist[0], teamlist.Count());
  246. if (!CurTeam || !CurTeam->IsActive) CurTeam = NULL;
  247. if (CurTeam) {
  248. teamlist.Set_Selected_Index(CurTeam);
  249. CurTeam = teamlist.Current_Item();
  250. } else {
  251. teamlist.Set_Selected_Index(0);
  252. if (TeamTypes.Count()) {
  253. CurTeam = teamlist.Current_Item();
  254. }
  255. }
  256. /*
  257. ** Create the list
  258. */
  259. commands = &teamlist;
  260. editbtn.Add_Tail(*commands);
  261. newbtn.Add_Tail(*commands);
  262. deletebtn.Add_Tail(*commands);
  263. okbtn.Add_Tail(*commands);
  264. /*
  265. ** Init tab stops for list
  266. */
  267. teamlist.Set_Tabs(tabs);
  268. /*
  269. ** Main Processing Loop
  270. */
  271. bool display = true;
  272. bool process = true;
  273. while (process) {
  274. /*
  275. ** Invoke game callback
  276. */
  277. Call_Back();
  278. /*
  279. ** Refresh display if needed
  280. */
  281. if (display /*&& LogicPage->Lock()*/) {
  282. Hide_Mouse();
  283. Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
  284. Draw_Caption(TXT_TEAM_EDIT, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
  285. commands->Draw_All();
  286. Show_Mouse();
  287. display = false;
  288. // LogicPage->Unlock();
  289. }
  290. /*
  291. ** Get user input
  292. */
  293. KeyNumType input = commands->Input();
  294. /*
  295. ** Process input
  296. */
  297. switch (input) {
  298. case (TEAM_LIST | KN_BUTTON):
  299. CurTeam = teamlist.Current_Item();
  300. break;
  301. case (BUTTON_EDIT | KN_BUTTON):
  302. if (teamlist.Count()) {
  303. process = false;
  304. edit_team = true;
  305. }
  306. break;
  307. case (BUTTON_NEW | KN_BUTTON):
  308. process = false;
  309. new_team = true;
  310. break;
  311. case (BUTTON_DELETE | KN_BUTTON):
  312. process = false;
  313. del_team = true;
  314. break;
  315. case (KN_RETURN):
  316. case (BUTTON_OK | KN_BUTTON):
  317. process = false;
  318. break;
  319. }
  320. }
  321. /*
  322. ** Redraw the display
  323. */
  324. HidPage.Clear();
  325. Flag_To_Redraw(true);
  326. Render();
  327. if (edit_team) return(1);
  328. if (new_team) return(2);
  329. if (del_team) return(3);
  330. return(0);
  331. }
  332. /***************************************************************************
  333. * MapEditClass::Team_Members -- user picks makeup of a team *
  334. * *
  335. * Team members are rendered in a 24 x 24 area; the Window coordinates *
  336. * have to be set to this area when the object's 'Display()' routine is *
  337. * called. Thus, the dialog's window coords have to be divisible by *
  338. * 24. The height of the dialog is computed based on how many objects *
  339. * there are in it. *
  340. * *
  341. * 10 pixels are left between rows of objects, so the # of that type of *
  342. * object can be displayed underneath the object. *
  343. * *
  344. * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ *
  345. * ³ Team Members ³ *
  346. * ³ ³ *
  347. * ³ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ³ *
  348. * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ *
  349. * ³ ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ *
  350. * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ *
  351. * ³ ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ *
  352. * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ *
  353. * ³ ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ *
  354. * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ *
  355. * ³ ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ *
  356. * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ *
  357. * ³ ÃÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ *
  358. * ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ *
  359. * ³ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ ³ *
  360. * ³ [OK] [Cancel] ³ *
  361. * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ *
  362. * *
  363. * INPUT: *
  364. * house house to display objects for *
  365. * *
  366. * OUTPUT: *
  367. * 0 = OK, -1 = cancel *
  368. * *
  369. * WARNINGS: *
  370. * CurTeam must NOT be NULL when this function is called. *
  371. * This routine uses HIDBUFF for data storage. *
  372. * *
  373. * HISTORY: *
  374. * 12/07/1994 BR : Created. *
  375. *=========================================================================*/
  376. //#define TEENSY_WEENSY
  377. /*
  378. ** Dialog & button dimensions
  379. */
  380. enum {
  381. D_DIALOG_W = 640,
  382. D_DIALOG_X = 0,
  383. D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),
  384. D_TXT6_H = 7,
  385. D_MARGIN = 7,
  386. #ifdef TEENSY_WEENSY
  387. D_PICTURE_W = 32,
  388. D_PICTURE_H = 24,
  389. #else
  390. D_PICTURE_W = 64,
  391. D_PICTURE_H = 48,
  392. #endif
  393. D_ROW_H = (D_PICTURE_H + 3),
  394. D_OK_W = 50,
  395. D_OK_H = 9,
  396. D_OK_X = D_DIALOG_CX - 5 - D_OK_W,
  397. D_OK_Y = 0,
  398. D_CANCEL_W = 50,
  399. D_CANCEL_H = 9,
  400. D_CANCEL_X = D_DIALOG_CX + 5,
  401. D_CANCEL_Y = 0,
  402. };
  403. int MapEditClass::Team_Members(HousesType house)
  404. {
  405. /*
  406. ** Button enumerations:
  407. */
  408. enum {
  409. BUTTON_OK = 100,
  410. BUTTON_CANCEL,
  411. };
  412. /*
  413. ** Redraw values: in order from "top" to "bottom" layer of the dialog
  414. ** (highest enum is the lowest layer). Each section of the map checks
  415. ** the requested redraw level to see if it's supposed to draw; if it's
  416. ** >= its level, it redraws.
  417. */
  418. typedef enum {
  419. REDRAW_NONE = 0,
  420. REDRAW_BUTTONS,
  421. REDRAW_BACKGROUND,
  422. REDRAW_ALL = REDRAW_BACKGROUND
  423. } RedrawType;
  424. RedrawType display; // requested redraw level
  425. bool process; // loop while true
  426. /*
  427. ** Dialog variables
  428. */
  429. KeyNumType input; // user input
  430. bool cancel = false; // true = user cancels
  431. RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
  432. /*
  433. ** Team display variables
  434. */
  435. const TechnoTypeClass **teamclass; // array of team classes
  436. int *teamcount; // array of class counts
  437. int numcols; // # units displayed horizontally
  438. int numrows; // # units displayed vertically
  439. /*
  440. ** Dialog dimensions.
  441. */
  442. int dlg_y;
  443. int dlg_h; // dialog height
  444. int msg_y; // y-coord for object names
  445. int curclass = -1; // current index into 'teamclass'; can be invalid!
  446. // (is based on current mouse position)
  447. int numclasses; // current # classes in the team (limited to <=5)
  448. int maxclasses; // max # classes available
  449. int i,j;
  450. /*
  451. ** Values for timing when mouse held down.
  452. */
  453. int lheld = 0;
  454. int rheld = 0;
  455. long tdelay[3] = {5, 20, 0};
  456. int tindex = 0;
  457. long heldtime;
  458. /*
  459. ** Buttons.
  460. */
  461. ControlClass * commands;
  462. TextButtonClass okbtn (BUTTON_OK, TXT_OK, TPF_CENTER | TPF_EFNT | TPF_NOSHADOW, D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
  463. TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, TPF_CENTER | TPF_EFNT | TPF_NOSHADOW, D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
  464. /*
  465. ** Set up the team data arrays (ObjectTypeClass pointers & count)
  466. */
  467. #ifdef WIN32
  468. teamclass = (const TechnoTypeClass **)SysMemPage.Get_Buffer();
  469. teamcount = (int *)SysMemPage.Get_Buffer() + MAX_TEAM_CLASSES * sizeof (ObjectTypeClass *);
  470. #else
  471. teamclass = (const TechnoTypeClass **)HidPage.Get_Buffer();
  472. teamcount = (int *)HidPage.Get_Buffer() + MAX_TEAM_CLASSES * sizeof (ObjectTypeClass *);
  473. #endif
  474. /*
  475. ** Fill in the ObjectTypeClass array with all available object type ptrs,
  476. ** checking to be sure this house can own the object
  477. */
  478. i = 0;
  479. for (InfantryType i_id = INFANTRY_FIRST; i_id < INFANTRY_COUNT; i_id++) {
  480. teamclass[i] = &InfantryTypeClass::As_Reference(i_id);
  481. i++;
  482. }
  483. for (AircraftType a_id = AIRCRAFT_FIRST; a_id < AIRCRAFT_COUNT; a_id++) {
  484. teamclass[i] = &AircraftTypeClass::As_Reference(a_id);
  485. i++;
  486. }
  487. for (UnitType u_id = UNIT_FIRST; u_id < UNIT_COUNT; u_id++) {
  488. teamclass[i] = &UnitTypeClass::As_Reference(u_id);
  489. i++;
  490. }
  491. for (VesselType v_id = VESSEL_FIRST; v_id < VESSEL_COUNT; v_id++) {
  492. teamclass[i] = &VesselTypeClass::As_Reference(v_id);
  493. i++;
  494. }
  495. /*
  496. ** Save max # classes.
  497. */
  498. maxclasses = i;
  499. /*
  500. ** Fill in the 'count' array with data from the current team:
  501. ** - For every class in the current team, find that class type in the
  502. ** 'teamclass' array & set its count value
  503. */
  504. for (j = 0; j < maxclasses; j++) {
  505. teamcount[j] = 0;
  506. }
  507. /*
  508. ** Loop through all classes in the team.
  509. */
  510. for (i = 0; i < CurTeam->ClassCount; i++) {
  511. /*
  512. ** Find this class in our array.
  513. */
  514. for (j = 0; j < maxclasses; j++) {
  515. /*
  516. ** Set the count; detect a match between the team's class & the
  517. ** 'teamclass' array entry by comparing the actual pointers; typeid
  518. ** won't work because E1 & E2 are the same type class.
  519. */
  520. if (CurTeam->Members[i].Class == teamclass[j]) {
  521. teamcount[j] = CurTeam->Members[i].Quantity;
  522. break;
  523. }
  524. }
  525. }
  526. numclasses = CurTeam->ClassCount;
  527. /*
  528. ** Set up the dialog dimensions based on number of classes we have to draw
  529. **
  530. ** Compute picture rows & cols.
  531. */
  532. numcols = (D_DIALOG_W - 16) / D_PICTURE_W;
  533. numrows = (maxclasses + numcols - 1) / numcols;
  534. /*
  535. ** Dialog's height = top margin + label + picture rows + margin + label + margin + btn
  536. */
  537. dlg_h = 400;
  538. dlg_y = 0;
  539. msg_y = dlg_y+dlg_h - 26 - 15;
  540. okbtn.Y = dlg_y + dlg_h - D_MARGIN - D_OK_H - 15;
  541. cancelbtn.Y = dlg_y + dlg_h - D_MARGIN - D_CANCEL_H - 15;
  542. /*
  543. ** Draw to SeenPage.
  544. */
  545. Set_Logic_Page(SeenBuff);
  546. /*
  547. ** Make sure 'house' is valid.
  548. */
  549. // if (house!=HOUSE_GOOD && house!=HOUSE_BAD && house != HOUSE_MULTI1 &&
  550. // house != HOUSE_MULTI2 && house != HOUSE_MULTI3 && house != HOUSE_MULTI4 ) {
  551. // if (Scen.ScenPlayer == SCEN_PLAYER_MPLAYER) {
  552. // house = HOUSE_MULTI1;
  553. // } else {
  554. // house = HOUSE_GOOD;
  555. // }
  556. // }
  557. /*
  558. ** Create the list.
  559. */
  560. commands = &okbtn;
  561. cancelbtn.Add_Tail(*commands);
  562. /*
  563. ** Main Processing Loop.
  564. */
  565. display = REDRAW_ALL;
  566. process = true;
  567. while (process) {
  568. /*
  569. ** Invoke game callback.
  570. */
  571. Call_Back();
  572. /*
  573. ** Refresh display if needed.
  574. */
  575. if (display) {
  576. /*
  577. ** Display the dialog box.
  578. */
  579. Hide_Mouse();
  580. if (display >= REDRAW_BACKGROUND) {
  581. /*
  582. ** Display the constant background of this dialog.
  583. */
  584. Dialog_Box(D_DIALOG_X, dlg_y, D_DIALOG_W, dlg_h);
  585. Draw_Caption(TXT_TEAM_MEMBERS, D_DIALOG_X, dlg_y, D_DIALOG_W);
  586. /*
  587. ** Draw the objects.
  588. */
  589. for (i = 0; i < maxclasses; i++) {
  590. /*
  591. ** Display the object along with any count value for it.
  592. */
  593. Draw_Member(teamclass[i], i, teamcount[i], house);
  594. }
  595. if ((unsigned)curclass < maxclasses) {
  596. Fancy_Text_Print(teamclass[curclass]->Full_Name(),
  597. D_DIALOG_X + D_DIALOG_W / 2, msg_y,
  598. &ColorRemaps[PCOLOR_BROWN], TBLACK,
  599. TPF_CENTER|TPF_EFNT|TPF_NOSHADOW);
  600. }
  601. }
  602. /*
  603. ** Redraw the buttons.
  604. */
  605. if (display >= REDRAW_BUTTONS) {
  606. commands->Draw_All();
  607. }
  608. Show_Mouse();
  609. display = REDRAW_NONE;
  610. }
  611. /*
  612. ** Get user input.
  613. */
  614. input = commands->Input();
  615. /*
  616. ** Process input.
  617. */
  618. switch (input) {
  619. /*
  620. ** Mouse buttons set or clear 'held' values
  621. */
  622. case (KN_LMOUSE):
  623. if (curclass >= 0 && curclass < maxclasses) {
  624. lheld = 1;
  625. tindex = 2;
  626. heldtime = 0;
  627. }
  628. break;
  629. case (KN_RMOUSE):
  630. if (curclass >= 0 && curclass < maxclasses) {
  631. rheld = 1;
  632. tindex = 2;
  633. heldtime = 0;
  634. }
  635. break;
  636. case ((int)KN_LMOUSE | (int)KN_RLSE_BIT):
  637. lheld = 0;
  638. break;
  639. case ((int)KN_RMOUSE | (int)KN_RLSE_BIT):
  640. rheld = 0;
  641. break;
  642. /*
  643. ** OK: save values & return.
  644. */
  645. case (BUTTON_OK | KN_BUTTON):
  646. process = false;
  647. break;
  648. /*
  649. ** Cancel: abort & return.
  650. */
  651. case (BUTTON_CANCEL | KN_BUTTON):
  652. cancel = true;
  653. process = false;
  654. break;
  655. default:
  656. /*
  657. ** Compute new 'curclass' based on mouse position.
  658. */
  659. i = (Get_Mouse_X() - 32 - D_DIALOG_X) / D_PICTURE_W +
  660. ((Get_Mouse_Y() - (dlg_y+8+11)) / D_ROW_H) * numcols;
  661. /*
  662. ** If it's changed, update class label.
  663. */
  664. if (i != curclass) {
  665. curclass = i;
  666. /*
  667. ** Clear out the previously printed name of the item.
  668. */
  669. Hide_Mouse();
  670. LogicPage->Fill_Rect(D_DIALOG_X + 32, msg_y, D_DIALOG_X + D_DIALOG_W - 64, msg_y + D_TXT6_H, BLACK);
  671. if ((unsigned)curclass < maxclasses) {
  672. Fancy_Text_Print(teamclass[curclass]->Full_Name(),
  673. D_DIALOG_X + D_DIALOG_W / 2, msg_y, scheme, TBLACK, TPF_CENTER|TPF_EFNT|TPF_NOSHADOW);
  674. }
  675. /*
  676. ** Force buttons to not be held.
  677. */
  678. lheld = 0;
  679. rheld = 0;
  680. Show_Mouse();
  681. }
  682. break;
  683. }
  684. /*
  685. ** Check for a 'held' mouse button; if it's down, and the correct
  686. ** amount of time has gone by, increment/decrement the count for the
  687. ** current class.
  688. */
  689. if (lheld) {
  690. /*
  691. ** The first time in, TickCount - heldtime will be larger than
  692. ** tdelay[2], so we increment the count immediately; then, we decrement
  693. ** tindex to go to the next time delay, which is longer; then, decr.
  694. ** again to go to the 1st time delay which is the shortest.
  695. */
  696. if (TickCount - heldtime > tdelay[tindex]) {
  697. heldtime = TickCount;
  698. if (tindex) {
  699. tindex--;
  700. }
  701. /*
  702. ** Detect addition of a new class.
  703. */
  704. if (teamcount[curclass]==0) {
  705. /*
  706. ** Don't allow more classes than we can handle.
  707. */
  708. if (numclasses == TeamTypeClass::MAX_TEAM_CLASSCOUNT) {
  709. continue;
  710. }
  711. numclasses++;
  712. }
  713. teamcount[curclass]++;
  714. /*
  715. ** Update number label.
  716. */
  717. Draw_Member(teamclass[curclass], curclass, teamcount[curclass], house);
  718. }
  719. } else {
  720. if (rheld) {
  721. /*
  722. ** The first time in, TickCount - heldtime will be larger than
  723. ** tdelay[2], so we increment the count immediately; then, we decrement
  724. ** tindex to go to the next time delay, which is longer; then, decr.
  725. ** again to go to the 1st time delay which is the shortest.
  726. */
  727. if (TickCount - heldtime > tdelay[tindex]) {
  728. if (tindex) {
  729. tindex--;
  730. }
  731. heldtime = TickCount;
  732. if (teamcount[curclass] > 0) {
  733. teamcount[curclass]--;
  734. /*
  735. ** Detect removal of a class.
  736. */
  737. if (teamcount[curclass] == 0) {
  738. numclasses--;
  739. }
  740. }
  741. /*
  742. ** Update number label.
  743. */
  744. Draw_Member(teamclass[curclass], curclass, teamcount[curclass], house);
  745. }
  746. }
  747. }
  748. }
  749. /*
  750. ** Copy data into team.
  751. */
  752. if (!cancel) {
  753. CurTeam->ClassCount = numclasses;
  754. i = 0; // current team class index
  755. for (j = 0; j < maxclasses; j++) {
  756. if (teamcount[j] > 0) {
  757. CurTeam->Members[i].Quantity = teamcount[j];
  758. CurTeam->Members[i].Class = teamclass[j];
  759. i++;
  760. }
  761. }
  762. }
  763. /*
  764. ** Redraw the display.
  765. */
  766. HidPage.Clear();
  767. Flag_To_Redraw(true);
  768. Render();
  769. if (cancel) return(-1);
  770. return(0);
  771. }
  772. /***********************************************************************************************
  773. * MapEditClass::Draw_Member -- Draws a member of the team dialog box. *
  774. * *
  775. * This routine will display the cameo image of the potential team member. In the corner, *
  776. * it will show the current quantity of this member for the current team being edited. *
  777. * *
  778. * INPUT: ptr -- Pointer to the member object type. *
  779. * *
  780. * index -- The index into the team dialog box array of selectable objects. This is *
  781. * used to determine the correct X and Y offsets to draw. *
  782. * *
  783. * quant -- The quantity number to display in the corner of the image. *
  784. * *
  785. * house -- The owner of this object. *
  786. * *
  787. * OUTPUT: none *
  788. * *
  789. * WARNINGS: none *
  790. * *
  791. * HISTORY: *
  792. * 07/02/1995 JLB : Created. *
  793. *=============================================================================================*/
  794. void MapEditClass::Draw_Member(TechnoTypeClass const * ptr, int index, int quant, HousesType house)
  795. {
  796. int numcols = (D_DIALOG_W - 64) / D_PICTURE_W;
  797. int col = index % numcols;
  798. int row = index / numcols;
  799. int dlg_y = 0;
  800. int x = D_DIALOG_X + 32 + col * D_PICTURE_W;
  801. int y = dlg_y + 8 + 13 + row * D_ROW_H;
  802. RemapControlType * scheme = GadgetClass::Get_Color_Scheme();
  803. /*
  804. ** Change the window to this box.
  805. */
  806. WindowList[WINDOW_EDITOR][WINDOWX] = x;
  807. WindowList[WINDOW_EDITOR][WINDOWY] = y;
  808. WindowList[WINDOW_EDITOR][WINDOWWIDTH] = D_PICTURE_W;
  809. WindowList[WINDOW_EDITOR][WINDOWHEIGHT] = D_PICTURE_H;
  810. Change_Window((int)WINDOW_EDITOR);
  811. Hide_Mouse();
  812. Draw_Box(x, y, D_PICTURE_W, D_PICTURE_H, BOXSTYLE_DOWN, true);
  813. ptr->Display(WinW/2, WinH>>1, WINDOW_EDITOR, house);
  814. if (quant > 0) {
  815. Fancy_Text_Print("%d", x+1, y+1, scheme, TBLACK, TPF_8POINT|TPF_DROPSHADOW, quant);
  816. // Fancy_Text_Print("%d", x+1, y+D_PICTURE_H-8, scheme, TBLACK, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_DROPSHADOW, quant);
  817. }
  818. Show_Mouse();
  819. }
  820. #endif