CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

MAPEDTM.CPP (28987B)


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