CnC_Remastered_Collection

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

MAPEDPLC.CPP (71130B)


      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:   F:\projects\c&c\vcs\code\mapedplc.cpv   2.16   16 Oct 1995 16:51:00   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 : MAPEDPLC.CPP                             *
     24  *                                                                         *
     25  *                   Programmer : Bill Randolph                            *
     26  *                                                                         *
     27  *                   Start Date : November 18, 1994                        *
     28  *                                                                         *
     29  *                  Last Update : July 4, 1995 [JLB]                       *
     30  *                                                                         *
     31  *-------------------------------------------------------------------------*
     32  * Object-placement routines                                               *
     33  *-------------------------------------------------------------------------*
     34  * Functions:                                                              *
     35  *   MapEditClass::Placement_Dialog -- adds an object to the scenario      *
     36  *   MapEditClass::Start_Placement -- enters placement mode                *
     37  *   MapEditClass::Place_Object -- attempts to place the current object    *
     38  *   MapEditClass::Cancel_Placement -- cancels placement mode              *
     39  *   MapEditClass::Place_Next -- while placing object, goes to next        *
     40  *   MapEditClass::Place_Prev -- while placing object, goes to previous    *
     41  *   MapEditClass::Place_Next_Category -- places next object category      *
     42  *   MapEditClass::Place_Prev_Category -- places previous object category  *
     43  *   MapEditClass::Place_Home -- homes the placement object                *
     44  *   MapEditClass::Toggle_House -- toggles current placement object's house*
     45  *   MapEditClass::Set_House_Buttons -- toggles house buttons for btn list *
     46  *   MapEditClass::Start_Trigger_Placement -- enters trigger placement mode*
     47  *   MapEditClass::Stop_Trigger_Placement -- exits trigger placement mode  *
     48  *   MapEditClass::Place_Trigger -- assigns trigger to object or cell      *
     49  *   MapEditClass::Start_Base_Building -- starts base-building mode        *
     50  *   MapEditClass::Cancel_Base_Building -- stops base-building mode        *
     51  *   MapEditClass::Build_Base_To -- builds the AI base to the given percent*
     52  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     53 
     54 #include	"function.h"
     55 
     56 #ifdef SCENARIO_EDITOR
     57 
     58 
     59 /***************************************************************************
     60  * MapEditClass::Placement_Dialog -- adds an object to the scenario        *
     61  *                                                                         *
     62  * This function sets LastChoice & LastHouse to the values chosen          *
     63  * by the user. It's up to the caller to call Start_Placement to enter     *
     64  * placement mode.                                                         *
     65  *   This routine does not modify PendingObject or PendingHouse.           *
     66  *                                                                         *
     67  *  ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿                   *
     68  *  ³   [GDI]  [NOD]  [Neutral]                        ³                   *
     69  *  ³                                                  ³                   *
     70  *  ³   ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿              ³                   *
     71  *  ³   ³                               ³ [Template]   ³                   *
     72  *  ³   ³                               ³ [Overlay ]   ³                   *
     73  *  ³   ³                               ³ [Smudge  ]   ³                   *
     74  *  ³   ³                               ³ [Terrain ]   ³                   *
     75  *  ³   ³      (Object picture)         ³ [Unit    ]   ³                   *
     76  *  ³   ³                               ³ [Infantry]   ³                   *
     77  *  ³   ³                               ³ [Aircraft]   ³                   *
     78  *  ³   ³                               ³ [Building]   ³                   *
     79  *  ³   ³                               ³              ³                   *
     80  *  ³   ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ     ÚÄÄÄÄÄÄ¿ ³                   *
     81  *  ³             [<-]  [->]                  ³(Grid)³ ³                   *
     82  *  ³                                         ³      ³ ³                   *
     83  *  ³         [OK]        [Cancel]            ÀÄÄÄÄÄÄÙ ³                   *
     84  *  ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ                   *
     85  *                                                                         *
     86  * INPUT:                                                                  *
     87  *      none.                                                              *
     88  *                                                                         *
     89  * OUTPUT:                                                                 *
     90  *      0 = OK, -1 = cancel                                                *
     91  *                                                                         *
     92  * WARNINGS:                                                               *
     93  *      none.                                                              *
     94  *                                                                         *
     95  * HISTORY:                                                                *
     96  *   10/21/1994 BR : Created.                                              *
     97  *=========================================================================*/
     98 int MapEditClass::Placement_Dialog(void)
     99 {
    100 	HousesType house;
    101 
    102 	/*........................................................................
    103 	Dialog & button dimensions
    104 	........................................................................*/
    105 	enum {
    106 		D_DIALOG_W = 480,
    107 		D_DIALOG_H = 360,
    108 		D_DIALOG_X = ((640 - D_DIALOG_W) / 2),
    109 		D_DIALOG_Y = ((400 - D_DIALOG_H) / 2),
    110 		D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2),
    111 
    112 		D_TXT8_H = 22,
    113 		D_MARGIN = 14,
    114 
    115 		D_PICTURE_W = 304,					// must be divisible by 8!
    116 		D_PICTURE_H = 210,
    117 		D_PICTURE_X = D_DIALOG_X + 16,		// must start on a byte boundary!
    118 		D_PICTURE_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN,
    119 		D_PICTURE_CX = D_PICTURE_X + D_PICTURE_W / 2,
    120 
    121 		D_GDI_W = 90,
    122 		D_GDI_H = 18,
    123 		D_GDI_X = D_DIALOG_X + D_MARGIN,
    124 		D_GDI_Y = D_DIALOG_Y + D_MARGIN,
    125 
    126 		D_NOD_W = 90,
    127 		D_NOD_H = 18,
    128 		D_NOD_X = D_GDI_X + D_GDI_W,
    129 		D_NOD_Y = D_DIALOG_Y + D_MARGIN,
    130 
    131 		D_NEUTRAL_W = 90,
    132 		D_NEUTRAL_H = 18,
    133 		D_NEUTRAL_X = D_NOD_X + D_NOD_W,
    134 		D_NEUTRAL_Y = D_DIALOG_Y + D_MARGIN,
    135 
    136 		D_MULTI1_W = 44,
    137 		D_MULTI1_H = 18,
    138 		D_MULTI1_X = D_GDI_X,
    139 		D_MULTI1_Y = D_GDI_Y,
    140 
    141 		D_MULTI2_W = 44,
    142 		D_MULTI2_H = 18,
    143 		D_MULTI2_X = D_MULTI1_X + D_MULTI1_W,
    144 		D_MULTI2_Y = D_GDI_Y,
    145 
    146 		D_MULTI3_W = 44,
    147 		D_MULTI3_H = 18,
    148 		D_MULTI3_X = D_MULTI2_X + D_MULTI2_W,
    149 		D_MULTI3_Y = D_GDI_Y,
    150 
    151 		D_MULTI4_W = 44,
    152 		D_MULTI4_H = 18,
    153 		D_MULTI4_X = D_MULTI3_X + D_MULTI3_W,
    154 		D_MULTI4_Y = D_GDI_Y,
    155 
    156 		D_LEFT_W = 90,
    157 		D_LEFT_H = 18,
    158 		D_LEFT_X = D_PICTURE_CX - 5 - D_LEFT_W,
    159 		D_LEFT_Y = D_PICTURE_Y + D_PICTURE_H + D_MARGIN,
    160 
    161 		D_RIGHT_W = 90,
    162 		D_RIGHT_H = 18,
    163 		D_RIGHT_X = D_PICTURE_CX + 5,
    164 		D_RIGHT_Y = D_PICTURE_Y + D_PICTURE_H + D_MARGIN,
    165 
    166 		D_TEMPLATE_W = 140,
    167 		D_TEMPLATE_H = 18,
    168 		D_TEMPLATE_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_TEMPLATE_W,
    169 		D_TEMPLATE_Y = D_PICTURE_Y,
    170 
    171 		D_OVERLAY_W = 140,
    172 		D_OVERLAY_H = 18,
    173 		D_OVERLAY_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_OVERLAY_W,
    174 		D_OVERLAY_Y = D_TEMPLATE_Y + D_TEMPLATE_H,
    175 
    176 		D_SMUDGE_W = 140,
    177 		D_SMUDGE_H = 18,
    178 		D_SMUDGE_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_SMUDGE_W,
    179 		D_SMUDGE_Y = D_OVERLAY_Y + D_OVERLAY_H,
    180 
    181 		D_TERRAIN_W = 140,
    182 		D_TERRAIN_H = 18,
    183 		D_TERRAIN_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_TERRAIN_W,
    184 		D_TERRAIN_Y = D_SMUDGE_Y + D_SMUDGE_H,
    185 
    186 		D_UNIT_W = 140,
    187 		D_UNIT_H = 18,
    188 		D_UNIT_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_UNIT_W,
    189 		D_UNIT_Y = D_TERRAIN_Y + D_TERRAIN_H,
    190 
    191 		D_INFANTRY_W = 140,
    192 		D_INFANTRY_H = 18,
    193 		D_INFANTRY_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_INFANTRY_W,
    194 		D_INFANTRY_Y = D_UNIT_Y + D_UNIT_H,
    195 
    196 		D_AIRCRAFT_W = 140,
    197 		D_AIRCRAFT_H = 18,
    198 		D_AIRCRAFT_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_AIRCRAFT_W,
    199 		D_AIRCRAFT_Y = D_INFANTRY_Y + D_INFANTRY_H,
    200 
    201 		D_BUILDING_W = 140,
    202 		D_BUILDING_H = 18,
    203 		D_BUILDING_X = D_DIALOG_X + D_DIALOG_W - D_MARGIN - D_BUILDING_W,
    204 		D_BUILDING_Y = D_AIRCRAFT_Y + D_AIRCRAFT_H,
    205 
    206 		D_OK_W = 90,
    207 		D_OK_H = 18,
    208 		D_OK_X = D_PICTURE_CX - D_OK_W - 5,
    209 		D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - D_MARGIN,
    210 
    211 		D_CANCEL_W = 90,
    212 		D_CANCEL_H = 18,
    213 		D_CANCEL_X = D_PICTURE_CX + 5,
    214 		D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - D_MARGIN,
    215 
    216 	};
    217 	/*........................................................................
    218 	Grid Dimensions
    219 	........................................................................*/
    220 	enum {
    221 		GRIDSIZE = 10,
    222 		GRIDBLOCK_W = 6,
    223 		GRIDBLOCK_H = 6,
    224 		D_GRID_X = D_DIALOG_X + D_DIALOG_W - (GRIDSIZE * GRIDBLOCK_W) - D_MARGIN,
    225 		D_GRID_Y = D_DIALOG_Y + D_DIALOG_H - (GRIDSIZE * GRIDBLOCK_H) - D_MARGIN,
    226 	};
    227 	/*........................................................................
    228 	Button enumerations:
    229 	........................................................................*/
    230 	enum {
    231 		BUTTON_GDI=100,
    232 		BUTTON_NOD,
    233 		BUTTON_NEUTRAL,
    234 		BUTTON_JP,			// placeholder
    235 		BUTTON_MULTI1,
    236 		BUTTON_MULTI2,
    237 		BUTTON_MULTI3,
    238 		BUTTON_MULTI4,
    239 		BUTTON_NEXT,
    240 		BUTTON_PREV,
    241 		BUTTON_OK,
    242 		BUTTON_CANCEL,
    243 		BUTTON_TEMPLATE,
    244 		BUTTON_OVERLAY,
    245 		BUTTON_SMUDGE,
    246 		BUTTON_TERRAIN,
    247 		BUTTON_UNIT,
    248 		BUTTON_INFANTRY,
    249 		BUTTON_AIRCRAFT,
    250 		BUTTON_BUILDING,
    251 	};
    252 	/*........................................................................
    253 	Redraw values: in order from "top" to "bottom" layer of the dialog
    254 	........................................................................*/
    255 	typedef enum {
    256 		REDRAW_NONE = 0,
    257 		REDRAW_BUTTONS,
    258 		REDRAW_OBJECT,
    259 		REDRAW_BACKGROUND,
    260 		REDRAW_ALL = REDRAW_BACKGROUND
    261 	} RedrawType;
    262 	/*........................................................................
    263 	Dialog variables
    264 	........................................................................*/
    265 	RedrawType display;									// display level
    266 	bool process;											// loop while true
    267 	bool cancel = false;							// true = user cancels
    268 	const ObjectTypeClass * curobj;			// Working object pointer.
    269 	int x,y;											// for drawing the grid
    270 	KeyNumType input;								// user input
    271 	short const *occupy;							// ptr into object's OccupyList
    272 	int cell;										// cell index for parsing OccupyList
    273 	int i;
    274 	int typeindex;									// index of class type
    275 	/*........................................................................
    276 	Buttons
    277 	........................................................................*/
    278 	ControlClass *commands;
    279 
    280 	TextButtonClass gdibtn (BUTTON_GDI, "GDI",
    281 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    282 		D_GDI_X, D_GDI_Y, D_GDI_W, D_GDI_H);
    283 
    284 	TextButtonClass nodbtn (BUTTON_NOD, "NOD",
    285 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    286 		D_NOD_X, D_NOD_Y, D_NOD_W, D_NOD_H);
    287 
    288 	TextButtonClass neutbtn (BUTTON_NEUTRAL, "Neutral",
    289 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    290 		D_NEUTRAL_X, D_NEUTRAL_Y, D_NEUTRAL_W, D_NEUTRAL_H);
    291 
    292 	TextButtonClass multi1btn (BUTTON_MULTI1, "M1",
    293 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    294 		D_MULTI1_X, D_MULTI1_Y, D_MULTI1_W, D_MULTI1_H);
    295 
    296 	TextButtonClass multi2btn (BUTTON_MULTI2, "M2",
    297 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    298 		D_MULTI2_X, D_MULTI2_Y, D_MULTI2_W, D_MULTI2_H);
    299 
    300 	TextButtonClass multi3btn (BUTTON_MULTI3, "M3",
    301 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    302 		D_MULTI3_X, D_MULTI3_Y, D_MULTI3_W, D_MULTI3_H);
    303 
    304 	TextButtonClass multi4btn (BUTTON_MULTI4, "M4",
    305 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    306 		D_MULTI4_X, D_MULTI4_Y, D_MULTI4_W, D_MULTI4_H);
    307 
    308 	TextButtonClass nextbtn (BUTTON_NEXT, TXT_RIGHT,
    309 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    310 		D_RIGHT_X, D_RIGHT_Y, D_RIGHT_W, D_RIGHT_H);
    311 
    312 	TextButtonClass prevbtn (BUTTON_PREV, TXT_LEFT,
    313 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    314 		D_LEFT_X, D_LEFT_Y, D_LEFT_W, D_LEFT_H);
    315 
    316 	TextButtonClass okbtn (BUTTON_OK, TXT_OK,
    317 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    318 		D_OK_X, D_OK_Y, D_OK_W, D_OK_H);
    319 
    320 	TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL,
    321 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    322 		D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H);
    323 
    324 	TextButtonClass templatebtn (BUTTON_TEMPLATE, "Template",
    325 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    326 		D_TEMPLATE_X, D_TEMPLATE_Y, D_TEMPLATE_W, D_TEMPLATE_H);
    327 
    328 	TextButtonClass overlaybtn (BUTTON_OVERLAY, "Overlay",
    329 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    330 		D_OVERLAY_X, D_OVERLAY_Y, D_OVERLAY_W, D_OVERLAY_H);
    331 
    332 	TextButtonClass smudgebtn (BUTTON_SMUDGE, "Smudge",
    333 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    334 		D_SMUDGE_X, D_SMUDGE_Y, D_SMUDGE_W, D_SMUDGE_H);
    335 
    336 	TextButtonClass terrainbtn (BUTTON_TERRAIN, "Terrain",
    337 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    338 		D_TERRAIN_X, D_TERRAIN_Y, D_TERRAIN_W, D_TERRAIN_H);
    339 
    340 	TextButtonClass unitbtn (BUTTON_UNIT, "Unit",
    341 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    342 		D_UNIT_X, D_UNIT_Y, D_UNIT_W, D_UNIT_H);
    343 
    344 	TextButtonClass infantrybtn (BUTTON_INFANTRY, "Infantry",
    345 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    346 		D_INFANTRY_X, D_INFANTRY_Y, D_INFANTRY_W, D_INFANTRY_H);
    347 
    348 	TextButtonClass aircraftbtn (BUTTON_AIRCRAFT, "Aircraft",
    349 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    350 		D_AIRCRAFT_X, D_AIRCRAFT_Y, D_AIRCRAFT_W, D_AIRCRAFT_H);
    351 
    352 	TextButtonClass buildingbtn (BUTTON_BUILDING, "Building",
    353 		TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW,
    354 		D_BUILDING_X, D_BUILDING_Y, D_BUILDING_W, D_BUILDING_H);
    355 
    356 	/*------------------------------------------------------------------------
    357 	Initialize addable objects list; we must do this every time in case one
    358 	of the object pools has become exhausted; that object won't be available
    359 	for adding.  (Skip aircraft, since they won't be used in the editor.)
    360 	------------------------------------------------------------------------*/
    361 	Clear_List();
    362 	TemplateTypeClass::Prep_For_Add();
    363 	OverlayTypeClass::Prep_For_Add();
    364 	SmudgeTypeClass::Prep_For_Add();
    365 	TerrainTypeClass::Prep_For_Add();
    366 	UnitTypeClass::Prep_For_Add();
    367 	InfantryTypeClass::Prep_For_Add();
    368 	BuildingTypeClass::Prep_For_Add();
    369 
    370 	/*........................................................................
    371 	Compute offset of each class type in the Objects array
    372 	........................................................................*/
    373 	TypeOffset[0] = 0;
    374 	for (i=1; i<NUM_EDIT_CLASSES; i++) {
    375 		TypeOffset[i] = TypeOffset[i-1] + NumType[i-1];
    376 	}
    377 
    378 	/*
    379 	--------------------- Return if no objects to place ----------------------
    380 	*/
    381 	if (!ObjCount)  {
    382 		return(-1);
    383 	}
    384 
    385 	/*
    386 	------------------------------- Initialize -------------------------------
    387 	*/
    388 	Set_Logic_Page(SeenBuff);
    389 	if (LastChoice >= ObjCount) {
    390 		LastChoice = 0;
    391 	}
    392 	curobj = Objects[LastChoice];		// current object to choose
    393 
    394 	commands = &neutbtn;
    395 	if (ScenPlayer == SCEN_PLAYER_MPLAYER) {
    396 		multi1btn.Add_Tail(*commands);
    397 		multi2btn.Add_Tail(*commands);
    398 		multi3btn.Add_Tail(*commands);
    399 		multi4btn.Add_Tail(*commands);
    400 	} else {
    401 		gdibtn.Add_Tail(*commands);
    402 		nodbtn.Add_Tail(*commands);
    403 	}
    404 	nextbtn.Add_Tail(*commands);
    405 	prevbtn.Add_Tail(*commands);
    406 	okbtn.Add_Tail(*commands);
    407 	cancelbtn.Add_Tail(*commands);
    408 	templatebtn.Add_Tail(*commands);
    409 	overlaybtn.Add_Tail(*commands);
    410 	smudgebtn.Add_Tail(*commands);
    411 	terrainbtn.Add_Tail(*commands);
    412 	unitbtn.Add_Tail(*commands);
    413 	infantrybtn.Add_Tail(*commands);
    414 	aircraftbtn.Add_Tail(*commands);
    415 	buildingbtn.Add_Tail(*commands);
    416 
    417 	/*........................................................................
    418 	If the current house isn't valid for the current object type, cycle to
    419 	the next house.
    420 	........................................................................*/
    421 	if (!Verify_House(LastHouse,curobj)) {
    422 		LastHouse = Cycle_House(LastHouse,curobj);
    423 	}
    424 
    425 	/*
    426 	..................... Set the buttons for this house .....................
    427 	*/
    428 	Set_House_Buttons(LastHouse, commands, BUTTON_GDI);
    429 
    430 	/*
    431 	-------------------------- Main processing loop --------------------------
    432 	*/
    433 	display = REDRAW_ALL;
    434 	process = true;
    435 	while (process) {
    436 
    437 		/*
    438 		** If we have just received input focus again after running in the background then
    439 		** we need to redraw.
    440 		*/
    441 		if (AllSurfaces.SurfacesRestored){
    442 			AllSurfaces.SurfacesRestored=FALSE;
    443 			display=REDRAW_ALL;
    444 		}
    445 
    446 		/*
    447 		........................ Invoke game callback .........................
    448 		*/
    449 		Call_Back();
    450 		/*
    451 		---------------------- Refresh display if needed ----------------------
    452 		*/
    453 		if (display > REDRAW_NONE) {
    454 			/*
    455 			---------------------- Display the dialog box ----------------------
    456 			*/
    457 			Hide_Mouse();
    458 			if (display >= REDRAW_BACKGROUND) {
    459 				Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H);
    460 				Draw_Caption(TXT_NONE, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W);
    461 			}
    462 
    463 			/*------------------------------------------------------------------
    464 			Display the current object:
    465 			- save the current window dimensions
    466 			- adjust the window size to the actual drawable area
    467 			- draw the shape
    468 			- reset the window dimensions
    469 			------------------------------------------------------------------*/
    470 			if (display >= REDRAW_OBJECT) {
    471 				WindowList[WINDOW_EDITOR][WINDOWX] = D_PICTURE_X >> 3;
    472 				WindowList[WINDOW_EDITOR][WINDOWY] = D_PICTURE_Y;
    473 				WindowList[WINDOW_EDITOR][WINDOWWIDTH] = D_PICTURE_W >> 3;
    474 				WindowList[WINDOW_EDITOR][WINDOWHEIGHT] = D_PICTURE_H;
    475 				Change_Window((int)WINDOW_EDITOR);
    476 				Draw_Box(D_PICTURE_X, D_PICTURE_Y, D_PICTURE_W, D_PICTURE_H,
    477 					BOXSTYLE_GREEN_DOWN, true);
    478 				curobj->Display(WinW<<2, WinH>>1, WINDOW_EDITOR, LastHouse);
    479 
    480 				/*
    481 				........................ Erase the grid .........................
    482 				*/
    483 				LogicPage->Fill_Rect(D_GRID_X - GRIDBLOCK_W * 2, D_GRID_Y,
    484 					D_GRID_X + GRIDSIZE * GRIDBLOCK_W,
    485 					D_GRID_Y + GRIDSIZE * GRIDBLOCK_H, BLACK);
    486 
    487 				/*
    488 				.............. Draw a box for every cell occupied ...............
    489 				*/
    490 				occupy = curobj->Occupy_List();
    491 				while ( (*occupy) != REFRESH_EOL) {
    492 					cell = (*occupy);
    493 					occupy++;
    494 					x = D_GRID_X + ((cell % MAP_CELL_W) * GRIDBLOCK_W);
    495 					y = D_GRID_Y + ((cell / MAP_CELL_W) * GRIDBLOCK_H);
    496 					LogicPage->Fill_Rect(x, y, x + GRIDBLOCK_W - 1, y + GRIDBLOCK_H - 1,
    497 						CC_BRIGHT_GREEN);
    498 				}
    499 
    500 				/*
    501 				..................... Draw the grid itself ......................
    502 				*/
    503 				for (y = 0; y <= GRIDSIZE; y++) {
    504 					for (x = 0; x <= GRIDSIZE; x++) {
    505 						LogicPage->Draw_Line(D_GRID_X + x * GRIDBLOCK_W, D_GRID_Y,
    506 							D_GRID_X + x * GRIDBLOCK_W,
    507 							D_GRID_Y + GRIDSIZE * GRIDBLOCK_H, CC_GREEN_SHADOW);
    508 					}
    509 					LogicPage->Draw_Line(D_GRID_X, D_GRID_Y + y * GRIDBLOCK_H,
    510 						D_GRID_X + GRIDSIZE * GRIDBLOCK_W, D_GRID_Y + y * GRIDBLOCK_H,
    511 						CC_GREEN_SHADOW);
    512 				}
    513 
    514 				/*...............................................................
    515 				Print the object's label from the class's Full_Name().
    516 				Warning: Text_String returns an EMS pointer, so standard string
    517 				functions won't work!
    518 				...............................................................*/
    519 				Fancy_Text_Print (curobj->Full_Name(),
    520 					D_PICTURE_CX, D_PICTURE_Y + D_MARGIN,
    521 					CC_GREEN, TBLACK,
    522 					TPF_CENTER | TPF_6PT_GRAD | TPF_USE_GRAD_PAL | TPF_NOSHADOW);
    523 			}
    524 
    525 			/*
    526 			-------------------------- Redraw buttons --------------------------
    527 			*/
    528 			if (display >= REDRAW_BUTTONS) {
    529 				/*...............................................................
    530 				Figure out which class category we're in & highlight that button
    531 				This updates 'typeindex', which is used below, and it also updates
    532 				the category button states.
    533 				...............................................................*/
    534 				i = 0;
    535 				for (typeindex = 0; typeindex < NUM_EDIT_CLASSES; typeindex++) {
    536 					i += NumType[typeindex];
    537 					if (LastChoice < i) break;
    538 				}
    539 				templatebtn.Turn_Off();
    540 				overlaybtn.Turn_Off();
    541 				smudgebtn.Turn_Off();
    542 				terrainbtn.Turn_Off();
    543 				unitbtn.Turn_Off();
    544 				infantrybtn.Turn_Off();
    545 				aircraftbtn.Turn_Off();
    546 				buildingbtn.Turn_Off();
    547 				switch (typeindex + BUTTON_TEMPLATE) {
    548 					case BUTTON_TEMPLATE:
    549 						templatebtn.Turn_On();
    550 						break;
    551 
    552 					case BUTTON_OVERLAY:
    553 						overlaybtn.Turn_On();
    554 						break;
    555 
    556 					case BUTTON_SMUDGE:
    557 						smudgebtn.Turn_On();
    558 						break;
    559 
    560 					case BUTTON_TERRAIN:
    561 						terrainbtn.Turn_On();
    562 						break;
    563 
    564 					case BUTTON_UNIT:
    565 						unitbtn.Turn_On();
    566 						break;
    567 
    568 					case BUTTON_INFANTRY:
    569 						infantrybtn.Turn_On();
    570 						break;
    571 
    572 					case BUTTON_AIRCRAFT:
    573 						aircraftbtn.Turn_On();
    574 						break;
    575 
    576 					case BUTTON_BUILDING:
    577 						buildingbtn.Turn_On();
    578 						break;
    579 				}
    580 			}
    581 
    582 			/*
    583 			.......................... Redraw buttons ..........................
    584 			*/
    585 			commands->Draw_All();
    586 			Show_Mouse();
    587 			display = REDRAW_NONE;
    588 
    589 		}
    590 
    591 		/*
    592 		........................... Get user input ............................
    593 		*/
    594 		input = commands->Input();
    595 
    596 		/*
    597 		------------------------- Process user input --------------------------
    598 		*/
    599 		switch (input) {
    600 			/*
    601 			---------------------------- GDI House -----------------------------
    602 			*/
    603 			case (BUTTON_GDI | KN_BUTTON):
    604 			case (BUTTON_NOD | KN_BUTTON):
    605 			case (BUTTON_NEUTRAL | KN_BUTTON):
    606 			case (BUTTON_MULTI1 | KN_BUTTON):
    607 			case (BUTTON_MULTI2 | KN_BUTTON):
    608 			case (BUTTON_MULTI3 | KN_BUTTON):
    609 			case (BUTTON_MULTI4 | KN_BUTTON):
    610 				house = (HousesType)( (input & (~KN_BUTTON)) - BUTTON_GDI);
    611 				/*
    612 				............... ignore if invalid for this object ...............
    613 				*/
    614 				if (!Verify_House(house,curobj)) {
    615 					Set_House_Buttons(LastHouse, commands, BUTTON_GDI);
    616 					break;
    617 				}
    618 
    619 				/*
    620 				...................... Set flags & buttons ......................
    621 				*/
    622 				LastHouse = house;
    623 				Set_House_Buttons(LastHouse, commands, BUTTON_GDI);
    624 				display = REDRAW_OBJECT;
    625 				break;
    626 
    627 			/*
    628 			--------------------------- Next in list ---------------------------
    629 			*/
    630 			case (KN_RIGHT):
    631 			case (BUTTON_NEXT | KN_BUTTON):
    632 				/*
    633 				..................... Increment to next obj .....................
    634 				*/
    635 				LastChoice++;
    636 				if (LastChoice == ObjCount) {
    637 					LastChoice = 0;
    638 				}
    639 				curobj = Objects[LastChoice];
    640 
    641 				/*
    642 				.................... Get valid house for obj ....................
    643 				*/
    644 				if (!Verify_House(LastHouse,curobj)) {
    645 					LastHouse = Cycle_House(LastHouse,curobj);
    646 					Set_House_Buttons(LastHouse, commands, BUTTON_GDI);
    647 				}
    648 
    649 				nextbtn.Turn_Off();
    650 				display = REDRAW_OBJECT;
    651 				break;
    652 
    653 			/*
    654 			------------------------- Previous in list -------------------------
    655 			*/
    656 			case (KN_LEFT):
    657 			case (BUTTON_PREV | KN_BUTTON):
    658 				/*
    659 				..................... Decrement to prev obj .....................
    660 				*/
    661 				LastChoice--;
    662 				if (LastChoice < 0) {
    663 					LastChoice = ObjCount-1;
    664 				}
    665 				curobj = Objects[LastChoice];
    666 
    667 				/*
    668 				.................... Get valid house for obj ....................
    669 				*/
    670 				if (!Verify_House(LastHouse,curobj)) {
    671 					LastHouse = Cycle_House(LastHouse,curobj);
    672 					Set_House_Buttons(LastHouse, commands, BUTTON_GDI);
    673 				}
    674 
    675 				prevbtn.Turn_Off();
    676 				display = REDRAW_OBJECT;
    677 				break;
    678 
    679 			/*
    680 			----------------------- Select a class type ------------------------
    681 			*/
    682 			case (BUTTON_TEMPLATE | KN_BUTTON):
    683 			case (BUTTON_OVERLAY | KN_BUTTON):
    684 			case (BUTTON_SMUDGE | KN_BUTTON):
    685 			case (BUTTON_TERRAIN | KN_BUTTON):
    686 			case (BUTTON_UNIT | KN_BUTTON):
    687 			case (BUTTON_INFANTRY | KN_BUTTON):
    688 			case (BUTTON_AIRCRAFT | KN_BUTTON):
    689 			case (BUTTON_BUILDING | KN_BUTTON):
    690 				/*
    691 				...................... Find index of class ......................
    692 				*/
    693 				typeindex = input - (BUTTON_TEMPLATE | KN_BUTTON);
    694 
    695 				/*
    696 				............ If no objects of that type, do nothing .............
    697 				*/
    698 				if (NumType[typeindex]==0) {
    699 					display = REDRAW_BUTTONS;			// force to reset button states
    700 					break;
    701 				}
    702 
    703 				/*
    704 				...................... Set current object .......................
    705 				*/
    706 				LastChoice = TypeOffset[typeindex];
    707 				curobj = Objects[LastChoice];
    708 
    709 				/*
    710 				.................... Get valid house for obj ....................
    711 				*/
    712 				if (!Verify_House(LastHouse,curobj)) {
    713 					LastHouse = Cycle_House(LastHouse,curobj);
    714 					Set_House_Buttons(LastHouse, commands, BUTTON_GDI);
    715 				}
    716 
    717 				display = REDRAW_OBJECT;
    718 				break;
    719 
    720 			/*
    721 			-------------------------- Next category ---------------------------
    722 			*/
    723 			case KN_PGDN:
    724 				typeindex++;
    725 				if (typeindex==NUM_EDIT_CLASSES) {
    726 					typeindex = 0;
    727 				}
    728 
    729 				/*
    730 				...................... Set current object .......................
    731 				*/
    732 				LastChoice = TypeOffset[typeindex];
    733 				curobj = Objects[LastChoice];
    734 
    735 				/*
    736 				.................... Get valid house for obj ....................
    737 				*/
    738 				if (!Verify_House(LastHouse,curobj)) {
    739 					LastHouse = Cycle_House(LastHouse,curobj);
    740 					Set_House_Buttons(LastHouse, commands, BUTTON_GDI);
    741 				}
    742 
    743 				display = REDRAW_OBJECT;
    744 				break;
    745 
    746 			/*
    747 			------------------------ Previous category -------------------------
    748 			*/
    749 			case KN_PGUP:
    750 				typeindex--;
    751 				if (typeindex < 0) {
    752 					typeindex = NUM_EDIT_CLASSES - 1;
    753 				}
    754 
    755 				/*
    756 				...................... Set current object .......................
    757 				*/
    758 				LastChoice = TypeOffset[typeindex];
    759 				curobj = Objects[LastChoice];
    760 
    761 				/*
    762 				.................... Get valid house for obj ....................
    763 				*/
    764 				if (!Verify_House(LastHouse,curobj)) {
    765 					LastHouse = Cycle_House(LastHouse,curobj);
    766 					Set_House_Buttons(LastHouse, commands, BUTTON_GDI);
    767 				}
    768 
    769 				display = REDRAW_OBJECT;
    770 				break;
    771 
    772 			/*
    773 			------------------------ Jump to 1st choice ------------------------
    774 			*/
    775 			case KN_HOME:
    776 				LastChoice = 0;
    777 				/*
    778 				...................... Set current object .......................
    779 				*/
    780 				curobj = Objects[LastChoice];
    781 				/*
    782 				.................... Get valid house for obj ....................
    783 				*/
    784 				if (!Verify_House(LastHouse,curobj)) {
    785 					LastHouse = Cycle_House(LastHouse,curobj);
    786 					Set_House_Buttons(LastHouse, commands, BUTTON_GDI);
    787 				}
    788 				display = REDRAW_OBJECT;
    789 				break;
    790 
    791 			/*
    792 			-------------------------------- OK --------------------------------
    793 			*/
    794 			case (KN_RETURN):
    795 			case (BUTTON_OK | KN_BUTTON):
    796 				cancel = false;
    797 				process = false;
    798 				break;
    799 
    800 			/*
    801 			------------------------------ Cancel ------------------------------
    802 			*/
    803 			case (KN_ESC):
    804 			case (BUTTON_CANCEL | KN_BUTTON):
    805 				cancel = true;
    806 				process = false;
    807 				break;
    808 
    809 			default:
    810 				break;
    811 		}
    812 
    813 	}
    814 
    815 	/*
    816 	--------------------------- Redraw the display ---------------------------
    817 	*/
    818 	HiddenPage.Clear();
    819 	Flag_To_Redraw(true);
    820 	Render();
    821 
    822 	if (cancel) {
    823 		return(-1);
    824 	}
    825 
    826 	return(0);
    827 }
    828 
    829 
    830 /***************************************************************************
    831  * MapEditClass::Start_Placement -- enters placement mode                  *
    832  *                                                                         *
    833  * INPUT:                                                                  *
    834  *      none.                                                              *
    835  *                                                                         *
    836  * OUTPUT:                                                                 *
    837  *      none.                                                              *
    838  *                                                                         *
    839  * WARNINGS:                                                               *
    840  *      none.                                                              *
    841  *                                                                         *
    842  * HISTORY:                                                                *
    843  *   11/04/1994 BR : Created.                                              *
    844  *=========================================================================*/
    845 void MapEditClass::Start_Placement(void)
    846 {
    847 	int i;
    848 
    849 	/*------------------------------------------------------------------------
    850 	Initialize addable objects list; we must do this every time in case one
    851 	of the object pools has become exhausted; that object won't be available
    852 	for adding.
    853 	------------------------------------------------------------------------*/
    854 	Clear_List();
    855 	TemplateTypeClass::Prep_For_Add();
    856 	OverlayTypeClass::Prep_For_Add();
    857 	SmudgeTypeClass::Prep_For_Add();
    858 	TerrainTypeClass::Prep_For_Add();
    859 	UnitTypeClass::Prep_For_Add();
    860 	InfantryTypeClass::Prep_For_Add();
    861 	//AircraftTypeClass::Prep_For_Add();
    862 	BuildingTypeClass::Prep_For_Add();
    863 	/*........................................................................
    864 	Compute offset of each class type in the Objects array
    865 	........................................................................*/
    866 	TypeOffset[0] = 0;
    867 	for (i=1; i<NUM_EDIT_CLASSES; i++) {
    868 		TypeOffset[i] = TypeOffset[i-1] + NumType[i-1];
    869 	}
    870 
    871 	/*
    872 	---------------------- Create the placement object -----------------------
    873 	*/
    874 	/*------------------------------------------------------------------------
    875 	Create the placement object:
    876 	- For normal placement mode, use the last-used index into Objects
    877 	  (LastChoice), and the last-used house (LastHouse).
    878 	- For base-building mode, force the object to be a building, and use the
    879 	  House specified in the Base object
    880 	------------------------------------------------------------------------*/
    881 	if (!BaseBuilding) {
    882 		if (LastChoice >= ObjCount)
    883 			LastChoice = ObjCount - 1;
    884 		PendingObject = Objects[LastChoice];
    885 		PendingHouse = LastHouse;
    886 		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(LastHouse));
    887 	} else {
    888 		if (LastChoice < TypeOffset[7])
    889 			LastChoice = TypeOffset[7];
    890 		if (LastChoice >= ObjCount)
    891 			LastChoice = ObjCount - 1;
    892 		PendingObject = Objects[LastChoice];
    893 		PendingHouse = LastHouse = Base.House;
    894 		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(LastHouse));
    895 	}
    896 
    897 
    898 	/*
    899 	------------------- Error if no more objects available -------------------
    900 	*/
    901 	if (!PendingObjectPtr) {
    902 		CCMessageBox().Process("No more objects of this type available.");
    903 		HiddenPage.Clear();
    904 		Flag_To_Redraw(true);
    905 		Render();
    906 		PendingObject = NULL;
    907 		if (BaseBuilding)
    908 			Cancel_Base_Building();
    909 		return;
    910 	}
    911 
    912 	/*
    913 	------------------------ Set the placement cursor ------------------------
    914 	*/
    915 	Set_Cursor_Pos();
    916 	Set_Cursor_Shape(PendingObject->Occupy_List());
    917 }
    918 
    919 
    920 /***************************************************************************
    921  * MapEditClass::Place_Object -- attempts to place the current object      *
    922  *                                                                         *
    923  * Placement of "real" objects is simply checked via their Unlimbo routine.*
    924  * Placement of templates is more complex:                                 *
    925  * - for every cell in the template's OccupyList, check for objects        *
    926  *     already in that cell by looking at the cell's OccupyList &          *
    927  *     OverlapList                                                         *
    928  * - "lift" all the objects in the cell by Mark'ing them                   *
    929  * - temporarily place the template in that cell                           *
    930  * - try to Unlimbo all the objects that were in the cell. If any          *
    931  *     objects fail to Unlimbo onto that template, the template cannot     *
    932  *     be placed here                                                      *
    933  *                                                                         *
    934  * It is assumed that the object being placed is a "new" object; the       *
    935  * object's strength & mission are not set during Unlimbo.                 *
    936  *                                                                         *
    937  * INPUT:                                                                  *
    938  *      none.                                                              *
    939  *                                                                         *
    940  * OUTPUT:                                                                 *
    941  *      0 = OK, -1 = unable to place                                       *
    942  *                                                                         *
    943  * WARNINGS:                                                               *
    944  *      none.                                                              *
    945  *                                                                         *
    946  * HISTORY:                                                                *
    947  *   11/04/1994 BR : Created.                                              *
    948  *=========================================================================*/
    949 int MapEditClass::Place_Object(void)
    950 {
    951 	CELL template_cell;						// cell being checked for template
    952 	COORDINATE obj_coord;							// coord of occupier object
    953 	int okflag;									// OK to place a template?
    954 	short const *occupy;						// ptr into template's OccupyList
    955 	ObjectClass *occupier;					// occupying object
    956 	TemplateType save_ttype;				// for saving cell's TType
    957 	unsigned char save_ticon;				// for saving cell's TIcon
    958 	BaseNodeClass node;						// for adding to an AI Base
    959 
    960 	/*------------------------------------------------------------------------
    961 	Placing a template:
    962 	- first lift up any objects in the cell
    963 	- place the template, and try to replace the objects; if they won't go
    964 	  back, the template can't go there
    965 	------------------------------------------------------------------------*/
    966 	//ScenarioInit++;
    967 	if (PendingObject->What_Am_I() == RTTI_TEMPLATETYPE) {
    968 
    969 		/*
    970 		.......... Loop through all cells this template will occupy ...........
    971 		*/
    972 		okflag = true;
    973 		occupy = PendingObject->Occupy_List();
    974 		while ((*occupy) != REFRESH_EOL) {
    975 
    976 			/*
    977 			................. Check this cell for an occupier ..................
    978 			*/
    979 			template_cell = (ZoneCell+ZoneOffset) + (*occupy);
    980 			if ((*this)[template_cell].Cell_Occupier()) {
    981 				occupier = (*this)[template_cell].Cell_Occupier();
    982 
    983 				/*
    984 				.................. Save object's coordinates ....................
    985 				*/
    986 				obj_coord = occupier->Coord;
    987 
    988 				/*
    989 				................... Place the object in limbo ...................
    990 				*/
    991 				occupier->Mark(MARK_UP);
    992 
    993 				/*
    994 				................ Set the cell's template values .................
    995 				*/
    996 				save_ttype = (*this)[template_cell].TType;
    997 				save_ticon = (*this)[template_cell].TIcon;
    998 				(*this)[template_cell].TType =
    999 					((TemplateTypeClass *)PendingObject)->Type;
   1000 				(*this)[template_cell].TIcon = Cell_X(*occupy) + Cell_Y(*occupy) *
   1001 					((TemplateTypeClass *)PendingObject)->Width;
   1002 				(*this)[template_cell].Recalc_Attributes();
   1003 				/*
   1004 				................ Try to put the object back down ................
   1005 				*/
   1006 				if (occupier->Can_Enter_Cell(Coord_Cell(obj_coord)) != MOVE_OK) {
   1007 					okflag = false;
   1008 				}
   1009 
   1010 				/*
   1011 				.............. Put everything back the way it was ...............
   1012 				*/
   1013 				(*this)[template_cell].TType = save_ttype;
   1014 				(*this)[template_cell].TIcon = save_ticon;
   1015 				(*this)[template_cell].Recalc_Attributes();
   1016 
   1017 				/*
   1018 				.......... Major error if can't replace the object now ..........
   1019 				*/
   1020 				occupier->Mark(MARK_DOWN);
   1021 			}
   1022 			occupy++;
   1023 		}
   1024 
   1025 		/*
   1026 		......... If it's still OK after ALL THAT, place the template .........
   1027 		*/
   1028 		if (okflag) {
   1029 			if (PendingObjectPtr->Unlimbo(Cell_Coord(ZoneCell + ZoneOffset))) {
   1030 				/*...............................................................
   1031 				Loop through all cells occupied by this template, and clear the
   1032 				smudge & overlay.
   1033 				...............................................................*/
   1034 				occupy = PendingObject->Occupy_List();
   1035 				while ((*occupy) != REFRESH_EOL) {
   1036 					/*
   1037 					............... Get cell for this occupy item ................
   1038 					*/
   1039 					template_cell = (ZoneCell+ZoneOffset) + (*occupy);
   1040 
   1041 					/*
   1042 					................... Clear smudge & overlay ...................
   1043 					*/
   1044 					(*this)[template_cell].Overlay = OVERLAY_NONE;
   1045 					(*this)[template_cell].OverlayData = 0;
   1046 					(*this)[template_cell].Smudge = SMUDGE_NONE;
   1047 
   1048 					/*
   1049 					............ make adjacent cells recalc attrib's .............
   1050 					*/
   1051 					(*this)[template_cell].Recalc_Attributes();
   1052 					(*this)[template_cell].Wall_Update();
   1053 					(*this)[template_cell].Concrete_Calc();
   1054 
   1055 					occupy++;
   1056 				}
   1057 
   1058 				/*
   1059 				......................... Set flags etc .........................
   1060 				*/
   1061 				PendingObjectPtr = 0;
   1062 				PendingObject = 0;
   1063 				PendingHouse = HOUSE_NONE;
   1064 				Set_Cursor_Shape(0);
   1065 				//ScenarioInit--;
   1066 				TotalValue = Overpass();
   1067 				Flag_To_Redraw(false);
   1068 				return(0);
   1069 			}
   1070 
   1071 			/*
   1072 			**	Failure to deploy results in a returned failure code.
   1073 			*/
   1074 			//ScenarioInit--;
   1075 			return(-1);
   1076 		}
   1077 
   1078 		/*
   1079 		........................ Not OK; return error .........................
   1080 		*/
   1081 		//ScenarioInit--;
   1082 		return(-1);
   1083 	}
   1084 
   1085 	/*------------------------------------------------------------------------
   1086 	Placing infantry: Infantry can go into cell sub-positions, so find the
   1087 	sub-position closest to the mouse & put him there
   1088 	------------------------------------------------------------------------*/
   1089 	if (PendingObject->What_Am_I() == RTTI_INFANTRYTYPE) {
   1090 		/*
   1091 		....................... Find cell sub-position ........................
   1092 		*/
   1093 		if (Is_Spot_Free(Pixel_To_Coord(Get_Mouse_X(),Get_Mouse_Y()))) {
   1094 			obj_coord = Closest_Free_Spot(Pixel_To_Coord(Get_Mouse_X(),
   1095 				Get_Mouse_Y()));
   1096 		} else {
   1097 			obj_coord = NULL;
   1098 		}
   1099 
   1100 		/*
   1101 		................ No free spots; don't place the object ................
   1102 		*/
   1103 		if (obj_coord == NULL) {
   1104 			//ScenarioInit--;
   1105 			return(-1);
   1106 		}
   1107 
   1108 		/*
   1109 		......................... Unlimbo the object ..........................
   1110 		*/
   1111 		if (PendingObjectPtr->Unlimbo(obj_coord)) {
   1112 			((InfantryClass *)PendingObjectPtr)->Set_Occupy_Bit(obj_coord);
   1113 //			Map[Coord_Cell(obj_coord)].Flag.Composite |=
   1114 //				(1 << CellClass::Spot_Index(obj_coord));
   1115 			PendingObjectPtr = 0;
   1116 			PendingObject = 0;
   1117 			PendingHouse = HOUSE_NONE;
   1118 			Set_Cursor_Shape(0);
   1119 			//ScenarioInit--;
   1120 			return(0);
   1121 		}
   1122 
   1123 		//ScenarioInit--;
   1124 		return(-1);
   1125 	}
   1126 
   1127 	/*------------------------------------------------------------------------
   1128 	Placing an object
   1129 	------------------------------------------------------------------------*/
   1130 	if (PendingObjectPtr->Unlimbo(Cell_Coord(ZoneCell + ZoneOffset))) {
   1131 
   1132 		/*
   1133 		** Update the Tiberium computation if we're placing an overlay
   1134 		*/
   1135 		if (PendingObject->What_Am_I() == RTTI_OVERLAYTYPE &&
   1136 			((OverlayTypeClass *)PendingObject)->IsTiberium) {
   1137 
   1138 			TotalValue = Overpass();
   1139 			Flag_To_Redraw(false);
   1140 		}
   1141 
   1142 		/*
   1143 		** If we're building a base, add this building to the base's Node list.
   1144 		*/
   1145 		if (BaseBuilding && PendingObject->What_Am_I() == RTTI_BUILDINGTYPE) {
   1146 			node.Type = ((BuildingTypeClass *)PendingObject)->Type;
   1147 			node.Coord = PendingObjectPtr->Coord;
   1148 			Base.Nodes.Add(node);
   1149 		}
   1150 
   1151 		PendingObjectPtr = 0;
   1152 		PendingObject = 0;
   1153 		PendingHouse = HOUSE_NONE;
   1154 		Set_Cursor_Shape(0);
   1155 		//ScenarioInit--;
   1156 		return(0);
   1157 	}
   1158 
   1159 	return(-1);
   1160 }
   1161 
   1162 
   1163 /***************************************************************************
   1164  * MapEditClass::Cancel_Placement -- cancels placement mode                *
   1165  *                                                                         *
   1166  * INPUT:                                                                  *
   1167  *      none.                                                              *
   1168  *                                                                         *
   1169  * OUTPUT:                                                                 *
   1170  *      none.                                                              *
   1171  *                                                                         *
   1172  * WARNINGS:                                                               *
   1173  *      none.                                                              *
   1174  *                                                                         *
   1175  * HISTORY:                                                                *
   1176  *   11/04/1994 BR : Created.                                              *
   1177  *=========================================================================*/
   1178 void MapEditClass::Cancel_Placement(void)
   1179 {
   1180 	/*
   1181 	---------------------- Delete the placement object -----------------------
   1182 	*/
   1183 	delete PendingObjectPtr;
   1184 	PendingObject = 0;
   1185 	PendingObjectPtr = 0;
   1186 	PendingHouse = HOUSE_NONE;
   1187 
   1188 	/*
   1189 	-------------------------- Restore cursor shape --------------------------
   1190 	*/
   1191 	Set_Cursor_Shape(0);
   1192 
   1193 	/*
   1194 	----------------- Redraw the map to erase old leftovers ------------------
   1195 	*/
   1196 	HiddenPage.Clear();
   1197 	Flag_To_Redraw(true);
   1198 	Render();
   1199 }
   1200 
   1201 
   1202 /***************************************************************************
   1203  * MapEditClass::Place_Next -- while placing object, goes to next          *
   1204  *                                                                         *
   1205  * - Deletes the current 'PendingObjectPtr'                                *
   1206  * - Increments LastChoice                                                 *
   1207  * - Tries to create a new 'PendingObjectPtr'; if fails, keeps             *
   1208  *   incrementing until it gets it                                         *
   1209  *                                                                         *
   1210  * INPUT:                                                                  *
   1211  *      none.                                                              *
   1212  *                                                                         *
   1213  * OUTPUT:                                                                 *
   1214  *      none.                                                              *
   1215  *                                                                         *
   1216  * WARNINGS:                                                               *
   1217  *      none.                                                              *
   1218  *                                                                         *
   1219  * HISTORY:                                                                *
   1220  *   11/03/1994 BR : Created.                                              *
   1221  *=========================================================================*/
   1222 void MapEditClass::Place_Next(void)
   1223 {
   1224 	delete PendingObjectPtr;
   1225 	PendingObjectPtr = NULL;
   1226 	PendingObject = NULL;
   1227 
   1228 	/*
   1229 	------------------ Loop until we create a valid object -------------------
   1230 	*/
   1231 	while (!PendingObjectPtr) {
   1232 		/*
   1233 		................. Go to next object in Objects list ...................
   1234 		*/
   1235 		LastChoice++;
   1236 		if (LastChoice == ObjCount) {
   1237 			/*
   1238 			** If we're in normal placement mode, wrap to the 1st object;
   1239 			** if we're in base-building mode, wrap to the 1st building
   1240 			*/
   1241 			if (!BaseBuilding) {
   1242 				LastChoice = 0;
   1243 			} else {
   1244 				LastChoice = TypeOffset[7];
   1245 			}
   1246 		}
   1247 
   1248 		/*
   1249 		................... Get house for this object type ....................
   1250 		*/
   1251 		if (!Verify_House(LastHouse,Objects[LastChoice])) {
   1252 			/*
   1253 			** If we're in normal placement mode, change the current
   1254 			** placement house to the one that can own this object.
   1255 			** If we're building a base, skip ahead to the next object if the
   1256 			** base's house can't own this one.
   1257 			*/
   1258 			if (!BaseBuilding) {
   1259 				LastHouse = Cycle_House(LastHouse,Objects[LastChoice]);
   1260 			} else {
   1261 				continue;
   1262 			}
   1263 		}
   1264 
   1265 		/*
   1266 		....................... Create placement object .......................
   1267 		*/
   1268 		PendingObject = Objects[LastChoice];
   1269 		PendingHouse = LastHouse;
   1270 		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
   1271 		if (!PendingObjectPtr) {
   1272 			PendingObject = NULL;
   1273 		}
   1274 	}
   1275 
   1276 	/*
   1277 	------------------------ Set the new cursor shape ------------------------
   1278 	*/
   1279 	Set_Cursor_Pos();
   1280 	Set_Cursor_Shape(0);
   1281 	Set_Cursor_Shape(PendingObject->Occupy_List());
   1282 
   1283 	/*
   1284 	----------------- Redraw the map to erase old leftovers ------------------
   1285 	*/
   1286 	HiddenPage.Clear();
   1287 	Flag_To_Redraw(true);
   1288 	Render();
   1289 }
   1290 
   1291 
   1292 /***************************************************************************
   1293  * MapEditClass::Place_Prev -- while placing object, goes to previous      *
   1294  *                                                                         *
   1295  * - Deletes the current 'PendingObjectPtr'                                *
   1296  * - Decrements LastChoice                                                 *
   1297  * - Tries to create a new 'PendingObjectPtr'; if fails, keeps             *
   1298  *   decrementing until it gets it                                         *
   1299  *                                                                         *
   1300  * INPUT:                                                                  *
   1301  *      none.                                                              *
   1302  *                                                                         *
   1303  * OUTPUT:                                                                 *
   1304  *      none.                                                              *
   1305  *                                                                         *
   1306  * WARNINGS:                                                               *
   1307  *      none.                                                              *
   1308  *                                                                         *
   1309  * HISTORY:                                                                *
   1310  *   11/03/1994 BR : Created.                                              *
   1311  *=========================================================================*/
   1312 void MapEditClass::Place_Prev(void)
   1313 {
   1314 	delete PendingObjectPtr;
   1315 	PendingObjectPtr = NULL;
   1316 	PendingObject = NULL;
   1317 
   1318 	/*
   1319 	------------------ Loop until we create a valid object -------------------
   1320 	*/
   1321 	while (!PendingObjectPtr) {
   1322 
   1323 		/*
   1324 		................. Go to prev object in Objects list ..................
   1325 		*/
   1326 		LastChoice--;
   1327 		/*
   1328 		** If we're in normal placement mode, wrap at the 1st object.
   1329 		** If we're building a base, wrap at the 1st building.
   1330 		*/
   1331 		if (!BaseBuilding) {
   1332 			if (LastChoice < 0)
   1333 				LastChoice = ObjCount - 1;
   1334 		} else {
   1335 			if (LastChoice < TypeOffset[7])
   1336 				LastChoice = ObjCount - 1;
   1337 		}
   1338 
   1339 		/*
   1340 		................... Get house for this object type ....................
   1341 		*/
   1342 		if (!Verify_House(LastHouse,Objects[LastChoice])) {
   1343 			/*
   1344 			** If we're in normal placement mode, change the current
   1345 			** placement house to the one that can own this object.
   1346 			** If we're building a base, skip ahead to the next object if the
   1347 			** base's house can't own this one.
   1348 			*/
   1349 			if (!BaseBuilding) {
   1350 				LastHouse = Cycle_House(LastHouse,Objects[LastChoice]);
   1351 			} else {
   1352 				continue;
   1353 			}
   1354 		}
   1355 
   1356 		/*
   1357 		....................... Create placement object .......................
   1358 		*/
   1359 		PendingObject = Objects[LastChoice];
   1360 		PendingHouse = LastHouse;
   1361 		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
   1362 		if (!PendingObjectPtr) {
   1363 			PendingObject = NULL;
   1364 		}
   1365 	}
   1366 
   1367 	/*
   1368 	------------------------ Set the new cursor shape ------------------------
   1369 	*/
   1370 	Set_Cursor_Pos();
   1371 	Set_Cursor_Shape(0);
   1372 	Set_Cursor_Shape(PendingObject->Occupy_List());
   1373 
   1374 	/*
   1375 	----------------- Redraw the map to erase old leftovers ------------------
   1376 	*/
   1377 	HiddenPage.Clear();
   1378 	Flag_To_Redraw(true);
   1379 	Render();
   1380 }
   1381 
   1382 
   1383 /***************************************************************************
   1384  * MapEditClass::Place_Next_Category -- places next category of object     *
   1385  *                                                                         *
   1386  * INPUT:                                                                  *
   1387  *      none.                                                              *
   1388  *                                                                         *
   1389  * OUTPUT:                                                                 *
   1390  *      none.                                                              *
   1391  *                                                                         *
   1392  * WARNINGS:                                                               *
   1393  *      none.                                                              *
   1394  *                                                                         *
   1395  * HISTORY:                                                                *
   1396  *   11/03/1994 BR : Created.                                              *
   1397  *=========================================================================*/
   1398 void MapEditClass::Place_Next_Category(void)
   1399 {
   1400 	int i;
   1401 
   1402 	/*
   1403 	** Don't allow this command if we're building a base; the only valid
   1404 	** category for base-building is buildings.
   1405 	*/
   1406 	if (BaseBuilding) {
   1407 		return;
   1408 	}
   1409 
   1410 	delete PendingObjectPtr;
   1411 	PendingObjectPtr = NULL;
   1412 	PendingObject = NULL;
   1413 
   1414 	/*
   1415 	------------------ Go to next category in Objects list -------------------
   1416 	*/
   1417 	i = LastChoice;
   1418 	while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) {
   1419 		i++;
   1420 		if (i == ObjCount) {
   1421 			i = 0;
   1422 		}
   1423 	}
   1424 	LastChoice = i;
   1425 
   1426 	/*
   1427 	------------------ Loop until we create a valid object -------------------
   1428 	*/
   1429 	while (!PendingObjectPtr) {
   1430 
   1431 		/*
   1432 		................... Get house for this object type ....................
   1433 		*/
   1434 		if (!Verify_House(LastHouse,Objects[LastChoice])) {
   1435 			LastHouse = Cycle_House(LastHouse,Objects[LastChoice]);
   1436 		}
   1437 
   1438 		/*
   1439 		....................... Create placement object .......................
   1440 		*/
   1441 		PendingObject = Objects[LastChoice];
   1442 		PendingHouse = LastHouse;
   1443 		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
   1444 
   1445 		/*
   1446 		.................. If this one failed, try the next ...................
   1447 		*/
   1448 		if (!PendingObjectPtr) {
   1449 			PendingObject = NULL;
   1450 			LastChoice++;
   1451 			if (LastChoice == ObjCount) {
   1452 				LastChoice = 0;
   1453 			}
   1454 		}
   1455 	}
   1456 
   1457 	/*
   1458 	------------------------ Set the new cursor shape ------------------------
   1459 	*/
   1460 	Set_Cursor_Pos();
   1461 	Set_Cursor_Shape(0);
   1462 	Set_Cursor_Shape(PendingObject->Occupy_List());
   1463 
   1464 	/*
   1465 	----------------- Redraw the map to erase old leftovers ------------------
   1466 	*/
   1467 	HiddenPage.Clear();
   1468 	Flag_To_Redraw(true);
   1469 	Render();
   1470 }
   1471 
   1472 
   1473 /***************************************************************************
   1474  * MapEditClass::Place_Prev_Category -- places previous category of object *
   1475  *                                                                         *
   1476  * INPUT:                                                                  *
   1477  *      none.                                                              *
   1478  *                                                                         *
   1479  * OUTPUT:                                                                 *
   1480  *      none.                                                              *
   1481  *                                                                         *
   1482  * WARNINGS:                                                               *
   1483  *      none.                                                              *
   1484  *                                                                         *
   1485  * HISTORY:                                                                *
   1486  *   11/03/1994 BR : Created.                                              *
   1487  *=========================================================================*/
   1488 void MapEditClass::Place_Prev_Category(void)
   1489 {
   1490 	int i;
   1491 
   1492 	/*
   1493 	** Don't allow this command if we're building a base; the only valid
   1494 	** category for base-building is buildings.
   1495 	*/
   1496 	if (BaseBuilding) {
   1497 		return;
   1498 	}
   1499 
   1500 	delete PendingObjectPtr;
   1501 	PendingObjectPtr = NULL;
   1502 	PendingObject = NULL;
   1503 
   1504 	/*
   1505 	------------------ Go to prev category in Objects list -------------------
   1506 	*/
   1507 	i = LastChoice;
   1508 	/*
   1509 	..................... Scan for the previous category .....................
   1510 	*/
   1511 	while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) {
   1512 		i--;
   1513 		if (i < 0) {
   1514 			i = ObjCount - 1;
   1515 		}
   1516 	}
   1517 	/*
   1518 	.................... Scan for start of this category .....................
   1519 	*/
   1520 	LastChoice = i;
   1521 	while (Objects[i]->What_Am_I() == Objects[LastChoice]->What_Am_I()) {
   1522 		LastChoice = i;
   1523 		i--;
   1524 		if (i < 0) {
   1525 			i = ObjCount - 1;
   1526 		}
   1527 	}
   1528 
   1529 	/*
   1530 	------------------ Loop until we create a valid object -------------------
   1531 	*/
   1532 	while (!PendingObjectPtr) {
   1533 		/*
   1534 		................... Get house for this object type ....................
   1535 		*/
   1536 		if (!Verify_House(LastHouse,Objects[LastChoice])) {
   1537 			LastHouse = Cycle_House(LastHouse,Objects[LastChoice]);
   1538 		}
   1539 
   1540 		/*
   1541 		....................... Create placement object .......................
   1542 		*/
   1543 		PendingObject = Objects[LastChoice];
   1544 		PendingHouse = LastHouse;
   1545 		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
   1546 
   1547 		/*
   1548 		.................. If this one failed, try the next ...................
   1549 		*/
   1550 		if (!PendingObjectPtr) {
   1551 			PendingObject = NULL;
   1552 			LastChoice--;
   1553 			if (LastChoice < 0) {
   1554 				LastChoice = ObjCount - 1;
   1555 			}
   1556 		}
   1557 	}
   1558 
   1559 	/*
   1560 	------------------------ Set the new cursor shape ------------------------
   1561 	*/
   1562 	Set_Cursor_Pos();
   1563 	Set_Cursor_Shape(0);
   1564 	Set_Cursor_Shape(PendingObject->Occupy_List());
   1565 
   1566 	/*
   1567 	----------------- Redraw the map to erase old leftovers ------------------
   1568 	*/
   1569 	HiddenPage.Clear();
   1570 	Flag_To_Redraw(true);
   1571 	Render();
   1572 }
   1573 
   1574 
   1575 /***************************************************************************
   1576  * MapEditClass::Place_Home -- homes the placement object                  *
   1577  *                                                                         *
   1578  * INPUT:                                                                  *
   1579  *      none.                                                              *
   1580  *                                                                         *
   1581  * OUTPUT:                                                                 *
   1582  *      none.                                                              *
   1583  *                                                                         *
   1584  * WARNINGS:                                                               *
   1585  *      none.                                                              *
   1586  *                                                                         *
   1587  * HISTORY:                                                                *
   1588  *   11/03/1994 BR : Created.                                              *
   1589  *=========================================================================*/
   1590 void MapEditClass::Place_Home(void)
   1591 {
   1592 	delete PendingObjectPtr;
   1593 	PendingObjectPtr = NULL;
   1594 	PendingObject = NULL;
   1595 
   1596 	/*
   1597 	** Don't allow this command if we're building a base; the only valid
   1598 	** category for base-building is buildings.
   1599 	*/
   1600 	if (BaseBuilding) {
   1601 		return;
   1602 	}
   1603 
   1604 	/*
   1605 	------------------ Loop until we create a valid object -------------------
   1606 	*/
   1607 	LastChoice = 0;
   1608 	while (!PendingObjectPtr) {
   1609 		/*
   1610 		................... Get house for this object type ....................
   1611 		*/
   1612 		if (!Verify_House(LastHouse,Objects[LastChoice])) {
   1613 			LastHouse = Cycle_House(LastHouse,Objects[LastChoice]);
   1614 		}
   1615 
   1616 		/*
   1617 		....................... Create placement object .......................
   1618 		*/
   1619 		PendingObject = Objects[LastChoice];
   1620 		PendingHouse = LastHouse;
   1621 		PendingObjectPtr = PendingObject->Create_One_Of(HouseClass::As_Pointer(PendingHouse));
   1622 
   1623 		/*
   1624 		.................. If this one failed, try the next ...................
   1625 		*/
   1626 		if (!PendingObjectPtr) {
   1627 			PendingObject = NULL;
   1628 			LastChoice++;
   1629 			if (LastChoice == ObjCount) {
   1630 				LastChoice = 0;
   1631 			}
   1632 		}
   1633 	}
   1634 
   1635 	/*
   1636 	------------------------ Set the new cursor shape ------------------------
   1637 	*/
   1638 	Set_Cursor_Pos();
   1639 	Set_Cursor_Shape(0);
   1640 	Set_Cursor_Shape(PendingObject->Occupy_List());
   1641 
   1642 	/*
   1643 	----------------- Redraw the map to erase old leftovers ------------------
   1644 	*/
   1645 	HiddenPage.Clear();
   1646 	Flag_To_Redraw(true);
   1647 	Render();
   1648 }
   1649 
   1650 
   1651 /***************************************************************************
   1652  * MapEditClass::Toggle_House -- toggles current placement object's house  *
   1653  *                                                                         *
   1654  * INPUT:                                                                  *
   1655  *                                                                         *
   1656  * OUTPUT:                                                                 *
   1657  *                                                                         *
   1658  * WARNINGS:                                                               *
   1659  *                                                                         *
   1660  * HISTORY:                                                                *
   1661  *   11/04/1994 BR : Created.                                              *
   1662  *=========================================================================*/
   1663 void MapEditClass::Toggle_House(void)
   1664 {
   1665 	TechnoClass *tp;
   1666 
   1667 	/*
   1668 	** Don't allow this command if we're building a base; the only valid
   1669 	** house for base-building is the one assigned to the base.
   1670 	*/
   1671 	if (BaseBuilding) {
   1672 		return;
   1673 	}
   1674 
   1675 	/*------------------------------------------------------------------------
   1676 	Only techno objects can be owned by a house; return if not a techno
   1677 	------------------------------------------------------------------------*/
   1678 	if (!PendingObjectPtr->Is_Techno()) {
   1679 		return;
   1680 	}
   1681 
   1682 	/*------------------------------------------------------------------------
   1683 	Select the house that will own this object
   1684 	------------------------------------------------------------------------*/
   1685 	LastHouse = Cycle_House(PendingObjectPtr->Owner(), PendingObject);
   1686 
   1687 	/*------------------------------------------------------------------------
   1688 	Change the house
   1689 	------------------------------------------------------------------------*/
   1690 	tp = (TechnoClass *)PendingObjectPtr;
   1691 	tp->House = HouseClass::As_Pointer(LastHouse);
   1692 
   1693 	/*------------------------------------------------------------------------
   1694 	Set house variables to new house
   1695 	------------------------------------------------------------------------*/
   1696 	PendingHouse = LastHouse;
   1697 }
   1698 
   1699 
   1700 /***************************************************************************
   1701  * MapEditClass::Set_House_Buttons -- toggles house buttons for btn list   *
   1702  *                                                                         *
   1703  * Looks in the given button list for the given GDI, NOD & Neutral button  *
   1704  * id's. Sets the On/Off state of the buttons based on the given house,    *
   1705  * only if that button is found in the list.                               *
   1706  *                                                                         *
   1707  * INPUT:                                                                  *
   1708  *      house            house to set buttons to                           *
   1709  *      btnlist         ptr to button list to search                       *
   1710  *      base_id         button ID for GDI; assumes other id's are sequential*
   1711  *                                                                         *
   1712  * OUTPUT:                                                                 *
   1713  *      none.                                                              *
   1714  *                                                                         *
   1715  * WARNINGS:                                                               *
   1716  *      none.                                                              *
   1717  *                                                                         *
   1718  * HISTORY:                                                                *
   1719  *   11/23/1994 BR : Created.                                              *
   1720  *=========================================================================*/
   1721 void MapEditClass::Set_House_Buttons(HousesType house, GadgetClass *btnlist, int base_id)
   1722 {
   1723 	HousesType h;
   1724 	int id;
   1725 	TextButtonClass *btn;
   1726 
   1727 	/*
   1728 	**	Loop through all houses, searching the button list for each one.
   1729 	*/
   1730 	for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) {
   1731 
   1732 		/*
   1733 		**	Compute the desired button ID; get a pointer to the button
   1734 		*/
   1735 		id = (int)h + base_id;
   1736 		btn = (TextButtonClass *)btnlist->Extract_Gadget(id);
   1737 		if (btn) {
   1738 
   1739 			/*
   1740 			**	If this house value is the desired one, turn the button on;
   1741 			**	otherwise, turn it off.
   1742 			*/
   1743 			if (h == house) {
   1744 				btn->Turn_On();
   1745 			} else {
   1746 				btn->Turn_Off();
   1747 			}
   1748 		}
   1749 	}
   1750 }
   1751 
   1752 
   1753 /***************************************************************************
   1754  * MapEditClass::Start_Trigger_Placement -- enters trigger placement mode  *
   1755  *                                                                         *
   1756  * INPUT:                                                                  *
   1757  *                                                                         *
   1758  * OUTPUT:                                                                 *
   1759  *                                                                         *
   1760  * WARNINGS:                                                               *
   1761  *                                                                         *
   1762  * HISTORY:                                                                *
   1763  *   12/01/1994 BR : Created.                                              *
   1764  *=========================================================================*/
   1765 void MapEditClass::Start_Trigger_Placement(void)
   1766 {
   1767 	Set_Default_Mouse(MOUSE_CAN_MOVE);
   1768 	Override_Mouse_Shape(MOUSE_CAN_MOVE);
   1769 }
   1770 
   1771 
   1772 /***************************************************************************
   1773  * MapEditClass::Stop_Trigger_Placement -- exits trigger placement mode    *
   1774  *                                                                         *
   1775  * INPUT:                                                                  *
   1776  *      none.                                                              *
   1777  *                                                                         *
   1778  * OUTPUT:                                                                 *
   1779  *      none.                                                              *
   1780  *                                                                         *
   1781  * WARNINGS:                                                               *
   1782  *      none.                                                              *
   1783  *                                                                         *
   1784  * HISTORY:                                                                *
   1785  *   12/01/1994 BR : Created.                                              *
   1786  *=========================================================================*/
   1787 void MapEditClass::Stop_Trigger_Placement(void)
   1788 {
   1789 	CurTrigger = NULL;
   1790 	Set_Default_Mouse(MOUSE_NORMAL);
   1791 	Override_Mouse_Shape(MOUSE_NORMAL);
   1792 }
   1793 
   1794 
   1795 /***************************************************************************
   1796  * MapEditClass::Place_Trigger -- assigns trigger to object or cell        *
   1797  *                                                                         *
   1798  * INPUT:                                                                  *
   1799  *      none.                                                              *
   1800  *                                                                         *
   1801  * OUTPUT:                                                                 *
   1802  *      none.                                                              *
   1803  *                                                                         *
   1804  * WARNINGS:                                                               *
   1805  *      none.                                                              *
   1806  *                                                                         *
   1807  * HISTORY:                                                                *
   1808  *   12/01/1994 BR : Created.                                              *
   1809  *=========================================================================*/
   1810 void MapEditClass::Place_Trigger(void)
   1811 {
   1812 	ObjectClass * object=NULL;		// Generic object clicked on.
   1813 	int x,y;
   1814 	CELL cell;									// Cell that was selected.
   1815 
   1816 	/*
   1817 	-------------------- See if an object was clicked on ---------------------
   1818 	*/
   1819 	x = _Kbd->MouseQX;
   1820 	y = _Kbd->MouseQY;
   1821 
   1822 	/*
   1823 	............................ Get cell for x,y ............................
   1824 	*/
   1825 	cell = Click_Cell_Calc(x, y);
   1826 
   1827 	/*
   1828 	............... Convert x,y to offset from cell upper-left ...............
   1829 	*/
   1830 	x = (x-TacPixelX) % ICON_PIXEL_W;
   1831 	y = (y-TacPixelY) % ICON_PIXEL_H;
   1832 
   1833 	/*
   1834 	......................... Get object at that x,y .........................
   1835 	*/
   1836 	object = Cell_Object(cell, x, y);
   1837 
   1838 	/*
   1839 	---------------------- Assign trigger to an object -----------------------
   1840 	*/
   1841 	if (object && TriggerClass::Event_Need_Object(CurTrigger->Event)) {
   1842 		object->Trigger = CurTrigger;
   1843 	} else {
   1844 
   1845 		/*
   1846 		------------------------ Assign trigger to a cell ------------------------
   1847 		*/
   1848 		if (CurTrigger->Event <= EVENT_OBJECTFIRST) {
   1849 			Map[cell].IsTrigger = 1;
   1850 			CellTriggers[cell] = CurTrigger;
   1851 		}
   1852 	}
   1853 
   1854 	/*
   1855 	-------------------------- Force map to redraw ---------------------------
   1856 	*/
   1857 	HiddenPage.Clear();
   1858 	Flag_To_Redraw(true);
   1859 }
   1860 
   1861 
   1862 /***************************************************************************
   1863  * MapEditClass::Start_Base_Building -- starts base-building mode          *
   1864  *                                                                         *
   1865  * INPUT:                                                                  *
   1866  *      none.                                                              *
   1867  *                                                                         *
   1868  * OUTPUT:                                                                 *
   1869  *      none.                                                              *
   1870  *                                                                         *
   1871  * WARNINGS:                                                               *
   1872  *      none.                                                              *
   1873  *                                                                         *
   1874  * HISTORY:                                                                *
   1875  *   12/01/1994 BR : Created.                                              *
   1876  *=========================================================================*/
   1877 void MapEditClass::Start_Base_Building(void)
   1878 {
   1879 	/*
   1880 	** Fully build the base so the user can edit it
   1881 	*/
   1882 	Build_Base_To(100);
   1883 
   1884 	/*
   1885 	** Start placement mode
   1886 	*/
   1887 	BaseBuilding = 1;
   1888 	Start_Placement();
   1889 
   1890 	/*
   1891 	** Force map to redraw
   1892 	*/
   1893 	HiddenPage.Clear();
   1894 	Flag_To_Redraw(true);
   1895 }
   1896 
   1897 
   1898 /***************************************************************************
   1899  * MapEditClass::Cancel_Base_Building -- stops base-building mode          *
   1900  *                                                                         *
   1901  * INPUT:                                                                  *
   1902  *      none.                                                              *
   1903  *                                                                         *
   1904  * OUTPUT:                                                                 *
   1905  *      none.                                                              *
   1906  *                                                                         *
   1907  * WARNINGS:                                                               *
   1908  *      none.                                                              *
   1909  *                                                                         *
   1910  * HISTORY:                                                                *
   1911  *   12/01/1994 BR : Created.                                              *
   1912  *=========================================================================*/
   1913 void MapEditClass::Cancel_Base_Building(void)
   1914 {
   1915 	/*
   1916 	** Build the base to the proper amount
   1917 	*/
   1918 	Build_Base_To(BasePercent);
   1919 
   1920 	/*
   1921 	** Cancel placement mode
   1922 	*/
   1923 	Cancel_Placement();
   1924 	BaseBuilding = 0;
   1925 
   1926 	/*
   1927 	** Force map to redraw
   1928 	*/
   1929 	HiddenPage.Clear();
   1930 	Flag_To_Redraw(true);
   1931 }
   1932 
   1933 
   1934 /***************************************************************************
   1935  * MapEditClass::Build_Base_To -- builds the AI base to the given percent  *
   1936  *                                                                         *
   1937  * INPUT:                                                                  *
   1938  *      percent      percentage to build base to                           *
   1939  *                                                                         *
   1940  * OUTPUT:                                                                 *
   1941  *      none.                                                              *
   1942  *                                                                         *
   1943  * WARNINGS:                                                               *
   1944  *      none.                                                              *
   1945  *                                                                         *
   1946  * HISTORY:                                                                *
   1947  *   12/01/1994 BR : Created.                                              *
   1948  *=========================================================================*/
   1949 void MapEditClass::Build_Base_To(int percent)
   1950 {
   1951 	int i;
   1952 	int num_buildings;
   1953 	BuildingTypeClass const *objtype;
   1954 	BuildingClass *obj;
   1955 
   1956 	//ScenarioInit++;
   1957 
   1958 	/*
   1959 	** Completely dismantle the base, so we start at a known point
   1960 	*/
   1961 	for (i = 0; i < Base.Nodes.Count(); i++) {
   1962 		if (Base.Is_Built(i)) {
   1963 			obj = Base.Get_Building(i);
   1964 			delete obj;
   1965 		}
   1966 	}
   1967 
   1968 	/*
   1969 	** Compute number of buildings to build
   1970 	*/
   1971 	num_buildings = (Base.Nodes.Count() * percent) / 100;
   1972 
   1973 	/*
   1974 	** Build the base to the desired amount
   1975 	*/
   1976 	for (i = 0; i < num_buildings; i++) {
   1977 		/*
   1978 		** Get a ptr to the type of building to build, create one, and unlimbo it.
   1979 		*/
   1980 		objtype = &BuildingTypeClass::As_Reference(Base.Nodes[i].Type);
   1981 		obj = (BuildingClass *)objtype->Create_One_Of(HouseClass::As_Pointer(Base.House));
   1982 		/*
   1983 		** If unlimbo fails, error out
   1984 		*/
   1985 		if (!obj->Unlimbo(Base.Nodes[i].Coord)) {
   1986 			delete obj;
   1987 			CCMessageBox().Process("Unable to build base!");
   1988 			return;
   1989 		}
   1990 	}
   1991 
   1992 	//ScenarioInit--;
   1993 }
   1994 
   1995 
   1996 #endif