MAPEDDLG.CPP (83457B)
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/MAPEDDLG.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 : MAPEDDLG.CPP * 24 * * 25 * Programmer : Bill Randolph * 26 * * 27 * Start Date : November 18, 1994 * 28 * * 29 * Last Update : September 4, 1996 [JLB] * 30 * * 31 *-------------------------------------------------------------------------* 32 * Map Editor dialogs & main menu options * 33 *-------------------------------------------------------------------------* 34 * Functions: * 35 * MapEditClass::Handle_Triggers -- processes the trigger dialogs * 36 * MapEditClass::Load_Scenario -- loads a scenario INI file * 37 * MapEditClass::New_Scenario -- creates a new scenario * 38 * MapEditClass::Pick_Scenario -- dialog for choosing scenario * 39 * MapEditClass::Save_Scenario -- saves current scenario to an INI file * 40 * MapEditClass::Scenario_Dialog -- scenario global parameters dialog * 41 * MapEditClass::Select_Trigger -- lets user select a trigger * 42 * MapEditClass::Size_Map -- lets user set size & location of map * 43 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 44 45 #include "function.h" 46 47 #ifdef SCENARIO_EDITOR 48 49 50 /*************************************************************************** 51 * MapEditClass::New_Scenario -- creates a new scenario * 52 * * 53 * - Prompts user for scenario data (house, scenario #); sets globals * 54 * PlayerPtr (for house) & Scenario (for scenario #) * 55 * - Prompts user for map size * 56 * - Initializes the scenario by calling Clear_Scenario(), which calls * 57 * everybody's Init() routine * 58 * * 59 * INPUT: * 60 * none. * 61 * * 62 * OUTPUT: * 63 * 0 = new scenario created, -1 = not * 64 * * 65 * WARNINGS: * 66 * none. * 67 * * 68 * HISTORY: * 69 * 10/21/1994 BR : Created. * 70 *=========================================================================*/ 71 int MapEditClass::New_Scenario(void) 72 { 73 int scen_num; 74 ScenarioPlayerType player; 75 ScenarioDirType dir; 76 ScenarioVarType var; 77 Disect_Scenario_Name(Scen.ScenarioName, scen_num, player, dir, var); 78 79 int rc; 80 HousesType house; 81 82 /* 83 ** Force the house save value to match the player house. 84 */ 85 if (PlayerPtr) { 86 switch (PlayerPtr->Class->House) { 87 case HOUSE_SPAIN: 88 player = SCEN_PLAYER_SPAIN; 89 break; 90 91 case HOUSE_GREECE: 92 player = SCEN_PLAYER_GREECE; 93 break; 94 95 default: 96 case HOUSE_USSR: 97 player = SCEN_PLAYER_USSR; 98 break; 99 } 100 } 101 102 /* 103 ** Prompt for scenario info 104 */ 105 rc = Pick_Scenario("New Scenario", scen_num, player, dir, var); 106 if (rc != 0) { 107 return(-1); 108 } 109 110 ScenarioInit++; 111 112 /* 113 ** Blow away everything 114 */ 115 Clear_Scenario(); 116 117 /* 118 ** Set parameters 119 */ 120 // Scen.Scenario = scen_num; 121 // Scen.ScenPlayer = player; 122 // Scen.ScenDir = dir; 123 // Scen.ScenVar = var; 124 Scen.Set_Scenario_Name(scen_num, player, dir, var); 125 126 /* 127 ** Create houses 128 */ 129 for (house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { 130 new HouseClass(house); 131 } 132 133 switch (player) { 134 case SCEN_PLAYER_MPLAYER: 135 PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI1); 136 PlayerPtr->IsHuman = true; 137 LastHouse = HOUSE_MULTI1; 138 break; 139 140 case SCEN_PLAYER_USSR: 141 PlayerPtr = HouseClass::As_Pointer(HOUSE_USSR); 142 PlayerPtr->IsHuman = true; 143 Base.House = HOUSE_SPAIN; 144 LastHouse = HOUSE_GOOD; 145 break; 146 147 case SCEN_PLAYER_SPAIN: 148 PlayerPtr = HouseClass::As_Pointer(HOUSE_SPAIN); 149 PlayerPtr->IsHuman = true; 150 Base.House = HOUSE_USSR; 151 LastHouse = HOUSE_GOOD; 152 break; 153 154 case SCEN_PLAYER_GREECE: 155 PlayerPtr = HouseClass::As_Pointer(HOUSE_GREECE); 156 PlayerPtr->IsHuman = true; 157 Base.House = HOUSE_USSR; 158 LastHouse = HOUSE_GOOD; 159 break; 160 } 161 162 /* 163 ** Init the entire map 164 */ 165 // Init_Clear(); 166 Fill_In_Data(); 167 168 /* 169 ** Prompt for map size 170 */ 171 Size_Map(-1, -1, 30, 30); 172 173 /* 174 ** Set the Home & Reinforcement Cells to the center of the map 175 */ 176 Scen.Waypoint[WAYPT_REINF] = XY_Cell(MapCellX + MapCellWidth / 2, MapCellY + MapCellHeight / 2); 177 Scen.Waypoint[WAYPT_HOME] = XY_Cell(MapCellX + MapCellWidth / 2, MapCellY + MapCellHeight / 2); 178 (*this)[TacticalCoord].IsWaypoint = 1; 179 Flag_Cell(Coord_Cell(TacticalCoord)); 180 181 Set_Tactical_Position(Cell_Coord(Scen.Waypoint[WAYPT_HOME] - (MAP_CELL_W * 4 * RESFACTOR) - (5 * RESFACTOR))); 182 ScenarioInit--; 183 184 return(0); 185 } 186 187 188 /*************************************************************************** 189 * MapEditClass::Load_Scenario -- loads a scenario INI file * 190 * * 191 * - Prompts user for scenario data (house, scenario #); sets globals * 192 * PlayerPtr (for house) & Scenario (for scenario #) * 193 * - Loads the INI file for that scenario * 194 * * 195 * INPUT: * 196 * none. * 197 * * 198 * OUTPUT: * 199 * 0. * 200 * * 201 * WARNINGS: * 202 * none. * 203 * * 204 * HISTORY: * 205 * 10/21/1994 BR : Created. * 206 *=========================================================================*/ 207 int MapEditClass::Load_Scenario(void) 208 { 209 int scen_num; 210 ScenarioPlayerType player; 211 ScenarioDirType dir; 212 ScenarioVarType var; 213 Disect_Scenario_Name(Scen.ScenarioName, scen_num, player, dir, var); 214 215 int rc; 216 NodeNameType * who; // node to add to Players 217 218 /* 219 ** Prompt for scenario info 220 */ 221 rc = Pick_Scenario("Load Scenario", scen_num, player, dir, var); 222 if (rc != 0) { 223 return(-1); 224 } 225 226 /* 227 ** Set parameters 228 */ 229 // Scen.Scenario = scen_num; 230 // Scen.ScenPlayer = player; 231 // Scen.ScenDir = dir; 232 // Scen.ScenVar = var; 233 Scen.Set_Scenario_Name(scen_num, player, dir, var); 234 235 /* 236 ** Read_Scenario_Ini() must be able to set PlayerPtr to the right house: 237 ** - Reading the INI will create the house objects 238 ** - PlayerPtr must be set before any Techno objects are created 239 ** - For GDI or NOD scenarios, PlayerPtr is set by reading the INI; 240 ** but for multiplayer, it's set via the Players vector; so, here we have 241 ** to set various multiplayer variables to fool the Assign_Houses() routine 242 ** into working properly. 243 */ 244 if (player == SCEN_PLAYER_MPLAYER) { 245 Clear_Vector(&Session.Players); 246 247 who = new NodeNameType; 248 strcpy(who->Name, Session.Handle); 249 who->Player.House = Session.House; 250 who->Player.Color = Session.ColorIdx; 251 Session.Players.Add (who); 252 253 Session.NumPlayers = 1; 254 LastHouse = HOUSE_MULTI1; 255 } else { 256 #ifdef NEVER 257 if (ScenPlayer==SCEN_PLAYER_JP) { 258 PlayerPtr = HouseClass::As_Pointer(HOUSE_MULTI4); 259 PlayerPtr->IsHuman = true; 260 Base.House = HOUSE_MULTI4; 261 } else { 262 #endif 263 LastHouse = HOUSE_GOOD; 264 } 265 266 /* 267 ** Blow away everything 268 */ 269 Clear_Scenario(); 270 271 /* 272 ** Read the INI 273 */ 274 if (Read_Scenario_INI(Scen.ScenarioName) == 0) { 275 if(Scen.Scenario < 20 && Scen.ScenarioName[2] == 'G'){ 276 WWMessageBox().Process("Please insert Red Alert CD1"); 277 }else if(Scen.Scenario < 20 && Scen.ScenarioName[2] == 'U') 278 WWMessageBox().Process("Please insert Red Alert CD2"); 279 else 280 WWMessageBox().Process("Unable to read scenario!"); 281 HidPage.Clear(); 282 Flag_To_Redraw(true); 283 Render(); 284 } else { 285 Fill_In_Data(); 286 GamePalette.Set(); 287 // Set_Palette(GamePalette); 288 } 289 290 return(0); 291 } 292 293 294 /*************************************************************************** 295 * MapEditClass::Save_Scenario -- saves current scenario to an INI file * 296 * * 297 * - Prompts user for scenario data (house, scenario #); sets globals * 298 * PlayerPtr (for house) & Scenario (for scenario #) * 299 * - Saves the INI file for this scenario * 300 * * 301 * INPUT: * 302 * none. * 303 * * 304 * OUTPUT: * 305 * 0 = OK, -1 = error/cancel * 306 * * 307 * WARNINGS: * 308 * none. * 309 * * 310 * HISTORY: * 311 * 10/21/1994 BR : Created. * 312 *=========================================================================*/ 313 int MapEditClass::Save_Scenario(void) 314 { 315 int scen_num; 316 ScenarioPlayerType player; 317 ScenarioDirType dir; 318 ScenarioVarType var; 319 320 Disect_Scenario_Name(Scen.ScenarioName, scen_num, player, dir, var); 321 322 int rc; 323 // FILE * fp; 324 // char fname[13]; 325 326 /* 327 ** Prompt for scenario info 328 */ 329 rc = Pick_Scenario("Save Scenario", scen_num, player, dir, var); 330 if (rc != 0) { 331 return(-1); 332 } 333 334 /* 335 ** Warning if scenario already exists 336 */ 337 // Scen.Set_Scenario_Name(scen_num, player, dir, var); 338 // fp = fopen(fname, "rb"); 339 // if (fp) { 340 // fclose(fp); 341 // rc = WWMessageBox().Process("File exists. Replace?", TXT_YES, TXT_NO); 342 // HidPage.Clear(); 343 // Flag_To_Redraw(true); 344 // Render(); 345 // if (rc==1) { 346 // return(-1); 347 // } 348 // } 349 350 /* 351 ** Set parameters 352 */ 353 // Scen.Scenario = scen_num; 354 // Scen.ScenPlayer = player; 355 // Scen.ScenDir = dir; 356 // Scen.ScenVar = var; 357 Scen.Set_Scenario_Name(scen_num, player, dir, var); 358 359 /* 360 ** Player may have changed from GDI to NOD, so change playerptr accordingly 361 */ 362 switch (player) { 363 case SCEN_PLAYER_USSR: 364 PlayerPtr = HouseClass::As_Pointer(HOUSE_USSR); 365 PlayerPtr->IsHuman = true; 366 // Base.House = HOUSE_SPAIN; 367 LastHouse = HOUSE_GOOD; 368 break; 369 370 case SCEN_PLAYER_SPAIN: 371 PlayerPtr = HouseClass::As_Pointer(HOUSE_SPAIN); 372 PlayerPtr->IsHuman = true; 373 // Base.House = HOUSE_USSR; 374 LastHouse = HOUSE_GOOD; 375 break; 376 377 case SCEN_PLAYER_GREECE: 378 PlayerPtr = HouseClass::As_Pointer(HOUSE_GREECE); 379 PlayerPtr->IsHuman = true; 380 // Base.House = HOUSE_USSR; 381 LastHouse = HOUSE_GOOD; 382 break; 383 } 384 385 /* 386 ** Write the INI 387 */ 388 Write_Scenario_INI(Scen.ScenarioName); 389 390 return(0); 391 } 392 393 394 /*************************************************************************** 395 * MapEditClass::Pick_Scenario -- dialog for choosing scenario * 396 * * 397 * Prompts user for: * 398 * - House (GDI, NOD) * 399 * - Scenario # * 400 * * 401 * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * 402 * ³ Caption ³ * 403 * ³ ³ * 404 * ³ Scenario ___ ³ * 405 * ³ Version ___ ³ * 406 * ³ ³ * 407 * ³ [East] [West] ³ * 408 * ³ ³ * 409 * ³ [ GDI ] ³ * 410 * ³ [ NOD ] ³ * 411 * ³ [Multi-Player] ³ * 412 * ³ ³ * 413 * ³ [OK] [Cancel] ³ * 414 * ³ ³ * 415 * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * 416 * * 417 * INPUT: * 418 * caption string to use as a title * 419 * scen_nump output: ptr to scenario # * 420 * playerp output: ptr to player type * 421 * dirp output: ptr to direction * 422 * varp output: ptr to variation * 423 * multi 1 = allow to change single/multiplayer; 0 = not * 424 * * 425 * OUTPUT: * 426 * 0 = OK, -1 = cancel * 427 * * 428 * WARNINGS: * 429 * none. * 430 * * 431 * HISTORY: * 432 * 10/21/1994 BR : Created. * 433 * 09/04/1996 JLB : Simplified * 434 *=========================================================================*/ 435 int MapEditClass::Pick_Scenario(char const * caption, int & scen_nump, ScenarioPlayerType & playerp, ScenarioDirType & dirp, ScenarioVarType & varp) 436 { 437 /* 438 ** Dialog & button dimensions 439 */ 440 enum { 441 D_DIALOG_W = 200, // dialog width 442 D_DIALOG_H = 164, // dialog height 443 D_DIALOG_X = ((320 - D_DIALOG_W) / 2), // centered x-coord 444 D_DIALOG_Y = ((200 - D_DIALOG_H) / 2), // centered y-coord 445 D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center 446 447 D_TXT8_H = 11, // ht of 8-pt text 448 D_MARGIN = 7, // margin width/height 449 450 D_SCEN_W = 45, // Scenario # width 451 D_SCEN_H = 9, // Scenario # height 452 D_SCEN_X = D_DIALOG_CX + 5, // Scenario # x 453 D_SCEN_Y = D_DIALOG_Y + D_MARGIN + D_TXT8_H + D_MARGIN, // Scenario # y 454 455 D_VARA_W = 13, // Version A width 456 D_VARA_H = 9, // Version A height 457 D_VARA_X = D_DIALOG_CX - (D_VARA_W * 5) / 2, // Version A x 458 D_VARA_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN, // Version A y 459 460 D_VARB_W = 13, // Version B width 461 D_VARB_H = 9, // Version B height 462 D_VARB_X = D_VARA_X + D_VARA_W, // Version B x 463 D_VARB_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN, // Version B y 464 465 D_VARC_W = 13, // Version C width 466 D_VARC_H = 9, // Version C height 467 D_VARC_X = D_VARB_X + D_VARB_W, // Version C x 468 D_VARC_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN, // Version C y 469 470 D_VARD_W = 13, // Version D width 471 D_VARD_H = 9, // Version D height 472 D_VARD_X = D_VARC_X + D_VARC_W, // Version D x 473 D_VARD_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN, // Version D y 474 475 D_VARLOSE_W = 13, // Version Lose width 476 D_VARLOSE_H = 9, // Version Lose height 477 D_VARLOSE_X = D_VARD_X + D_VARD_W, // Version Lose x 478 D_VARLOSE_Y = D_SCEN_Y + D_SCEN_H + D_MARGIN, // Version Lose y 479 480 D_EAST_W = 50, // EAST width 481 D_EAST_H = 9, // EAST height 482 D_EAST_X = D_DIALOG_CX - D_EAST_W - 5, // EAST x 483 D_EAST_Y = D_VARLOSE_Y + D_VARLOSE_H + D_MARGIN,// EAST y 484 485 D_WEST_W = 50, // WEST width 486 D_WEST_H = 9, // WEST height 487 D_WEST_X = D_DIALOG_CX + 5, // WEST x 488 D_WEST_Y = D_VARLOSE_Y + D_VARLOSE_H + D_MARGIN,// EAST y 489 490 D_GDI_W = 90, // GDI width 491 D_GDI_H = 9, // GDI height 492 D_GDI_X = D_DIALOG_CX - (D_GDI_W / 2), // GDI x 493 D_GDI_Y = D_EAST_Y + D_EAST_H + D_MARGIN, // GDI y 494 495 D_NOD_W = 90, // NOD width 496 D_NOD_H = 9, // NOD height 497 D_NOD_X = D_DIALOG_CX - (D_NOD_W / 2), // NOD x 498 D_NOD_Y = D_GDI_Y + D_GDI_H, // NOD y 499 500 D_NEU_W = 90, // Neutral width 501 D_NEU_H = 9, // Neutral height 502 D_NEU_X = D_DIALOG_CX - (D_NOD_W / 2), // Neutral x 503 D_NEU_Y = D_NOD_Y + D_NOD_H, // Neutral y 504 505 D_MPLAYER_W = 90, // Multi-Player width 506 D_MPLAYER_H = 9, // Multi-Player height 507 D_MPLAYER_X = D_DIALOG_CX - (D_MPLAYER_W / 2), // Multi-Player x 508 D_MPLAYER_Y = D_NEU_Y + D_NEU_H, // Multi-Player y 509 510 D_OK_W = 45, // OK width 511 D_OK_H = 9, // OK height 512 D_OK_X = D_DIALOG_CX - D_OK_W - 5, // OK x 513 D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - (D_MARGIN+15), // OK y 514 515 D_CANCEL_W = 45, // Cancel width 516 D_CANCEL_H = 9, // Cancel height 517 D_CANCEL_X = D_DIALOG_CX + 5, // Cancel x 518 D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - (D_MARGIN+15), // Cancel y 519 520 }; 521 522 /* 523 ** Button enumerations 524 */ 525 enum { 526 BUTTON_GDI=100, 527 BUTTON_NOD, 528 BUTTON_NEUTRAL, 529 BUTTON_MPLAYER, 530 BUTTON_EAST, 531 BUTTON_WEST, 532 BUTTON_OK, 533 BUTTON_CANCEL, 534 BUTTON_SCENARIO, 535 BUTTON_VAR_A, 536 BUTTON_VAR_B, 537 BUTTON_VAR_C, 538 BUTTON_VAR_D, 539 }; 540 541 /* 542 ** Dialog variables 543 */ 544 bool cancel = false; // true = user cancels 545 546 /* 547 ** Other Variables 548 */ 549 char scen_buf[10]={0}; // buffer for editing scenario # 550 551 /* 552 ** Buttons 553 */ 554 ControlClass * commands = NULL; // the button list 555 #ifdef FIXIT_CSII // checked - ajw 9/28/98 556 EditClass editbtn (BUTTON_SCENARIO, scen_buf, 5, TPF_EFNT|TPF_NOSHADOW, D_SCEN_X, D_SCEN_Y, D_SCEN_W, D_SCEN_H, EditClass::ALPHANUMERIC); 557 #else 558 EditClass editbtn (BUTTON_SCENARIO, scen_buf, 5, TPF_EFNT|TPF_NOSHADOW, D_SCEN_X, D_SCEN_Y, D_SCEN_W, D_SCEN_H, EditClass::NUMERIC); 559 #endif 560 561 TextButtonClass varabtn(BUTTON_VAR_A, "A", TPF_EBUTTON, D_VARA_X, D_VARA_Y, D_VARA_W, D_VARA_H); 562 TextButtonClass varbbtn(BUTTON_VAR_B, "B", TPF_EBUTTON, D_VARB_X, D_VARB_Y, D_VARB_W, D_VARB_H); 563 TextButtonClass varcbtn(BUTTON_VAR_C, "C", TPF_EBUTTON, D_VARC_X, D_VARC_Y, D_VARC_W, D_VARC_H); 564 TextButtonClass vardbtn(BUTTON_VAR_D, "D", TPF_EBUTTON, D_VARD_X, D_VARD_Y, D_VARD_W, D_VARD_H); 565 TextButtonClass gdibtn(BUTTON_GDI, "North (Spain)", TPF_EBUTTON, D_GDI_X, D_GDI_Y, D_GDI_W, D_GDI_H); 566 TextButtonClass nodbtn(BUTTON_NOD, "South (Greece)", TPF_EBUTTON, D_NOD_X, D_NOD_Y, D_NOD_W, D_NOD_H); 567 TextButtonClass neubtn(BUTTON_NEUTRAL, HouseTypeClass::As_Reference(HOUSE_USSR).IniName, TPF_EBUTTON, D_NEU_X, D_NEU_Y, D_NEU_W, D_NEU_H); 568 TextButtonClass playermbtn(BUTTON_MPLAYER, "Multiplayer", TPF_EBUTTON, D_MPLAYER_X, D_MPLAYER_Y, D_MPLAYER_W, D_MPLAYER_H); 569 TextButtonClass eastbtn(BUTTON_EAST, "East", TPF_EBUTTON, D_EAST_X, D_EAST_Y, D_EAST_W, D_EAST_H); 570 TextButtonClass westbtn(BUTTON_WEST, "West", TPF_EBUTTON, D_WEST_X, D_WEST_Y, D_WEST_W, D_WEST_H); 571 TextButtonClass okbtn(BUTTON_OK, TXT_OK, TPF_EBUTTON, D_OK_X, D_OK_Y, D_OK_W, D_OK_H); 572 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_EBUTTON, D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); 573 574 /* 575 ** Initialize 576 */ 577 Set_Logic_Page(SeenBuff); 578 579 #ifdef FIXIT_CSII // checked - ajw 9/28/98 580 if (scen_nump < 100) { 581 sprintf(scen_buf, "%d", scen_nump); // init edit buffer 582 } else { 583 char first = scen_nump / 36; 584 char second = scen_nump % 36; 585 scen_buf[0] = first + 'A'; 586 //Mono_Printf("picking map, scen# = %d, first = %c, second = %d (numeric)\n",scen_nump, scen_buf[0],second);Keyboard->Get();Keyboard->Get(); 587 if (second < 10) { 588 scen_buf[1] = second + '0'; 589 } else { 590 scen_buf[1] = (second-10) + 'A'; 591 } 592 scen_buf[2] = 0; 593 } 594 #else 595 sprintf(scen_buf, "%d", scen_nump); // init edit buffer 596 #endif 597 editbtn.Set_Text(scen_buf, 5); 598 599 varabtn.Turn_Off(); 600 varbbtn.Turn_Off(); 601 varcbtn.Turn_Off(); 602 vardbtn.Turn_Off(); 603 switch (varp) { 604 case SCEN_VAR_A: 605 varabtn.Turn_On(); 606 break; 607 608 case SCEN_VAR_B: 609 varbbtn.Turn_On(); 610 break; 611 612 case SCEN_VAR_C: 613 varcbtn.Turn_On(); 614 break; 615 616 case SCEN_VAR_D: 617 vardbtn.Turn_On(); 618 break; 619 } 620 621 /* 622 ** Create the button list 623 */ 624 commands = &editbtn; 625 varabtn.Add_Tail(*commands); 626 varbbtn.Add_Tail(*commands); 627 varcbtn.Add_Tail(*commands); 628 vardbtn.Add_Tail(*commands); 629 gdibtn.Add_Tail(*commands); 630 nodbtn.Add_Tail(*commands); 631 neubtn.Add_Tail(*commands); 632 playermbtn.Add_Tail(*commands); 633 eastbtn.Add_Tail(*commands); 634 westbtn.Add_Tail(*commands); 635 okbtn.Add_Tail(*commands); 636 cancelbtn.Add_Tail(*commands); 637 638 /* 639 ** Init the button states 640 */ 641 gdibtn.Turn_Off(); 642 nodbtn.Turn_Off(); 643 neubtn.Turn_Off(); 644 playermbtn.Turn_Off(); 645 if (playerp == SCEN_PLAYER_MPLAYER) { 646 playermbtn.Turn_On(); 647 } else { 648 if (PlayerPtr) { 649 switch (PlayerPtr->Class->House) { 650 case HOUSE_SPAIN: 651 gdibtn.Turn_On(); 652 break; 653 654 case HOUSE_GREECE: 655 nodbtn.Turn_On(); 656 break; 657 658 case HOUSE_USSR: 659 neubtn.Turn_On(); 660 break; 661 } 662 #ifdef FIXIT_CSII // checked - ajw 9/28/98 663 } else { 664 switch (Scen.ScenarioName[2]) { 665 case 'G': 666 gdibtn.Turn_On(); 667 break; 668 669 case 'U': 670 nodbtn.Turn_On(); 671 break; 672 673 case 'M': 674 playermbtn.Turn_On(); 675 break; 676 } 677 #endif 678 } 679 } 680 681 eastbtn.Turn_Off(); 682 westbtn.Turn_Off(); 683 if (dirp == SCEN_DIR_EAST) { 684 eastbtn.Turn_On(); 685 } else { 686 westbtn.Turn_On(); 687 } 688 689 /* 690 ** Main Processing Loop 691 */ 692 bool display = true; 693 bool process = true; 694 while (process) { 695 696 /* 697 ** Invoke game callback 698 */ 699 Call_Back(); 700 701 /* 702 ** Refresh display if needed 703 */ 704 if (display) { 705 Hide_Mouse(); 706 Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); 707 Draw_Caption(caption, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); 708 Fancy_Text_Print("Scenario", D_DIALOG_CX - 5, D_SCEN_Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_RIGHT | TPF_EFNT | TPF_NOSHADOW); 709 commands->Draw_All(); 710 Show_Mouse(); 711 712 display = false; 713 } 714 715 /* 716 ** Get user input 717 */ 718 KeyNumType input = commands->Input(); 719 720 /* 721 ** Process input 722 */ 723 switch (input) { 724 725 /* 726 ** Handle a click on one of the scenario variation group buttons. 727 */ 728 case (BUTTON_VAR_A | KN_BUTTON): 729 case (BUTTON_VAR_B | KN_BUTTON): 730 case (BUTTON_VAR_C | KN_BUTTON): 731 case (BUTTON_VAR_D | KN_BUTTON): 732 varabtn.Turn_Off(); 733 varbbtn.Turn_Off(); 734 varcbtn.Turn_Off(); 735 vardbtn.Turn_Off(); 736 switch (input) { 737 case (BUTTON_VAR_A | KN_BUTTON): 738 varp = SCEN_VAR_A; 739 varabtn.Turn_On(); 740 break; 741 742 case (BUTTON_VAR_B | KN_BUTTON): 743 varp = SCEN_VAR_B; 744 varbbtn.Turn_On(); 745 break; 746 747 case (BUTTON_VAR_C | KN_BUTTON): 748 varp = SCEN_VAR_C; 749 varcbtn.Turn_On(); 750 break; 751 752 case (BUTTON_VAR_D | KN_BUTTON): 753 varp = SCEN_VAR_D; 754 vardbtn.Turn_On(); 755 break; 756 } 757 break; 758 759 /* 760 ** Handle a click on the east/west variation group. 761 */ 762 case (BUTTON_EAST | KN_BUTTON): 763 case (BUTTON_WEST | KN_BUTTON): 764 westbtn.Turn_Off(); 765 eastbtn.Turn_Off(); 766 switch (input) { 767 case (BUTTON_EAST | KN_BUTTON): 768 dirp = SCEN_DIR_EAST; 769 eastbtn.Turn_On(); 770 break; 771 772 case (BUTTON_WEST | KN_BUTTON): 773 dirp = SCEN_DIR_WEST; 774 westbtn.Turn_On(); 775 break; 776 } 777 break; 778 779 780 /* 781 ** Handle a click on one of the player category 782 ** group buttons. 783 */ 784 case (BUTTON_GDI | KN_BUTTON): 785 case (BUTTON_NOD | KN_BUTTON): 786 case (BUTTON_NEUTRAL | KN_BUTTON): 787 case (BUTTON_MPLAYER | KN_BUTTON): 788 gdibtn.Turn_Off(); 789 nodbtn.Turn_Off(); 790 neubtn.Turn_Off(); 791 playermbtn.Turn_Off(); 792 switch (input) { 793 case (BUTTON_GDI | KN_BUTTON): 794 playerp = SCEN_PLAYER_SPAIN; 795 gdibtn.Turn_On(); 796 break; 797 798 case (BUTTON_NOD | KN_BUTTON): 799 playerp = SCEN_PLAYER_GREECE; 800 nodbtn.Turn_On(); 801 break; 802 803 case (BUTTON_NEUTRAL | KN_BUTTON): 804 playerp = SCEN_PLAYER_USSR; 805 neubtn.Turn_On(); 806 break; 807 808 case (BUTTON_MPLAYER | KN_BUTTON): 809 playerp = SCEN_PLAYER_MPLAYER; 810 playermbtn.Turn_On(); 811 break; 812 } 813 break; 814 815 case (KN_RETURN): 816 case (BUTTON_OK | KN_BUTTON): 817 cancel = false; 818 process = false; 819 break; 820 821 case (KN_ESC): 822 case (BUTTON_CANCEL | KN_BUTTON): 823 cancel = true; 824 process = false; 825 break; 826 827 case (BUTTON_SCENARIO | KN_BUTTON): 828 break; 829 830 default: 831 break; 832 } 833 } 834 835 /* 836 ** Redraw the display 837 */ 838 HidPage.Clear(); 839 Flag_To_Redraw(true); 840 Render(); 841 842 /* 843 ** If cancel, just return 844 */ 845 if (cancel) { 846 return(-1); 847 } 848 849 /* 850 ** Save selections & return 851 */ 852 #ifdef FIXIT_CSII // checked - ajw 9/28/98 853 if (scen_buf[0] <= '9' && scen_buf[1] <= '9') { 854 scen_nump = atoi(scen_buf); 855 } else { 856 char first = scen_buf[0]; 857 char second = scen_buf[1]; 858 if (first <= '9') { 859 first -= '0'; 860 } else { 861 if (first >= 'a' && first <= 'z') { 862 first -= 'a'; 863 } else { 864 first -= 'A'; 865 } 866 } 867 if (second <= '9') { 868 second -= '0'; 869 } else { 870 if (second >= 'a' && second <= 'z') { 871 second = (second - 'a') + 10; 872 } else { 873 second = (second - 'A') + 10; 874 } 875 } 876 scen_nump = (first * 36) + second; 877 //Mono_Printf("Converted to: %d, %d = %d\n",first, second, scen_nump);Keyboard->Get();Keyboard->Get(); 878 } 879 #else 880 scen_nump = atoi(scen_buf); 881 #endif 882 883 return(0); 884 } 885 886 887 /*************************************************************************** 888 * MapEditClass::Size_Map -- lets user set size & location of map * 889 * * 890 * Lets the user select a side of the map and expand/shrink it to the * 891 * desired size, or move the whole map around the available map area. * 892 * * 893 * The entire available map area is displayed, but the map is limited such * 894 * that there's always one blank cell around the map; this lets objects * 895 * properly exit the screen, since they have a blank undisplayed cell to * 896 * exit onto. * 897 * * 898 * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * 899 * ³ ³ * 900 * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Clear Terrain ³ * 901 * ³ ³ ³ Water ³ * 902 * ³ ³ ³ Tiberium ³ * 903 * ³ ³ ³ Rock/Wall/Road ³ * 904 * ³ ³ (Map Area) ³ GDI Unit ³ * 905 * ³ ³ ³ NOD Unit ³ * 906 * ³ ³ ³ Neutral Unit ³ * 907 * ³ ³ ³ Terrain Object ³ * 908 * ³ ³ ³ Starting Cell ³ * 909 * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ * 910 * ³ ³ * 911 * ³ X Y Width Height ³ * 912 * ³ ## ## ## ## ³ * 913 * ³ ³ * 914 * ³ ³ * 915 * ³ [OK] [Cancel] ³ * 916 * ³ ³ * 917 * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * 918 * * 919 * INPUT: * 920 * x,y,w,h: initial size parameters (-1 = center the thing) * 921 * * 922 * OUTPUT: * 923 * 0 = OK, -1 = cancel * 924 * * 925 * WARNINGS: * 926 * none. * 927 * * 928 * HISTORY: * 929 * 10/21/1994 BR : Created. * 930 *=========================================================================*/ 931 int MapEditClass::Size_Map(int x, int y, int w, int h) 932 { 933 /* 934 ** Dialog & button dimensions 935 */ 936 enum { 937 D_DIALOG_W = 350, // dialog width 938 D_DIALOG_H = 225, // dialog height 939 D_DIALOG_X = 0, // centered x-coord 940 D_DIALOG_Y = 0, // centered y-coord 941 // D_DIALOG_CX = D_DIALOG_X + (D_DIALOG_W / 2), // coord of x-center 942 943 D_TXT8_H = 11, // ht of 8-pt text 944 D_MARGIN = 7, // margin width/height 945 946 D_BORD_X1 = D_DIALOG_X + 45, 947 // D_BORD_X1 = D_DIALOG_X + (D_DIALOG_W / 2 - MAP_CELL_W) / 2, 948 D_BORD_Y1 = D_DIALOG_Y + 25, 949 D_BORD_X2 = D_BORD_X1 + MAP_CELL_W + 1, 950 D_BORD_Y2 = D_BORD_Y1 + MAP_CELL_H + 1, 951 952 D_OK_W = 45, // OK width 953 D_OK_H = 9, // OK height 954 D_OK_X = D_DIALOG_X + 45, // OK x 955 D_OK_Y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - (D_MARGIN + 10), // OK y 956 957 D_CANCEL_W = 45, // Cancel width 958 D_CANCEL_H = 9, // Cancel height 959 D_CANCEL_X = D_DIALOG_X + D_DIALOG_W - (35 + D_CANCEL_W), // Cancel x 960 D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - D_CANCEL_H - (D_MARGIN + 10), // Cancel y 961 }; 962 963 /* 964 ** Button enumerations: 965 */ 966 enum { 967 BUTTON_OK=100, 968 BUTTON_CANCEL, 969 }; 970 971 /* 972 ** Redraw values: in order from "top" to "bottom" layer of the dialog 973 */ 974 typedef enum { 975 REDRAW_NONE = 0, 976 REDRAW_MAP, // includes map interior & coord values 977 REDRAW_BACKGROUND, // includes box, map board, key, coord labels, btns 978 REDRAW_ALL = REDRAW_BACKGROUND 979 } RedrawType; 980 981 /* 982 ** Dialog variables: 983 */ 984 RedrawType display; // requested redraw level 985 bool cancel = false; // true = user cancels 986 KeyNumType input; // user input 987 int grabbed = 0; // 1=TLeft,2=TRight,3=BRight,4=BLeft 988 int map_x1; // map coords x1, pixel coords 989 int map_x2; // map coords x2, pixel coords 990 int map_y1; // map coords y1, pixel coords 991 int map_y2; // map coords y2, pixel coords 992 int delta1, delta2; // mouse-click proximity 993 int mx,my; // last-saved mouse coords 994 // char txt[40]; 995 int txt_x,txt_y; // for displaying text 996 // unsigned index; // for drawing map symbology 997 CELL cell; // for drawing map symbology 998 int color; // for drawing map symbology 999 ObjectClass * occupier; // cell's occupier 1000 RemapControlType * scheme = GadgetClass::Get_Color_Scheme(); 1001 1002 /* 1003 ** Buttons 1004 */ 1005 ControlClass * commands = NULL; 1006 1007 TextButtonClass okbtn (BUTTON_OK, TXT_OK, TPF_EBUTTON, D_OK_X, D_OK_Y, D_OK_W, D_OK_H); 1008 1009 TextButtonClass cancelbtn (BUTTON_CANCEL, TXT_CANCEL, TPF_EBUTTON, D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); 1010 1011 /* 1012 ** Initialize 1013 */ 1014 Set_Logic_Page(SeenBuff); 1015 1016 /* 1017 ** Set up the actual map area relative to the map's border coords 1018 */ 1019 if (x==-1) { 1020 map_x1 = D_BORD_X1 + (MAP_CELL_W - w) / 2 + 1; 1021 } else { 1022 map_x1 = D_BORD_X1 + x + 1; 1023 } 1024 1025 if (y==-1) { 1026 map_y1 = D_BORD_Y1 + (MAP_CELL_H - h) / 2 + 1; 1027 } else { 1028 map_y1 = D_BORD_Y1 + y + 1; 1029 } 1030 1031 map_x2 = map_x1 + w - 1; 1032 map_y2 = map_y1 + h - 1; 1033 1034 /* 1035 ** Build the button list 1036 */ 1037 commands = &okbtn; 1038 cancelbtn.Add_Tail(*commands); 1039 1040 /* 1041 ** Main processing loop 1042 */ 1043 display = REDRAW_ALL; 1044 bool process = true; 1045 while (process) { 1046 1047 /* 1048 ** Invoke game callback 1049 */ 1050 Call_Back(); 1051 1052 /* 1053 ** Refresh display if needed 1054 */ 1055 if (display) { 1056 Hide_Mouse(); 1057 1058 /* 1059 ** Redraw the background, map border, key, and coord labels 1060 */ 1061 if (display >= REDRAW_BACKGROUND) { 1062 1063 /* 1064 ** Background 1065 */ 1066 Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); 1067 Draw_Caption(TXT_SIZE_MAP, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); 1068 1069 /* 1070 ** Draw the map border 1071 */ 1072 if (LogicPage->Lock()) { 1073 LogicPage->Draw_Rect(D_BORD_X1, D_BORD_Y1, D_BORD_X2, D_BORD_Y2, scheme->Shadow); 1074 // for (index = D_BORD_X1; index < D_BORD_X2; 1075 // index += (320/ICON_PIXEL_W)) { 1076 // LogicPage->Put_Pixel(index, D_BORD_Y1-1, scheme->Shadow); 1077 // LogicPage->Put_Pixel(index, D_BORD_Y2+1, scheme->Shadow); 1078 // } 1079 // for (index = D_BORD_Y1; index < D_BORD_Y2-8; 1080 // index += (200/ICON_PIXEL_H)) { 1081 // LogicPage->Put_Pixel(D_BORD_X1-1, index, scheme->Shadow); 1082 // LogicPage->Put_Pixel(D_BORD_X2+1, index, scheme->Shadow); 1083 // } 1084 1085 /* 1086 ** Draw the map "key" 1087 */ 1088 txt_x = D_BORD_X2 + 15; 1089 txt_y = D_BORD_Y1; 1090 Plain_Text_Print("Clear Terrain", txt_x, txt_y, GroundColor[LAND_CLEAR], TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1091 txt_y += 8; 1092 Plain_Text_Print("Water", txt_x, txt_y, GroundColor[LAND_WATER], TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1093 txt_y += 8; 1094 Plain_Text_Print("Tiberium", txt_x, txt_y, GroundColor[LAND_TIBERIUM], TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1095 txt_y += 8; 1096 Plain_Text_Print("Rock", txt_x, txt_y, GroundColor[LAND_ROCK], TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1097 txt_y += 8; 1098 Plain_Text_Print("Wall", txt_x, txt_y, GroundColor[LAND_WALL], TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1099 txt_y += 8; 1100 Plain_Text_Print("Beach", txt_x, txt_y, GroundColor[LAND_BEACH], TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1101 txt_y += 8; 1102 Plain_Text_Print("Rough", txt_x, txt_y, GroundColor[LAND_ROUGH], TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1103 txt_y += 8; 1104 Plain_Text_Print("River", txt_x, txt_y, GroundColor[LAND_RIVER], TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1105 // txt_y += 8; 1106 // Plain_Text_Print("GDI Unit", txt_x, txt_y, YELLOW, TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1107 // txt_y += 8; 1108 // Plain_Text_Print("Nod Unit", txt_x, txt_y, RED, TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1109 // txt_y += 8; 1110 // Plain_Text_Print("Neutral Unit", txt_x, txt_y, PURPLE, TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1111 txt_y += 8; 1112 Plain_Text_Print("Terrain Object", txt_x, txt_y, DKGREEN, TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1113 txt_y += 8; 1114 Plain_Text_Print("Starting Cell", txt_x, txt_y, WHITE, TBLACK, TPF_DROPSHADOW | TPF_EFNT); 1115 1116 /* 1117 ** Draw the coordinate labels 1118 */ 1119 txt_x = D_DIALOG_X + D_DIALOG_W / 8; 1120 txt_y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - 43; 1121 Fancy_Text_Print(" X", txt_x, txt_y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_CENTER | TPF_EFNT | TPF_NOSHADOW); 1122 1123 txt_x += (D_DIALOG_W - 20) / 4; 1124 Fancy_Text_Print(" Y", txt_x, txt_y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_CENTER | TPF_EFNT | TPF_NOSHADOW); 1125 1126 txt_x += (D_DIALOG_W - 20) / 4; 1127 Fancy_Text_Print(" Width", txt_x, txt_y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_CENTER | TPF_EFNT | TPF_NOSHADOW); 1128 1129 txt_x += (D_DIALOG_W - 20) / 4; 1130 Fancy_Text_Print(" Height", txt_x, txt_y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_CENTER | TPF_EFNT | TPF_NOSHADOW); 1131 1132 LogicPage->Unlock(); 1133 } 1134 1135 /* 1136 ** Redraw the buttons 1137 */ 1138 commands->Flag_List_To_Redraw(); 1139 } 1140 1141 /* 1142 ** Redraw the map symbology & location 1143 */ 1144 if (display >= REDRAW_MAP) { 1145 1146 if (LogicPage->Lock()) { 1147 1148 /* 1149 ** Erase the map interior 1150 */ 1151 LogicPage->Fill_Rect(D_BORD_X1 + 1, D_BORD_Y1 + 1, D_BORD_X2 - 1, D_BORD_Y2 - 1, BLACK); 1152 1153 /* 1154 ** Draw Land map symbols (use color according to Ground[] array). 1155 */ 1156 for (cell=0; cell < MAP_CELL_TOTAL; cell++) { 1157 occupier = (*this)[cell].Cell_Occupier(); 1158 if (occupier == NULL) { 1159 color = GroundColor[(*this)[cell].Land_Type()]; 1160 LogicPage->Put_Pixel(D_BORD_X1 + Cell_X(cell) + 1, D_BORD_Y1 + Cell_Y(cell) + 1, color); 1161 } 1162 } 1163 1164 /* 1165 ** Draw the actual map location 1166 */ 1167 LogicPage->Draw_Rect(map_x1, map_y1, map_x2, map_y2, WHITE); 1168 switch (grabbed) { 1169 case 1: 1170 LogicPage->Draw_Line(map_x1, map_y1, map_x1 + 5, map_y1, BLUE); 1171 LogicPage->Draw_Line(map_x1, map_y1, map_x1, map_y1 + 5, BLUE); 1172 break; 1173 1174 case 2: 1175 LogicPage->Draw_Line(map_x2, map_y1, map_x2 - 5, map_y1, BLUE); 1176 LogicPage->Draw_Line(map_x2, map_y1, map_x2, map_y1 + 5, BLUE); 1177 break; 1178 1179 case 3: 1180 LogicPage->Draw_Line(map_x2, map_y2, map_x2 - 5, map_y2, BLUE); 1181 LogicPage->Draw_Line(map_x2, map_y2, map_x2, map_y2 - 5, BLUE); 1182 break; 1183 1184 case 4: 1185 LogicPage->Draw_Line(map_x1, map_y2, map_x1 + 5, map_y2, BLUE); 1186 LogicPage->Draw_Line(map_x1, map_y2, map_x1, map_y2 - 5, BLUE); 1187 break; 1188 1189 case 5: 1190 LogicPage->Draw_Rect(map_x1, map_y1, map_x2, map_y2, BLUE); 1191 break; 1192 1193 default: 1194 break; 1195 } 1196 1197 /* 1198 ** Draw Unit map symbols (Use the radar map color according to 1199 ** that specified in the house type class object. 1200 ** DKGREEN = terrain object 1201 */ 1202 for (cell=0; cell < MAP_CELL_TOTAL; cell++) { 1203 occupier = (*this)[cell].Cell_Occupier(); 1204 if (occupier) { 1205 color = DKGREEN; 1206 if (occupier && occupier->Owner() != HOUSE_NONE) { 1207 color = ColorRemaps[HouseClass::As_Pointer(occupier->Owner())->RemapColor].Color; 1208 } 1209 LogicPage->Put_Pixel(D_BORD_X1 + Cell_X(cell) + 1, D_BORD_Y1 + Cell_Y(cell) + 1, color); 1210 } 1211 } 1212 1213 /* 1214 ** Draw Home location 1215 */ 1216 LogicPage->Put_Pixel(D_BORD_X1 + Cell_X(Scen.Waypoint[WAYPT_HOME]) + 1, D_BORD_Y1 + Cell_Y(Scen.Waypoint[WAYPT_HOME]) + 1, WHITE); 1217 1218 /* 1219 ** Erase old coordinates 1220 */ 1221 // LogicPage->Fill_Rect( D_DIALOG_X + 7, 1222 // D_DIALOG_Y + D_DIALOG_H - D_OK_H - 22, 1223 // D_DIALOG_X + D_DIALOG_W - 7, 1224 // D_DIALOG_Y + D_DIALOG_H - D_OK_H - 22 + 10, BLACK); 1225 1226 /* 1227 ** Draw the coordinates 1228 */ 1229 txt_x = D_DIALOG_X + D_DIALOG_W / 8; 1230 txt_y = D_DIALOG_Y + D_DIALOG_H - D_OK_H - 32; 1231 Fancy_Text_Print("%5d", txt_x, txt_y, GadgetClass::Get_Color_Scheme(), BLACK, TPF_CENTER | TPF_EFNT | TPF_NOSHADOW, map_x1 - D_BORD_X1 - 1); 1232 1233 txt_x += (D_DIALOG_W - 20) / 4; 1234 Fancy_Text_Print("%5d", txt_x, txt_y, GadgetClass::Get_Color_Scheme(), BLACK, TPF_CENTER | TPF_EFNT | TPF_NOSHADOW, map_y1 - D_BORD_Y1 - 1); 1235 1236 txt_x += (D_DIALOG_W - 20) / 4; 1237 Fancy_Text_Print("%5d", txt_x, txt_y, GadgetClass::Get_Color_Scheme(), BLACK, TPF_CENTER | TPF_EFNT | TPF_NOSHADOW, map_x2 - map_x1 + 1); 1238 1239 txt_x += (D_DIALOG_W - 20) / 4; 1240 Fancy_Text_Print("%5d", txt_x, txt_y, GadgetClass::Get_Color_Scheme(), BLACK, TPF_CENTER | TPF_EFNT | TPF_NOSHADOW, map_y2 - map_y1 + 1); 1241 1242 LogicPage->Unlock(); 1243 } 1244 } 1245 1246 Show_Mouse(); 1247 display = REDRAW_NONE; 1248 } 1249 1250 /* 1251 ** Process user input 1252 */ 1253 input = commands->Input(); 1254 1255 /* 1256 ** Normal button processing: This is done when the mouse button is NOT 1257 ** being held down ('grabbed' is 0). 1258 */ 1259 if (grabbed == 0) { 1260 switch (input) { 1261 case (KN_RETURN): 1262 case (BUTTON_OK | KN_BUTTON): 1263 cancel = false; 1264 process = false; 1265 break; 1266 1267 case (KN_ESC): 1268 case (BUTTON_CANCEL | KN_BUTTON): 1269 cancel = true; 1270 process = false; 1271 break; 1272 1273 case KN_LMOUSE: 1274 /* 1275 ** Grab top left 1276 */ 1277 delta1 = abs(Keyboard->MouseQX - map_x1); 1278 delta2 = abs(Keyboard->MouseQY - map_y1); 1279 if (delta1 < 3 && delta2 < 3) { 1280 grabbed = 1; 1281 mx = Keyboard->MouseQX; 1282 my = Keyboard->MouseQY; 1283 display = REDRAW_MAP; 1284 break; 1285 } 1286 1287 /* 1288 ** Grab top right 1289 */ 1290 delta1 = abs(Keyboard->MouseQX - map_x2); 1291 delta2 = abs(Keyboard->MouseQY - map_y1); 1292 if (delta1 < 3 && delta2 < 3) { 1293 grabbed = 2; 1294 mx = Keyboard->MouseQX; 1295 my = Keyboard->MouseQY; 1296 display = REDRAW_MAP; 1297 break; 1298 } 1299 1300 /* 1301 ** Grab bottom right 1302 */ 1303 delta1 = abs(Keyboard->MouseQX - map_x2); 1304 delta2 = abs(Keyboard->MouseQY - map_y2); 1305 if (delta1 < 3 && delta2 < 3) { 1306 grabbed = 3; 1307 mx = Keyboard->MouseQX; 1308 my = Keyboard->MouseQY; 1309 display = REDRAW_MAP; 1310 break; 1311 } 1312 1313 /* 1314 ** Grab bottom left 1315 */ 1316 delta1 = abs(Keyboard->MouseQX - map_x1); 1317 delta2 = abs(Keyboard->MouseQY - map_y2); 1318 if (delta1 < 3 && delta2 < 3) { 1319 grabbed = 4; 1320 mx = Keyboard->MouseQX; 1321 my = Keyboard->MouseQY; 1322 display = REDRAW_MAP; 1323 break; 1324 } 1325 1326 /* 1327 ** Grab the whole map 1328 */ 1329 delta1 = abs(Keyboard->MouseQX - ((map_x1 + map_x2) / 2)); 1330 delta2 = abs(Keyboard->MouseQY - ((map_y1 + map_y2) / 2)); 1331 if (delta1 < (map_x2 - map_x1) / 4 && 1332 delta2 < (map_y2 - map_y1) / 4) { 1333 grabbed = 5; 1334 mx = Keyboard->MouseQX; 1335 my = Keyboard->MouseQY; 1336 display = REDRAW_MAP; 1337 } 1338 break; 1339 1340 default: 1341 break; 1342 } 1343 } else { 1344 1345 /* 1346 ** Mouse motion processing: This is done while the left mouse button IS 1347 ** being held down. 1348 ** - First, check for the button release; if detected, un-grab 1349 ** - Then, handle mouse motion. WWLIB doesn't pass through a KN_MOUSE_MOVE 1350 ** value while the button is being held down, so this case must be 1351 ** trapped as a default. 1352 */ 1353 switch (input) { 1354 case ((int)KN_LMOUSE | (int)KN_RLSE_BIT): 1355 grabbed = 0; 1356 display = REDRAW_MAP; 1357 break; 1358 1359 default: 1360 delta1 = Get_Mouse_X() - mx; 1361 delta2 = Get_Mouse_Y() - my; 1362 if (delta1==0 && delta2==0) { 1363 break; 1364 } 1365 1366 /* 1367 ** Move top left 1368 */ 1369 if (grabbed==1) { 1370 map_x1 += delta1; 1371 if (map_x1 > map_x2 - 2) { 1372 map_x1 = map_x2 - 2; 1373 } else { 1374 if (map_x1 < D_BORD_X1 + 2) { 1375 map_x1 = D_BORD_X1 + 2; 1376 } 1377 } 1378 1379 map_y1 += delta2; 1380 if (map_y1 > map_y2 - 2) { 1381 map_y1 = map_y2 - 2; 1382 } else { 1383 if (map_y1 < D_BORD_Y1 + 2) { 1384 map_y1 = D_BORD_Y1 + 2; 1385 } 1386 } 1387 display = REDRAW_MAP; 1388 mx = Get_Mouse_X(); 1389 my = Get_Mouse_Y(); 1390 } 1391 1392 /* 1393 ** Move top right 1394 */ 1395 if (grabbed==2) { 1396 map_x2 += delta1; 1397 if (map_x2 < map_x1 + 2) { 1398 map_x2 = map_x1 + 2; 1399 } else { 1400 if (map_x2 > D_BORD_X2 - 2) { 1401 map_x2 = D_BORD_X2 - 2; 1402 } 1403 } 1404 1405 map_y1 += delta2; 1406 if (map_y1 > map_y2 - 2) { 1407 map_y1 = map_y2 - 2; 1408 } else { 1409 if (map_y1 < D_BORD_Y1 + 2) { 1410 map_y1 = D_BORD_Y1 + 2; 1411 } 1412 } 1413 display = REDRAW_MAP; 1414 mx = Get_Mouse_X(); 1415 my = Get_Mouse_Y(); 1416 } 1417 1418 /* 1419 ** Move bottom right 1420 */ 1421 if (grabbed==3) { 1422 map_x2 += delta1; 1423 if (map_x2 < map_x1 + 2) { 1424 map_x2 = map_x1 + 2; 1425 } else { 1426 if (map_x2 > D_BORD_X2 - 2) { 1427 map_x2 = D_BORD_X2 - 2; 1428 } 1429 } 1430 1431 map_y2 += delta2; 1432 if (map_y2 < map_y1 + 2) { 1433 map_y2 = map_y1 + 2; 1434 } else { 1435 if (map_y2 > D_BORD_Y2 - 2) { 1436 map_y2 = D_BORD_Y2 - 2; 1437 } 1438 } 1439 display = REDRAW_MAP; 1440 mx = Get_Mouse_X(); 1441 my = Get_Mouse_Y(); 1442 } 1443 1444 /* 1445 ** Move bottom left 1446 */ 1447 if (grabbed==4) { 1448 map_x1 += delta1; 1449 if (map_x1 > map_x2 - 2) { 1450 map_x1 = map_x2 - 2; 1451 } else { 1452 if (map_x1 < D_BORD_X1 + 2) { 1453 map_x1 = D_BORD_X1 + 2; 1454 } 1455 } 1456 1457 map_y2 += delta2; 1458 if (map_y2 < map_y1 + 2) { 1459 map_y2 = map_y1 + 2; 1460 } else { 1461 if (map_y2 > D_BORD_Y2 - 2) { 1462 map_y2 = D_BORD_Y2 - 2; 1463 } 1464 } 1465 display = REDRAW_MAP; 1466 mx = Get_Mouse_X(); 1467 my = Get_Mouse_Y(); 1468 } 1469 1470 /* 1471 ** Move whole map 1472 */ 1473 if (grabbed==5) { 1474 if (map_x1 + delta1 > D_BORD_X1 + 1 && map_x2 + delta1 < D_BORD_X2 - 1) { 1475 map_x1 += delta1; 1476 map_x2 += delta1; 1477 } 1478 1479 if (map_y1 + delta2 > D_BORD_Y1 + 1 && map_y2 + delta2 < D_BORD_Y2 - 1) { 1480 map_y1 += delta2; 1481 map_y2 += delta2; 1482 } 1483 display = REDRAW_MAP; 1484 mx = Get_Mouse_X(); 1485 my = Get_Mouse_Y(); 1486 } 1487 break; 1488 } 1489 } 1490 } 1491 1492 /* 1493 ** Redraw the display 1494 */ 1495 HidPage.Clear(); 1496 Flag_To_Redraw(true); 1497 Render(); 1498 1499 /* 1500 ** If cancel, just return 1501 */ 1502 if (cancel) { 1503 return(-1); 1504 } 1505 1506 /* 1507 ** Save selections 1508 */ 1509 MapCellX = map_x1 - D_BORD_X1 - 1; 1510 MapCellY = map_y1 - D_BORD_Y1 - 1; 1511 MapCellWidth = map_x2 - map_x1 + 1; 1512 MapCellHeight = map_y2 - map_y1 + 1; 1513 1514 /* 1515 ** Clip Home Cell to new map size 1516 */ 1517 if (Cell_X(Scen.Waypoint[WAYPT_HOME]) < MapCellX) { 1518 Scen.Waypoint[WAYPT_HOME] = XY_Cell(MapCellX, Cell_Y(Scen.Waypoint[WAYPT_HOME])); 1519 } 1520 1521 if (Cell_X(Scen.Waypoint[WAYPT_HOME]) > MapCellX + MapCellWidth - 1) { 1522 Scen.Waypoint[WAYPT_HOME] = XY_Cell(MapCellX + MapCellWidth - 1, Cell_Y(Scen.Waypoint[WAYPT_HOME])); 1523 } 1524 1525 if (Cell_Y(Scen.Waypoint[WAYPT_HOME]) < MapCellY) { 1526 Scen.Waypoint[WAYPT_HOME] = XY_Cell(Cell_X(Scen.Waypoint[WAYPT_HOME]), MapCellY); 1527 } 1528 1529 if (Cell_Y(Scen.Waypoint[WAYPT_HOME]) > MapCellY + MapCellHeight - 1) { 1530 Scen.Waypoint[WAYPT_HOME] = XY_Cell(Cell_X(Scen.Waypoint[WAYPT_HOME]), MapCellY + MapCellHeight - 1); 1531 } 1532 1533 return(0); 1534 } 1535 1536 1537 /*************************************************************************** 1538 * MapEditClass::Scenario_Dialog -- scenario global parameters dialog * 1539 * * 1540 * Edits the house specific and general scenario options. * 1541 * * 1542 * * 1543 * INPUT: * 1544 * none. * 1545 * * 1546 * OUTPUT: * 1547 * 0 = OK, -1 = cancel * 1548 * * 1549 * WARNINGS: * 1550 * Uses HIDBUFF. * 1551 * * 1552 * HISTORY: * 1553 * 11/14/1994 BR : Created. * 1554 * 02/13/1996 JLB : Revamped to new system. * 1555 *=========================================================================*/ 1556 int MapEditClass::Scenario_Dialog(void) 1557 { 1558 TheaterType orig_theater = Scen.Theater; // original theater 1559 HousesType house = PlayerPtr->Class->House; 1560 HousesType newhouse = house; 1561 HouseStaticClass hdata[HOUSE_COUNT]; 1562 1563 /* 1564 ** Fill in the house data for each house that exists. 1565 */ 1566 for (HousesType h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { 1567 HouseClass * hptr = HouseClass::As_Pointer(h); 1568 if (hptr) { 1569 hdata[h] = hptr->Control; 1570 } 1571 } 1572 1573 /* 1574 ** Dialog & button dimensions 1575 */ 1576 enum { 1577 D_DIALOG_W = 320 * RESFACTOR, 1578 D_DIALOG_H = 200 * RESFACTOR, 1579 D_DIALOG_X = ((320 * RESFACTOR - D_DIALOG_W) / 2), 1580 D_DIALOG_Y = ((200 * RESFACTOR - D_DIALOG_H) / 2), 1581 1582 D_OK_W = 45, 1583 D_OK_H = 9, 1584 D_OK_X = D_DIALOG_X + 15 * RESFACTOR, 1585 D_OK_Y = D_DIALOG_Y + D_DIALOG_H - 15 * RESFACTOR, 1586 1587 D_CANCEL_W = 45, 1588 D_CANCEL_H = 9, 1589 D_CANCEL_X = D_DIALOG_X + D_DIALOG_W - (D_CANCEL_W+15*RESFACTOR), 1590 D_CANCEL_Y = D_DIALOG_Y + D_DIALOG_H - 15*RESFACTOR 1591 }; 1592 1593 /* 1594 ** Button enumerations: 1595 */ 1596 enum { 1597 LIST_THEATER=100, 1598 BUTTON_DESCRIPTION, 1599 BUTTON_ALLIES, 1600 BUTTON_CONTROL, 1601 BUTTON_SMARTIES, 1602 BUTTON_BASE, 1603 BUTTON_NOSPYPLANE, 1604 BUTTON_INHERIT, 1605 BUTTON_TIMER, 1606 BUTTON_THEME, 1607 BUTTON_RECORD, 1608 BUTTON_EVAC, 1609 BUTTON_MONEYTIB, 1610 BUTTON_TECH, 1611 BUTTON_TRUCKCRATE, 1612 BUTTON_ENDOFGAME, 1613 BUTTON_SKIPSCORE, 1614 BUTTON_ONETIME, 1615 BUTTON_NOMAPSEL, 1616 BUTTON_HOUSE, 1617 BUTTON_CREDITS, 1618 BUTTON_SOURCE, 1619 BUTTON_MAXUNIT, 1620 BUTTON_INTRO, 1621 BUTTON_BRIEFING, 1622 BUTTON_ACTION, 1623 BUTTON_WIN, 1624 BUTTON_LOSE, 1625 BUTTON_OK, 1626 BUTTON_CANCEL, 1627 }; 1628 1629 /* 1630 ** Initialize 1631 */ 1632 Set_Logic_Page(SeenBuff); 1633 1634 ControlClass * commands = NULL; // the button list 1635 1636 /* 1637 ** Theater choice drop down list. 1638 */ 1639 char theatertext[45] = ""; 1640 DropListClass theaterbtn(LIST_THEATER, theatertext, sizeof(theatertext)-1, 1641 TPF_EFNT|TPF_NOSHADOW, 1642 D_DIALOG_X+15*RESFACTOR, D_DIALOG_Y+30, 65, 8*5, 1643 MFCD::Retrieve("EBTN-UP.SHP"), 1644 MFCD::Retrieve("EBTN-DN.SHP")); 1645 for (TheaterType t = THEATER_FIRST; t < THEATER_COUNT; t++) { 1646 theaterbtn.Add_Item(Theaters[t].Name); 1647 } 1648 theaterbtn.Set_Selected_Index(orig_theater); 1649 1650 char description[DESCRIP_MAX] = ""; 1651 strcpy(description, Scen.Description); 1652 EditClass desc(BUTTON_DESCRIPTION, description, sizeof(description), TPF_EFNT|TPF_NOSHADOW, theaterbtn.X+theaterbtn.Width+15, theaterbtn.Y, 160); 1653 1654 /* 1655 ** Button that tells if this scenario should inherit buildings from the previous. 1656 */ 1657 CheckBoxClass inherit(BUTTON_INHERIT, theaterbtn.X+theaterbtn.Width+15+250, theaterbtn.Y); 1658 if (Scen.IsToInherit) { 1659 inherit.Turn_On(); 1660 } else { 1661 inherit.Turn_Off(); 1662 } 1663 1664 /* 1665 ** Records scenario disposition into holding slot. 1666 */ 1667 CheckBoxClass record(BUTTON_RECORD, inherit.X, inherit.Y+8); 1668 if (Scen.IsToCarryOver) { 1669 record.Turn_On(); 1670 } else { 1671 record.Turn_Off(); 1672 } 1673 1674 /* 1675 ** Should Tanya/civilian be automatically evacuated? 1676 */ 1677 CheckBoxClass tanya(BUTTON_EVAC, record.X, record.Y+8); 1678 if (Scen.IsTanyaEvac) { 1679 tanya.Turn_On(); 1680 } else { 1681 tanya.Turn_Off(); 1682 } 1683 1684 /* 1685 ** End of game with with scenario? 1686 */ 1687 CheckBoxClass endofgame(BUTTON_ENDOFGAME, tanya.X, tanya.Y+8); 1688 if (Scen.IsEndOfGame) { 1689 endofgame.Turn_On(); 1690 } else { 1691 endofgame.Turn_Off(); 1692 } 1693 1694 /* 1695 ** Timer inherit logic. 1696 */ 1697 CheckBoxClass timercarry(BUTTON_TIMER, endofgame.X, endofgame.Y+8); 1698 if (Scen.IsInheritTimer) { 1699 timercarry.Turn_On(); 1700 } else { 1701 timercarry.Turn_Off(); 1702 } 1703 1704 /* 1705 ** Disable spy plane option? 1706 */ 1707 CheckBoxClass nospyplane(BUTTON_NOSPYPLANE, timercarry.X, timercarry.Y+8); 1708 if (Scen.IsNoSpyPlane) { 1709 nospyplane.Turn_On(); 1710 } else { 1711 nospyplane.Turn_Off(); 1712 } 1713 1714 /* 1715 ** Skip the score screen? 1716 */ 1717 CheckBoxClass skipscore(BUTTON_SKIPSCORE, nospyplane.X, nospyplane.Y+8); 1718 if (Scen.IsSkipScore) { 1719 skipscore.Turn_On(); 1720 } else { 1721 skipscore.Turn_Off(); 1722 } 1723 1724 /* 1725 ** Skip the map selection screen for next mission. Presume goes to 1726 ** variation "B"? 1727 */ 1728 CheckBoxClass nomapsel(BUTTON_NOMAPSEL, skipscore.X, skipscore.Y+8); 1729 if (Scen.IsNoMapSel) { 1730 nomapsel.Turn_On(); 1731 } else { 1732 nomapsel.Turn_Off(); 1733 } 1734 1735 /* 1736 ** Return to main menu after mission completes? 1737 */ 1738 CheckBoxClass onetime(BUTTON_ONETIME, nomapsel.X, nomapsel.Y+8); 1739 if (Scen.IsOneTimeOnly) { 1740 onetime.Turn_On(); 1741 } else { 1742 onetime.Turn_Off(); 1743 } 1744 1745 /* 1746 ** Trucks carry a wood crate? 1747 */ 1748 CheckBoxClass truckcrate(BUTTON_TRUCKCRATE, onetime.X, onetime.Y+8); 1749 if (Scen.IsTruckCrate) { 1750 truckcrate.Turn_On(); 1751 } else { 1752 truckcrate.Turn_Off(); 1753 } 1754 1755 /* 1756 ** Transfer credits into tiberium storage at scenario start? 1757 */ 1758 CheckBoxClass moneytib(BUTTON_MONEYTIB, truckcrate.X, truckcrate.Y+8); 1759 if (Scen.IsMoneyTiberium) { 1760 moneytib.Turn_On(); 1761 } else { 1762 moneytib.Turn_Off(); 1763 } 1764 1765 /* 1766 ** Intro movie name. 1767 */ 1768 char introtext[_MAX_FNAME+_MAX_EXT]; 1769 DropListClass intro(BUTTON_INTRO, introtext, sizeof(introtext), 1770 TPF_EFNT|TPF_NOSHADOW, 1771 theaterbtn.X, theaterbtn.Y+theaterbtn.Height+24, 50, 7*10, 1772 MFCD::Retrieve("EBTN-UP.SHP"), 1773 MFCD::Retrieve("EBTN-DN.SHP")); 1774 intro.Add_Item("<none>"); 1775 for (VQType v = VQ_FIRST; v < VQ_COUNT; v++) { 1776 intro.Add_Item(VQName[v]); 1777 } 1778 intro.Set_Selected_Index((int)Scen.IntroMovie + 1); 1779 1780 /* 1781 ** Briefing movie name. 1782 */ 1783 char brieftext[_MAX_FNAME+_MAX_EXT]; 1784 DropListClass briefing(BUTTON_BRIEFING, brieftext, sizeof(brieftext), 1785 TPF_EFNT|TPF_NOSHADOW, 1786 intro.X+intro.Width+10, intro.Y, 50, 7*10, 1787 MFCD::Retrieve("EBTN-UP.SHP"), 1788 MFCD::Retrieve("EBTN-DN.SHP")); 1789 briefing.Add_Item("<none>"); 1790 for (v = VQ_FIRST; v < VQ_COUNT; v++) { 1791 briefing.Add_Item(VQName[v]); 1792 } 1793 briefing.Set_Selected_Index((int)Scen.BriefMovie + 1); 1794 1795 char actiontext[_MAX_FNAME+_MAX_EXT]; 1796 DropListClass action(BUTTON_ACTION, actiontext, sizeof(actiontext), 1797 TPF_EFNT|TPF_NOSHADOW, 1798 briefing.X+briefing.Width+10, briefing.Y, 50, 7*10, 1799 MFCD::Retrieve("EBTN-UP.SHP"), 1800 MFCD::Retrieve("EBTN-DN.SHP")); 1801 action.Add_Item("<none>"); 1802 for (v = VQ_FIRST; v < VQ_COUNT; v++) { 1803 action.Add_Item(VQName[v]); 1804 } 1805 action.Set_Selected_Index((int)Scen.ActionMovie + 1); 1806 1807 char wintext[_MAX_FNAME+_MAX_EXT]; 1808 DropListClass win(BUTTON_WIN, wintext, sizeof(wintext), 1809 TPF_EFNT|TPF_NOSHADOW, 1810 action.X+action.Width+10, action.Y, 50, 7*10, 1811 MFCD::Retrieve("EBTN-UP.SHP"), 1812 MFCD::Retrieve("EBTN-DN.SHP")); 1813 win.Add_Item("<none>"); 1814 for (v = VQ_FIRST; v < VQ_COUNT; v++) { 1815 win.Add_Item(VQName[v]); 1816 } 1817 win.Set_Selected_Index((int)Scen.WinMovie + 1); 1818 1819 char losetext[_MAX_FNAME+_MAX_EXT]; 1820 DropListClass lose(BUTTON_LOSE, losetext, sizeof(losetext), 1821 TPF_EFNT|TPF_NOSHADOW, 1822 win.X+win.Width+10, win.Y, 50, 7*10, 1823 MFCD::Retrieve("EBTN-UP.SHP"), 1824 MFCD::Retrieve("EBTN-DN.SHP")); 1825 lose.Add_Item("<none>"); 1826 for (v = VQ_FIRST; v < VQ_COUNT; v++) { 1827 lose.Add_Item(VQName[v]); 1828 } 1829 lose.Set_Selected_Index((int)Scen.LoseMovie + 1); 1830 1831 /* 1832 ** House choice list. 1833 */ 1834 ListClass housebtn(BUTTON_HOUSE, 1835 D_DIALOG_X+15*RESFACTOR, D_DIALOG_Y+105, 55, 7*10, 1836 TPF_EFNT|TPF_NOSHADOW, 1837 MFCD::Retrieve("EBTN-UP.SHP"), 1838 MFCD::Retrieve("EBTN-DN.SHP")); 1839 for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { 1840 housebtn.Add_Item(HouseTypeClass::As_Reference(h).IniName); 1841 } 1842 housebtn.Set_Selected_Index(PlayerPtr->Class->House); 1843 1844 /* 1845 ** Base house choice drop down list. 1846 */ 1847 char basetext[35]; 1848 DropListClass basebtn(BUTTON_BASE, basetext, sizeof(basetext), 1849 TPF_EFNT|TPF_NOSHADOW, 1850 D_DIALOG_X+15*RESFACTOR, D_DIALOG_Y+80, 65, 7*10, 1851 MFCD::Retrieve("EBTN-UP.SHP"), 1852 MFCD::Retrieve("EBTN-DN.SHP")); 1853 for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { 1854 basebtn.Add_Item(HouseTypeClass::As_Reference(h).IniName); 1855 } 1856 if (Base.House != HOUSE_NONE) { 1857 basebtn.Set_Selected_Index(Base.House); 1858 } 1859 1860 /* 1861 ** Opening scenario theme. 1862 */ 1863 char themetext[65]; 1864 DropListClass themebtn(BUTTON_THEME, themetext, sizeof(themetext), 1865 TPF_EFNT|TPF_NOSHADOW, 1866 basebtn.X+basebtn.Width+15*RESFACTOR, basebtn.Y, 85, 7*10, 1867 MFCD::Retrieve("EBTN-UP.SHP"), 1868 MFCD::Retrieve("EBTN-DN.SHP")); 1869 themebtn.Add_Item("<none>"); 1870 for (ThemeType th = THEME_FIRST; th < THEME_COUNT; th++) { 1871 themebtn.Add_Item(Theme.Full_Name(th)); 1872 } 1873 if (Scen.TransitTheme != THEME_NONE) { 1874 themebtn.Set_Selected_Index(Scen.TransitTheme+1); 1875 } else { 1876 themebtn.Set_Selected_Index(0); 1877 } 1878 1879 /* 1880 ** Build level (technology). 1881 */ 1882 SliderClass techlevel(BUTTON_TECH, housebtn.X+housebtn.Width+15, housebtn.Y, 100, 8); 1883 techlevel.Set_Maximum(16); 1884 1885 char statictechbuff[15]; 1886 StaticButtonClass techstatic(0, "999", TPF_EFNT|TPF_NOSHADOW, techlevel.X+techlevel.Width-20, techlevel.Y-7); 1887 1888 /* 1889 ** Starting credits. 1890 */ 1891 SliderClass creditbtn(BUTTON_CREDITS, housebtn.X+housebtn.Width+15, techlevel.Y+20, 100, 8); 1892 creditbtn.Set_Maximum(201); 1893 1894 char staticcreditbuff[15]; 1895 StaticButtonClass creditstatic(0, "999999999", TPF_EFNT|TPF_NOSHADOW, creditbtn.X+creditbtn.Width-50, creditbtn.Y-7); 1896 1897 /* 1898 ** Maximum unit/infantry slider. 1899 */ 1900 SliderClass maxunit(BUTTON_MAXUNIT, housebtn.X+housebtn.Width+15, creditbtn.Y+20, 100, 8); 1901 maxunit.Set_Maximum(501); 1902 1903 char staticmaxunitbuff[15]; 1904 StaticButtonClass maxunitstatic(0, "999999", TPF_EFNT|TPF_NOSHADOW, maxunit.X+maxunit.Width-30, maxunit.Y-7); 1905 1906 /* 1907 ** Source of ground delivery reinforcements. 1908 */ 1909 char sourcetext[25] = ""; 1910 ListClass sourcebtn(BUTTON_SOURCE, 1911 housebtn.X+housebtn.Width+15, maxunit.Y+20, 100, 7*4, 1912 TPF_EFNT|TPF_NOSHADOW, 1913 MFCD::Retrieve("EBTN-UP.SHP"), 1914 MFCD::Retrieve("EBTN-DN.SHP")); 1915 for (SourceType source = SOURCE_FIRST; source <= SOURCE_WEST; source++) { 1916 sourcebtn.Add_Item(SourceName[source]); 1917 } 1918 1919 /* 1920 ** Smartness lider. 1921 */ 1922 SliderClass smarties(BUTTON_SMARTIES, sourcebtn.X, sourcebtn.Y+sourcebtn.Height+15, 35, 8); 1923 smarties.Set_Maximum(Rule.MaxIQ+1); 1924 1925 char staticsmartiesbuff[15]; 1926 StaticButtonClass smartiesstatic(0, "9999", TPF_EFNT|TPF_NOSHADOW, smarties.X+smarties.Width-20, smarties.Y-7); 1927 1928 /* 1929 ** List box of who is allied with whom. 1930 */ 1931 CheckListClass allies(BUTTON_ALLIES, 1932 techlevel.X+techlevel.Width+5, housebtn.Y, 65, 7*10, 1933 TPF_EFNT|TPF_NOSHADOW, 1934 MFCD::Retrieve("EBTN-UP.SHP"), 1935 MFCD::Retrieve("EBTN-DN.SHP")); 1936 for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { 1937 allies.Add_Item(HouseTypeClass::As_Reference(h).IniName); 1938 if (hdata[house].Allies & (1L << h)) { 1939 allies.Check_Item(h, true); 1940 } 1941 } 1942 allies.Set_Selected_Index(0); 1943 1944 /* 1945 ** List box of who the player can control. 1946 */ 1947 CheckListClass control(BUTTON_CONTROL, 1948 allies.X+allies.Width+10, housebtn.Y, 65, 7*10, 1949 TPF_EFNT|TPF_NOSHADOW, 1950 MFCD::Retrieve("EBTN-UP.SHP"), 1951 MFCD::Retrieve("EBTN-DN.SHP")); 1952 for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { 1953 control.Add_Item(HouseTypeClass::As_Reference(h).IniName); 1954 if (HouseClass::As_Pointer(h)->IsPlayerControl) { 1955 control.Check_Item(h, true); 1956 } 1957 } 1958 control.Set_Selected_Index(0); 1959 1960 /* 1961 ** Create the ubiquitous "ok" and "cancel" buttons. 1962 */ 1963 TextButtonClass okbtn(BUTTON_OK, TXT_OK, TPF_EBUTTON, D_OK_X, D_OK_Y, D_OK_W, D_OK_H); 1964 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_EBUTTON, D_CANCEL_X, D_CANCEL_Y, D_CANCEL_W, D_CANCEL_H); 1965 1966 /* 1967 ** Create the list 1968 */ 1969 commands = &okbtn; 1970 cancelbtn.Add_Tail(*commands); 1971 theaterbtn.Add_Tail(*commands); 1972 themebtn.Add_Tail(*commands); 1973 housebtn.Add_Tail(*commands); 1974 techlevel.Add_Tail(*commands); 1975 techstatic.Add_Tail(*commands); 1976 sourcebtn.Add_Tail(*commands); 1977 creditbtn.Add_Tail(*commands); 1978 creditstatic.Add_Tail(*commands); 1979 maxunitstatic.Add_Tail(*commands); 1980 moneytib.Add_Tail(*commands); 1981 smartiesstatic.Add_Tail(*commands); 1982 allies.Add_Tail(*commands); 1983 control.Add_Tail(*commands); 1984 maxunit.Add_Tail(*commands); 1985 nospyplane.Add_Tail(*commands); 1986 skipscore.Add_Tail(*commands); 1987 nomapsel.Add_Tail(*commands); 1988 onetime.Add_Tail(*commands); 1989 inherit.Add_Tail(*commands); 1990 timercarry.Add_Tail(*commands); 1991 tanya.Add_Tail(*commands); 1992 record.Add_Tail(*commands); 1993 truckcrate.Add_Tail(*commands); 1994 endofgame.Add_Tail(*commands); 1995 briefing.Add_Tail(*commands); 1996 intro.Add_Tail(*commands); 1997 action.Add_Tail(*commands); 1998 win.Add_Tail(*commands); 1999 lose.Add_Tail(*commands); 2000 basebtn.Add_Tail(*commands); 2001 smarties.Add_Tail(*commands); 2002 desc.Add_Tail(*commands); 2003 2004 /* 2005 ** Main Processing Loop 2006 */ 2007 bool housechange = true; 2008 bool display = true; 2009 bool process = true; 2010 bool cancel = false; // true = user cancels 2011 bool dotext = true; // display the text. 2012 bool fetch = false; // Fetch data from dialog into tracking structure. 2013 //Set_Logic_Page(SeenBuff); 2014 while (process) { 2015 2016 /* 2017 ** Invoke game callback 2018 */ 2019 Call_Back(); 2020 2021 /* 2022 ** If the house changes, then all the gadgets that reflect the settings of the 2023 ** house should change as well. 2024 */ 2025 if (housechange) { 2026 HouseStaticClass * hstatic = &hdata[newhouse]; 2027 creditbtn.Set_Value(hstatic->InitialCredits/100); 2028 techlevel.Set_Value(hstatic->TechLevel); 2029 sourcebtn.Set_Selected_Index(hstatic->Edge); 2030 maxunit.Set_Value(hstatic->MaxUnit + hstatic->MaxInfantry); 2031 for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { 2032 allies.Check_Item(h, hstatic->Allies & (1L << h)); 2033 } 2034 smarties.Set_Value(hstatic->IQ); 2035 2036 house = newhouse; 2037 housechange = false; 2038 display = true; 2039 } 2040 2041 /* 2042 ** Refresh display if needed 2043 */ 2044 if (display) { 2045 Hide_Mouse(); 2046 2047 /* 2048 ** Draw the background 2049 */ 2050 Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); 2051 Draw_Caption(TXT_SCENARIO_OPTIONS, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); 2052 2053 /* 2054 ** Display the text that doesn't need drawing except when the entire dialog 2055 ** needs to be redrawn. 2056 */ 2057 Fancy_Text_Print("Tech Level =", techlevel.X, techlevel.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2058 Fancy_Text_Print("Credits =", creditbtn.X, creditbtn.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2059 Fancy_Text_Print("Unit Max =", maxunit.X, maxunit.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2060 Fancy_Text_Print("IQ =", smarties.X, smarties.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2061 Fancy_Text_Print("Prebuild Base:", basebtn.X, basebtn.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2062 Fancy_Text_Print("Theater:", theaterbtn.X, theaterbtn.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2063 Fancy_Text_Print("Scenario Name:", desc.X, desc.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2064 Fancy_Text_Print("Country:", housebtn.X, housebtn.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2065 Fancy_Text_Print("Home Edge:", sourcebtn.X, sourcebtn.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2066 Fancy_Text_Print("Allies:", allies.X, allies.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2067 Fancy_Text_Print("Plyr Control:", control.X, control.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2068 Fancy_Text_Print("Theme:", themebtn.X, themebtn.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2069 Fancy_Text_Print("Intro:", intro.X, intro.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2070 Fancy_Text_Print("Briefing:", briefing.X, briefing.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2071 Fancy_Text_Print("Action:", action.X, action.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2072 Fancy_Text_Print("Win:", win.X, win.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2073 Fancy_Text_Print("Lose:", lose.X, lose.Y-7, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2074 Fancy_Text_Print("Store scenario?", record.X+10, record.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2075 Fancy_Text_Print("Inherit stored scenario?", inherit.X+10, inherit.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2076 Fancy_Text_Print("Auto evac. Tanya (civilian)?", tanya.X+10, tanya.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2077 Fancy_Text_Print("Last mission of game?", endofgame.X+10, endofgame.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2078 Fancy_Text_Print("Inherit mission timer from last scenario?", timercarry.X+10, timercarry.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2079 Fancy_Text_Print("Disable spy plane?", nospyplane.X+10, nospyplane.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2080 Fancy_Text_Print("Skip the score screen?", skipscore.X+10, skipscore.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2081 Fancy_Text_Print("No map selection (force var 'B')?", nomapsel.X+10, nomapsel.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2082 Fancy_Text_Print("Return to main menu after scenario finishes?", onetime.X+10, onetime.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2083 Fancy_Text_Print("Truck carries wood crate?", truckcrate.X+10, truckcrate.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2084 Fancy_Text_Print("Initial money is transferred to silos?", moneytib.X+10, moneytib.Y, GadgetClass::Get_Color_Scheme(), TBLACK, TPF_EFNT|TPF_NOSHADOW); 2085 2086 theaterbtn.Collapse(); 2087 themebtn.Collapse(); 2088 intro.Collapse(); 2089 briefing.Collapse(); 2090 action.Collapse(); 2091 win.Collapse(); 2092 lose.Collapse(); 2093 basebtn.Collapse(); 2094 commands->Draw_All(true); 2095 Show_Mouse(); 2096 display = false; 2097 dotext = true; 2098 } 2099 2100 /* 2101 ** Display the text of the buttons that could change their text as a 2102 ** result of slider interaction. 2103 */ 2104 if (dotext) { 2105 dotext = false; 2106 Hide_Mouse(); 2107 2108 sprintf(statictechbuff, "%2d", techlevel.Get_Value()); 2109 techstatic.Set_Text(statictechbuff); 2110 techstatic.Draw_Me(); 2111 2112 sprintf(staticcreditbuff, "$%-7d", creditbtn.Get_Value() * 100); 2113 creditstatic.Set_Text(staticcreditbuff); 2114 creditstatic.Draw_Me(); 2115 2116 sprintf(staticmaxunitbuff, "%4d", maxunit.Get_Value()); 2117 maxunitstatic.Set_Text(staticmaxunitbuff); 2118 maxunitstatic.Draw_Me(); 2119 2120 sprintf(staticsmartiesbuff, "%2d", smarties.Get_Value()); 2121 smartiesstatic.Set_Text(staticsmartiesbuff); 2122 smartiesstatic.Draw_Me(); 2123 2124 Show_Mouse(); 2125 } 2126 2127 /* 2128 ** Get user input 2129 */ 2130 KeyNumType input = commands->Input(); 2131 2132 /* 2133 ** Process input 2134 */ 2135 switch (input) { 2136 case BUTTON_ALLIES|KN_BUTTON: 2137 allies.Check_Item(house, true); 2138 break; 2139 2140 case BUTTON_CONTROL|KN_BUTTON: 2141 control.Check_Item(house, true); 2142 break; 2143 2144 case BUTTON_THEME|KN_BUTTON: 2145 case BUTTON_INTRO|KN_BUTTON: 2146 case BUTTON_BRIEFING|KN_BUTTON: 2147 case BUTTON_ACTION|KN_BUTTON: 2148 case BUTTON_WIN|KN_BUTTON: 2149 case BUTTON_LOSE|KN_BUTTON: 2150 case BUTTON_BASE|KN_BUTTON: 2151 case LIST_THEATER|KN_BUTTON: 2152 briefing.Collapse(); 2153 action.Collapse(); 2154 win.Collapse(); 2155 themebtn.Collapse(); 2156 intro.Collapse(); 2157 lose.Collapse(); 2158 basebtn.Collapse(); 2159 theaterbtn.Collapse(); 2160 display = true; 2161 break; 2162 2163 case BUTTON_SMARTIES|KN_BUTTON: 2164 case BUTTON_MAXUNIT|KN_BUTTON: 2165 case BUTTON_CREDITS|KN_BUTTON: 2166 case BUTTON_TECH|KN_BUTTON: 2167 briefing.Collapse(); 2168 action.Collapse(); 2169 win.Collapse(); 2170 lose.Collapse(); 2171 basebtn.Collapse(); 2172 themebtn.Collapse(); 2173 theaterbtn.Collapse(); 2174 dotext = true; 2175 break; 2176 2177 case BUTTON_HOUSE|KN_BUTTON: 2178 newhouse = HousesType(housebtn.Current_Index()); 2179 housechange = true; 2180 briefing.Collapse(); 2181 action.Collapse(); 2182 themebtn.Collapse(); 2183 win.Collapse(); 2184 intro.Collapse(); 2185 lose.Collapse(); 2186 basebtn.Collapse(); 2187 theaterbtn.Collapse(); 2188 fetch = true; 2189 break; 2190 2191 case (KN_RETURN): 2192 case (BUTTON_OK | KN_BUTTON): 2193 cancel = false; 2194 process = false; 2195 fetch = true; 2196 break; 2197 2198 case (KN_ESC): 2199 case (BUTTON_CANCEL | KN_BUTTON): 2200 cancel = true; 2201 process = false; 2202 break; 2203 2204 default: 2205 break; 2206 } 2207 2208 2209 /* 2210 ** If the house changes, then all the gadgets that reflect the settings of the 2211 ** house should change as well. 2212 */ 2213 if (fetch) { 2214 fetch = false; 2215 HouseStaticClass * hstatic = &hdata[house]; 2216 2217 Base.House = HousesType(basebtn.Current_Index()); 2218 hstatic->InitialCredits = creditbtn.Get_Value() * 100; 2219 hstatic->Edge = SourceType(sourcebtn.Current_Index()); 2220 hstatic->TechLevel = techlevel.Get_Value(); 2221 hstatic->MaxUnit = maxunit.Get_Value()/2; 2222 hstatic->MaxInfantry = maxunit.Get_Value()/2; 2223 hstatic->IQ = smarties.Get_Value(); 2224 for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { 2225 if (allies.Is_Checked(h)) { 2226 hstatic->Allies |= (1L << h); 2227 } else { 2228 hstatic->Allies &= ~(1L << h); 2229 } 2230 } 2231 } 2232 } 2233 2234 /* 2235 ** Redraw the map 2236 */ 2237 HidPage.Clear(); 2238 Flag_To_Redraw(true); 2239 Render(); 2240 2241 /* 2242 ** If cancel, just return 2243 */ 2244 if (cancel) { 2245 return(-1); 2246 } 2247 2248 /* 2249 ** Copy the dialog data back into the appropriate game data locations. 2250 */ 2251 for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) { 2252 HouseClass * hptr = HouseClass::As_Pointer(h); 2253 if (hptr != NULL) { 2254 hptr->Control = hdata[h]; 2255 hptr->Allies = hdata[h].Allies; 2256 2257 if (control.Is_Checked(h)) { 2258 hptr->IsPlayerControl = true; 2259 } else { 2260 hptr->IsPlayerControl = false; 2261 } 2262 } 2263 } 2264 PlayerPtr->IsPlayerControl = true; 2265 strncpy(Scen.Description, desc.Get_Text(), sizeof(Scen.Description)); 2266 Scen.Description[sizeof(Scen.Description)-1] = '\0'; 2267 Scen.IntroMovie = VQType(intro.Current_Index()-1); 2268 Scen.BriefMovie = VQType(briefing.Current_Index()-1); 2269 Scen.ActionMovie = VQType(action.Current_Index()-1); 2270 Scen.WinMovie = VQType(win.Current_Index()-1); 2271 Scen.LoseMovie = VQType(lose.Current_Index()-1); 2272 Scen.IsToInherit = inherit.IsOn; 2273 Scen.IsToCarryOver = record.IsOn; 2274 Scen.IsTanyaEvac = tanya.IsOn; 2275 Scen.IsEndOfGame = endofgame.IsOn; 2276 Scen.IsInheritTimer = timercarry.IsOn; 2277 Scen.IsNoSpyPlane = nospyplane.IsOn; 2278 Scen.IsSkipScore = skipscore.IsOn; 2279 Scen.IsNoMapSel = nomapsel.IsOn; 2280 Scen.IsOneTimeOnly = onetime.IsOn; 2281 Scen.IsTruckCrate = truckcrate.IsOn; 2282 Scen.IsMoneyTiberium = moneytib.IsOn; 2283 Scen.TransitTheme = ThemeType(themebtn.Current_Index()-1); 2284 2285 /* 2286 ** Change the theater: 2287 ** - 1st set the Theater global 2288 ** - scan all cells to check their TType for compatibility with the new 2289 ** theater; if not compatible, set TType to TEMPLATE_NONE & TIcon to 0 2290 ** - Then, re-initialize the TypeClasses for the new Theater 2291 */ 2292 TheaterType theater = TheaterType(theaterbtn.Current_Index()); 2293 if (theater != orig_theater) { 2294 2295 unsigned char theater_mask; // template/terrain mask 2296 TerrainClass * terrain; // cell's terrain pointer 2297 2298 /* 2299 ** Loop through all cells 2300 */ 2301 for (CELL i = 0; i < MAP_CELL_TOTAL; i++) { 2302 2303 /* 2304 ** If this cell has a template icon & that template isn't compatible 2305 ** with this theater, set the icon to NONE 2306 */ 2307 if ((*this)[i].TType != TEMPLATE_NONE) { 2308 theater_mask = TemplateTypeClass::As_Reference((*this)[i].TType).Theater; 2309 if ( (theater_mask & (1 << theater))==0) { 2310 (*this)[i].TType = TEMPLATE_NONE; 2311 (*this)[i].TIcon = 0; 2312 } 2313 } 2314 2315 /* 2316 ** If this cell has terrain in it, and that terrain isn't compatible 2317 ** with this theater, delete the terrain object. 2318 */ 2319 terrain = (*this)[i].Cell_Terrain(); 2320 if (terrain != NULL) { 2321 theater_mask = terrain->Class->Theater; 2322 if ( (theater_mask & (1<<theater))==0) { 2323 delete terrain; 2324 } 2325 } 2326 } 2327 2328 /* 2329 ** Remove any old theater specific uncompressed shapes 2330 */ 2331 #ifdef WIN32 2332 Reset_Theater_Shapes(); 2333 #endif //WIN32 2334 /* 2335 ** Force shapes to reload 2336 */ 2337 LastTheater = THEATER_NONE; 2338 2339 /* 2340 ** Re-init the object Type Classes for this theater 2341 */ 2342 Init_Theater(theater); 2343 TerrainTypeClass::Init(theater); 2344 TemplateTypeClass::Init(theater); 2345 OverlayTypeClass::Init(theater); 2346 UnitTypeClass::Init(theater); 2347 InfantryTypeClass::Init(theater); 2348 BuildingTypeClass::Init(theater); 2349 BulletTypeClass::Init(theater); 2350 AnimTypeClass::Init(theater); 2351 AircraftTypeClass::Init(theater); 2352 VesselTypeClass::Init(theater); 2353 SmudgeTypeClass::Init(theater); 2354 2355 // LastTheater = theater; 2356 } 2357 2358 return(0); 2359 } 2360 2361 2362 /*************************************************************************** 2363 * Handle_Triggers -- processes the trigger dialogs * 2364 * * 2365 * INPUT: * 2366 * none. * 2367 * * 2368 * OUTPUT: * 2369 * none. * 2370 * * 2371 * WARNINGS: * 2372 * none. * 2373 * * 2374 * HISTORY: * 2375 * 11/29/1994 BR : Created. * 2376 *=========================================================================*/ 2377 void MapEditClass::Handle_Triggers(void) 2378 { 2379 int rc; 2380 2381 /* 2382 ** Trigger dialog processing loop: 2383 ** - Invoke the trigger selection dialog. If a trigger's selected, break 2384 ** & return 2385 ** - If user wants to edit the current trigger, do so 2386 ** - If user wants to create new trigger, new a TriggerClass & edit it 2387 ** - If user wants to delete trigger, delete the current trigger 2388 ** - Keep looping until 'OK' 2389 */ 2390 while (1) { 2391 2392 /* 2393 ** Select trigger 2394 */ 2395 rc = Select_Trigger(); 2396 2397 /* 2398 ** 'OK'; break 2399 */ 2400 if (rc==0) break; 2401 2402 /* 2403 ** 'Edit' 2404 */ 2405 if (rc==1 && CurTrigger) { 2406 if (CurTrigger->Edit()) { 2407 Changed = 1; 2408 } 2409 HidPage.Clear(); 2410 Flag_To_Redraw(true); 2411 Render(); 2412 } 2413 2414 /* 2415 ** 'New' 2416 */ 2417 if (rc==2) { 2418 2419 /* 2420 ** Create a new trigger 2421 */ 2422 CurTrigger = new TriggerTypeClass(); 2423 if (CurTrigger) { 2424 2425 /* 2426 ** delete it if user cancels 2427 */ 2428 if (!CurTrigger->Edit()) { 2429 delete CurTrigger; 2430 CurTrigger = NULL; 2431 } else { 2432 Changed = 1; 2433 } 2434 HidPage.Clear(); 2435 Flag_To_Redraw(true); 2436 Render(); 2437 2438 } else { 2439 2440 /* 2441 ** Unable to create; issue warning 2442 */ 2443 WWMessageBox().Process("No more triggers available."); 2444 HidPage.Clear(); 2445 Flag_To_Redraw(true); 2446 Render(); 2447 } 2448 } 2449 2450 /* 2451 ** 'Delete' 2452 */ 2453 if (rc==3) { 2454 if (CurTrigger) { 2455 Detach_This_From_All(CurTrigger->As_Target(), true); 2456 delete CurTrigger; 2457 //CurTrigger->Remove(); 2458 CurTrigger = NULL; 2459 Changed = 1; 2460 } 2461 } 2462 } 2463 2464 /* 2465 ** Let the CurTrigger global exist if the trigger can be placed on the 2466 ** ground or on a game object. 2467 */ 2468 if (CurTrigger && !(CurTrigger->Attaches_To() & (ATTACH_OBJECT|ATTACH_CELL))) { 2469 CurTrigger = NULL; 2470 } 2471 } 2472 2473 2474 /*************************************************************************** 2475 * MapEditClass::Select_Trigger -- lets user select a trigger * 2476 * * 2477 * CurTrigger can be NULL when this function is called. * 2478 * * 2479 * ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ * 2480 * ³ Triggers ³ * 2481 * ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿ ³ * 2482 * ³ ³ Name Event Action House Team ³³ ³ * 2483 * ³ ³ Name Event Action House Team ÃÄ´ ³ * 2484 * ³ ³ Name Event Action House Team ³ ³ ³ * 2485 * ³ ³ Name Event Action House Team ³ ³ ³ * 2486 * ³ ³ ³ ³ ³ * 2487 * ³ ³ ³ ³ ³ * 2488 * ³ ³ ÃÄ´ ³ * 2489 * ³ ³ ³³ ³ * 2490 * ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ ³ * 2491 * ³ ³ * 2492 * ³ [Edit] [New] [Delete] [OK] ³ * 2493 * ³ ³ * 2494 * ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ * 2495 * * 2496 * INPUT: * 2497 * none. * 2498 * * 2499 * OUTPUT: * 2500 * 0 = OK, 1 = Edit, 2 = New, 3 = Delete * 2501 * * 2502 * WARNINGS: * 2503 * Uses HIDBUFF. * 2504 * * 2505 * HISTORY: * 2506 * 11/29/1994 BR : Created. * 2507 * 05/07/1996 JLB : Streamlined and sort trigger list. * 2508 *=========================================================================*/ 2509 int MapEditClass::Select_Trigger(void) 2510 { 2511 /* 2512 ** Dialog & button dimensions 2513 */ 2514 enum { 2515 D_DIALOG_W = 400, 2516 D_DIALOG_H = 250, 2517 D_DIALOG_X = 0, 2518 D_DIALOG_Y = 0, 2519 2520 D_TXT8_H = 11, 2521 D_MARGIN = 35, 2522 2523 D_LIST_W = (D_DIALOG_W-(D_MARGIN*2))-10, 2524 D_LIST_H = D_DIALOG_H-70, 2525 D_LIST_X = D_DIALOG_X + (D_DIALOG_W-D_LIST_W)/2, 2526 D_LIST_Y = D_DIALOG_Y + 25, 2527 2528 BUTTON_W = 45, 2529 BUTTON_H = 9, 2530 2531 D_EDIT_W = BUTTON_W, 2532 D_EDIT_H = BUTTON_H, 2533 D_EDIT_X = D_DIALOG_X + D_DIALOG_W - (((D_EDIT_W+10)*4)+25), 2534 D_EDIT_Y = D_DIALOG_Y + D_DIALOG_H - 20 - D_EDIT_H, 2535 2536 D_NEW_W = BUTTON_W, 2537 D_NEW_H = BUTTON_H, 2538 D_NEW_X = D_EDIT_X + D_EDIT_W + 10, 2539 D_NEW_Y = D_DIALOG_Y + D_DIALOG_H - 20 - D_NEW_H, 2540 2541 D_DELETE_W = BUTTON_W, 2542 D_DELETE_H = BUTTON_H, 2543 D_DELETE_X = D_NEW_X + D_NEW_W + 10, 2544 D_DELETE_Y = D_DIALOG_Y + D_DIALOG_H - 20 - D_DELETE_H, 2545 2546 D_OK_W = BUTTON_W, 2547 D_OK_H = BUTTON_H, 2548 D_OK_X = D_DELETE_X + D_DELETE_W + 10, 2549 D_OK_Y = D_DIALOG_Y + D_DIALOG_H - 20 - D_OK_H, 2550 2551 }; 2552 2553 /* 2554 ** Button enumerations: 2555 */ 2556 enum { 2557 TRIGGER_LIST=100, 2558 BUTTON_EDIT, 2559 BUTTON_NEW, 2560 BUTTON_DELETE, 2561 BUTTON_OK, 2562 }; 2563 2564 /* 2565 ** Dialog variables: 2566 */ 2567 bool edit_trig = false; // true = user wants to edit 2568 bool new_trig = false; // true = user wants to new 2569 bool del_trig = false; // true = user wants to new 2570 int i; // loop counter 2571 2572 /* 2573 ** Buttons 2574 */ 2575 ControlClass * commands = NULL; // the button list 2576 2577 TListClass<CCPtr<TriggerTypeClass> > triggerlist(TRIGGER_LIST, D_LIST_X, D_LIST_Y, D_LIST_W, D_LIST_H, 2578 TPF_EFNT|TPF_NOSHADOW, 2579 MFCD::Retrieve("EBTN-UP.SHP"), 2580 MFCD::Retrieve("EBTN-DN.SHP")); 2581 2582 TextButtonClass editbtn(BUTTON_EDIT, "Edit", TPF_EBUTTON, D_EDIT_X, D_EDIT_Y, D_EDIT_W, D_EDIT_H); 2583 TextButtonClass newbtn(BUTTON_NEW, "New", TPF_EBUTTON, D_NEW_X, D_NEW_Y, D_NEW_W, D_NEW_H); 2584 TextButtonClass deletebtn(BUTTON_DELETE, "Delete", TPF_EBUTTON, D_DELETE_X, D_DELETE_Y, D_DELETE_W, D_DELETE_H); 2585 TextButtonClass okbtn(BUTTON_OK, TXT_OK, TPF_EBUTTON, D_OK_X, D_OK_Y, D_OK_W, D_OK_H); 2586 2587 /* 2588 ** Initialize 2589 */ 2590 Set_Logic_Page(SeenBuff); 2591 2592 /* 2593 ** Fill in the list box 2594 */ 2595 for (i = 0; i < TriggerTypes.Count(); i++) { 2596 triggerlist.Add_Item(TriggerTypes.Ptr(i)); 2597 } 2598 2599 PNBubble_Sort(&triggerlist[0], triggerlist.Count()); 2600 2601 if (CurTrigger) { 2602 triggerlist.Set_Selected_Index(CurTrigger); 2603 } else { 2604 triggerlist.Set_Selected_Index(0); 2605 } 2606 2607 /* 2608 ** Set CurTrigger if it isn't 2609 */ 2610 if (TriggerTypes.Count()==0) { 2611 CurTrigger = NULL; 2612 } else { 2613 CurTrigger = triggerlist.Current_Item(); 2614 // if (!CurTrigger) { 2615 // CurTrigger = &*triggerlist.Current_Item(); 2616 // } 2617 } 2618 2619 /* 2620 ** Create the list 2621 */ 2622 commands = &triggerlist; 2623 editbtn.Add_Tail(*commands); 2624 newbtn.Add_Tail(*commands); 2625 deletebtn.Add_Tail(*commands); 2626 okbtn.Add_Tail(*commands); 2627 2628 /* 2629 ** Main Processing Loop 2630 */ 2631 bool display = true; 2632 bool process = true; 2633 while (process) { 2634 /* 2635 ** Invoke game callback 2636 */ 2637 Call_Back(); 2638 2639 /* 2640 ** Refresh display if requested. 2641 */ 2642 if (display /*&& LogicPage->Lock()*/) { 2643 Hide_Mouse(); 2644 Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); 2645 Draw_Caption(TXT_TRIGGER_EDITOR, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); 2646 commands->Flag_List_To_Redraw(); 2647 commands->Draw_All(); 2648 Show_Mouse(); 2649 display = false; 2650 // LogicPage->Unlock(); 2651 } 2652 2653 /* 2654 ** Get user input 2655 */ 2656 KeyNumType input = commands->Input(); 2657 2658 /* 2659 ** Process input 2660 */ 2661 switch (input) { 2662 case (TRIGGER_LIST | KN_BUTTON): 2663 CurTrigger = &*triggerlist.Current_Item(); 2664 // CurTrigger = (TriggerTypeClass *)&*triggerlist.Current_Item(); 2665 break; 2666 2667 case (BUTTON_EDIT | KN_BUTTON): 2668 if (CurTrigger) { // only allow if there's one selected 2669 process = false; 2670 edit_trig = true; 2671 } 2672 break; 2673 2674 case (BUTTON_NEW | KN_BUTTON): 2675 process = false; 2676 new_trig = true; 2677 break; 2678 2679 case (BUTTON_DELETE | KN_BUTTON): 2680 process = false; 2681 del_trig = true; 2682 break; 2683 2684 case (KN_RETURN): 2685 case (BUTTON_OK | KN_BUTTON): 2686 process = false; 2687 break; 2688 } 2689 } 2690 2691 /* 2692 ** Redraw the display 2693 */ 2694 HidPage.Clear(); 2695 Flag_To_Redraw(true); 2696 Render(); 2697 2698 if (edit_trig) return(1); 2699 if (new_trig) return(2); 2700 if (del_trig) return(3); 2701 return(0); 2702 } 2703 2704 2705 #endif