MAPEDTM.CPP 28 KB

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