TRIGTYPE.CPP (81229B)
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/TRIGTYPE.CPP 1 3/03/97 10:26a 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 : TRIGTYPE.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : 06/05/96 * 28 * * 29 * Last Update : July 9, 1996 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * TriggerTypeClass::As_Target -- Convert this trigger type object into a target value. * 34 * TriggerTypeClass::Attaches_To -- Determines what trigger can attach to. * 35 * TriggerTypeClass::Build_INI_Entry -- Construct the INI entry into the buffer specified. * 36 * TriggerTypeClass::Description -- Build a text description of the trigger type. * 37 * TriggerTypeClass::Detach -- Removes attachments to the target object specified. * 38 * TriggerTypeClass::Draw_It -- Draws this trigger as if it were a line in a list box. * 39 * TriggerTypeClass::Edit -- Edit the trigger type through the scenario editor. * 40 * TriggerTypeClass::Fill_In -- fills in trigger from the given INI entry * 41 * TriggerTypeClass::From_Name -- Convert an ASCII name into a trigger type pointer. * 42 * TriggerTypeClass::Init -- Initialize the trigger type object management system. * 43 * TriggerTypeClass::Read_INI -- reads triggers from the INI file * 44 * TriggerTypeClass::TriggerTypeClass -- Constructor for trigger class object. * 45 * TriggerTypeClass::Write_INI -- Stores all trigger types to the INI database specified. * 46 * TriggerTypeClass::operator delete -- Returns a trigger type class object back to the pool * 47 * TriggerTypeClass::operator new -- Allocates a trigger type class object. * 48 * TriggerTypeClass::~TriggerTypeClass -- Deleting a trigger type deletes associated triggers* 49 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 50 51 52 #include "function.h" 53 #include "trigtype.h" 54 55 56 /*********************************************************************************************** 57 * TriggerTypeClass::TriggerTypeClass -- Constructor for trigger class object. * 58 * * 59 * This is the normal constructor for a trigger object. The trigger starts with no team * 60 * members, no mission, and default values for all settings. * 61 * * 62 * INPUT: none * 63 * * 64 * OUTPUT: none * 65 * * 66 * WARNINGS: none * 67 * * 68 * HISTORY: * 69 * 06/10/1996 JLB : Created. * 70 *=============================================================================================*/ 71 TriggerTypeClass::TriggerTypeClass(void) : 72 AbstractTypeClass(RTTI_TRIGGERTYPE, TriggerTypes.ID(this), TXT_NONE, "x"), 73 IsPersistant(VOLATILE), 74 EventControl(MULTI_ONLY), 75 ActionControl(MULTI_ONLY), 76 House(HOUSE_SPAIN) 77 { 78 } 79 80 81 /*********************************************************************************************** 82 * TriggerTypeClass::~TriggerTypeClass -- Deleting a trigger type deletes associated triggers. * 83 * * 84 * When a trigger type is deleted, then all triggers that refer to that type must also * 85 * be deleted as well. There can be no 'orphan' triggers in existence. * 86 * * 87 * INPUT: none * 88 * * 89 * OUTPUT: none * 90 * * 91 * WARNINGS: none * 92 * * 93 * HISTORY: * 94 * 07/09/1996 JLB : Created. * 95 *=============================================================================================*/ 96 TriggerTypeClass::~TriggerTypeClass(void) 97 { 98 } 99 100 101 /*********************************************************************************************** 102 * TriggerTypeClass::operator new -- Allocates a trigger type class object. * 103 * * 104 * This routine will allocate a block of memory from the special trigger type object * 105 * pool. * 106 * * 107 * INPUT: none * 108 * * 109 * OUTPUT: Returns with a pointer to the allocated trigger type memory block. If there is * 110 * no more block available in the pool, then NULL is returned. * 111 * * 112 * WARNINGS: none * 113 * * 114 * HISTORY: * 115 * 07/09/1996 JLB : Created. * 116 *=============================================================================================*/ 117 void * TriggerTypeClass::operator new(size_t ) 118 { 119 void * ptr = TriggerTypes.Allocate(); 120 if (ptr) { 121 ((TriggerTypeClass *)ptr)->IsActive = true; 122 } 123 124 return(ptr); 125 } 126 127 128 /*********************************************************************************************** 129 * TriggerTypeClass::operator delete -- Returns a trigger type class object back to the pool * 130 * * 131 * This routine will return a previously allocated trigger type object to the private * 132 * memory pool from which it was allocated. * 133 * * 134 * INPUT: ptr -- Pointer to the trigger type class to return to the pool. * 135 * * 136 * OUTPUT: none * 137 * * 138 * WARNINGS: none * 139 * * 140 * HISTORY: * 141 * 07/09/1996 JLB : Created. * 142 *=============================================================================================*/ 143 void TriggerTypeClass::operator delete(void * ptr) 144 { 145 if (ptr) { 146 ((TriggerTypeClass *)ptr)->IsActive = false; 147 } 148 TriggerTypes.Free((TriggerTypeClass *)ptr); 149 } 150 151 152 /*********************************************************************************************** 153 * TriggerTypeClass::As_Target -- Convert this trigger type object into a target value. * 154 * * 155 * Use this routine to take this trigger type class object and convert it into a * 156 * target number. * 157 * * 158 * INPUT: none * 159 * * 160 * OUTPUT: Returns with the target number that represents this trigger type class object. * 161 * * 162 * WARNINGS: none * 163 * * 164 * HISTORY: * 165 * 07/09/1996 JLB : Created. * 166 *=============================================================================================*/ 167 TARGET TriggerTypeClass::As_Target(void) const 168 { 169 return(Build_Target(RTTI_TRIGGERTYPE, ID)); 170 } 171 172 173 /*********************************************************************************************** 174 * TriggerTypeClass::Detach -- Removes attachments to the target object specified. * 175 * * 176 * When an object disappears from the game, it must be detached from all other objects that * 177 * may be referring to it. This routine will detach the specified target object from any * 178 * references to it in this trigger type class. * 179 * * 180 * INPUT: target -- The target object to be detached from this trigger type. * 181 * * 182 * OUTPUT: none * 183 * * 184 * WARNINGS: none * 185 * * 186 * HISTORY: * 187 * 07/09/1996 JLB : Created. * 188 *=============================================================================================*/ 189 void TriggerTypeClass::Detach(TARGET target, bool) 190 { 191 Action1.Detach(target); 192 Action2.Detach(target); 193 } 194 195 196 #ifdef SCENARIO_EDITOR 197 /*********************************************************************************************** 198 * TriggerTypeClass::Edit -- Edit the trigger type through the scenario editor. * 199 * * 200 * This is the scenario editor interface to a trigger type class object. It brings up a * 201 * fancy schmancy dialog to allow full edit control of the trigger type. * 202 * * 203 * INPUT: none * 204 * * 205 * OUTPUT: bool; Was the "OK" button pressed? A false return value indicates that the edits * 206 * to this trigger type class object should be rejected. * 207 * * 208 * WARNINGS: none * 209 * * 210 * HISTORY: * 211 * 07/09/1996 JLB : Created. * 212 *=============================================================================================*/ 213 bool TriggerTypeClass::Edit(void) 214 { 215 enum { 216 /* 217 ** Dialog position and dimensions. 218 */ 219 D_DIALOG_W = 320 + 100, 220 D_DIALOG_H = 200 + 20, 221 D_DIALOG_X = 0, 222 D_DIALOG_Y = 0, 223 224 /* 225 ** Event entry list box coordinates and dimensions. 226 */ 227 E1_X=D_DIALOG_X+45, 228 E1_Y=D_DIALOG_Y+65, 229 E2_X=E1_X, 230 E2_Y=E1_Y+22, 231 E_WIDTH=160, 232 E_HEIGHT=8*5, 233 234 /* 235 ** Event optional data entry coordinates and dimensions. 236 */ 237 ED1_X=E1_X+E_WIDTH+20, 238 ED1_Y=E1_Y, 239 ED2_X=ED1_X, 240 ED2_Y=E2_Y, 241 242 ED_WIDTH=95, 243 ED_HEIGHT=8*5, 244 245 /* 246 ** Action entry list box coordinates. 247 */ 248 A1_X=E1_X, 249 A1_Y=D_DIALOG_Y+120, 250 A2_X=E1_X, 251 A2_Y=A1_Y+22, 252 253 /* 254 ** Action optional data entry coordinates. 255 */ 256 AD1_X=A1_X+E_WIDTH+20, 257 AD1_Y=A1_Y, 258 AD2_X=AD1_X, 259 AD2_Y=A2_Y, 260 261 /* 262 ** Misc control values. 263 */ 264 GENERAL_SIZE=10, // Text length for general data entry fields. 265 ENTRY_SIZE=35, // Maximum size of event or action description text. 266 WAYPOINT_SIZE=3, // Text length maximum for waypoint entry. 267 TEAM_SIZE=10, // Team name text entry field length. 268 DESC_SIZE=35 // Maximum length of object full name description. 269 }; 270 271 /* 272 ** Button enumerations: 273 */ 274 enum { 275 EVENT_LIST=100, // Primary event list. 276 EVENT_LIST2, // Secondary event list. 277 ACTION_LIST, // Primary action list. 278 ACTION_LIST2, // Secondary action list. 279 NAME_EDIT, // Trigger name edit field. 280 DATA_SPEECH1, // Primary action speech. 281 DATA_SPEECH2, // Secondary action speech. 282 DATA_THEME1, // Primary action theme. 283 DATA_THEME2, // Secondary action theme. 284 DATA_MOVIE1, // Primary action movie. 285 DATA_MOVIE2, // Secondary action movie. 286 DATA_SOUND1, // Primary action sound effect. 287 DATA_SOUND2, // Secondary action sound effect. 288 DATA_SPECIAL1, // Primary action special weapon. 289 DATA_SPECIAL2, // Secondary action special weapon. 290 DATA_EDIT, // Primary event waypoint data field. 291 DATA_EDIT2, // Secondary event waypoint data field. 292 DATA_EDIT3, // Primary action waypoint data field. 293 DATA_EDIT4, // Secondary action waypoint data field. 294 DATA_HTYPE1, // Primary event house choice list. 295 DATA_HTYPE2, // Secondary event house choice list. 296 DATA_HTYPE3, // Primary action house choice list. 297 DATA_HTYPE4, // Secondary action house choice list. 298 DATA_BOOLTYPE1, // Primary action boolean data list. 299 DATA_BOOLTYPE2, // Secondary action boolean data list. 300 DATA_GENERAL1, // Primary event general data field. 301 DATA_GENERAL2, // Secondary event general data field. 302 DATA_GENERAL3, // Primary action general data field. 303 DATA_GENERAL4, // Secondary action general data field. 304 DATA_BTYPE1, // Primary event building type list. 305 DATA_BTYPE2, // Secondary event building type list. 306 DATA_ITYPE1, // Primary event infantry type list. 307 DATA_ITYPE2, // Secondary event infantry type list. 308 DATA_ATYPE1, // Primary event aircraft type list. 309 DATA_ATYPE2, // Secondary event aircraft type list. 310 DATA_UTYPE1, // Primary event unit type list. 311 DATA_UTYPE2, // Secondary event unit type list. 312 DATA_TTYPE1, // Primary event team type entry list. 313 DATA_TTYPE2, // Secondary event team type entry list. 314 DATA_TTYPE3, // Primary action team type entry list. 315 DATA_TTYPE4, // Secondary action team type entry list. 316 DATA_TRTYPE1, // Primary action trigger list. 317 DATA_TRTYPE2, // Secondary action trigger list. 318 BUTTON_HOUSE, // House ownership for this trigger. 319 BUTTON_PERSISTANCE, // Persistence of this trigger. 320 BUTTON_OK, // Ok button - save and exit. 321 BUTTON_CANCEL, // Cancel button - just exit. 322 BUTTON_ACTION, // Multiple action control button. 323 BUTTON_EVENT, // Multiple event control button. 324 }; 325 326 /* 327 ** Dialog variables: 328 */ 329 bool cancel = false; // true = user cancels 330 int i; // loop counter 331 RemapControlType * scheme = GadgetClass::Get_Color_Scheme(); 332 333 /* 334 ** Buttons 335 */ 336 ControlClass * commands = NULL; // the button list 337 338 /* 339 ** List of events allowed. 340 */ 341 char eventtext[ENTRY_SIZE] = ""; 342 TDropListClass<EventChoiceClass *> event1list(EVENT_LIST, eventtext, sizeof(eventtext), 343 TPF_EFNT | TPF_NOSHADOW, 344 E1_X, E1_Y, E_WIDTH, E_HEIGHT, 345 MFCD::Retrieve("EBTN-UP.SHP"), 346 MFCD::Retrieve("EBTN-DN.SHP")); 347 char event2text[ENTRY_SIZE] = ""; 348 TDropListClass<EventChoiceClass *> event2list(EVENT_LIST2, event2text, sizeof(event2text), 349 TPF_EFNT | TPF_NOSHADOW, 350 E2_X, E2_Y, E_WIDTH, E_HEIGHT, 351 MFCD::Retrieve("EBTN-UP.SHP"), 352 MFCD::Retrieve("EBTN-DN.SHP")); 353 for (TEventType event = TEVENT_FIRST; event < TEVENT_COUNT; event++) { 354 event1list.Add_Item(&EventChoices[event]); 355 event2list.Add_Item(&EventChoices[event]); 356 } 357 358 PBubble_Sort(&event1list[0], event1list.Count()); 359 PBubble_Sort(&event2list[0], event2list.Count()); 360 361 if (Event1.Event == TEVENT_NONE) Event1.Event = TEVENT_FIRST; 362 event1list.Set_Selected_Index(&EventChoices[Event1.Event]); 363 if (Event2.Event == TEVENT_NONE) Event2.Event = TEVENT_FIRST; 364 event2list.Set_Selected_Index(&EventChoices[Event2.Event]); 365 366 /* 367 ** List of actions allowed. 368 */ 369 char actiontext[ENTRY_SIZE] = ""; 370 TDropListClass<ActionChoiceClass *> action1list(ACTION_LIST, actiontext, sizeof(actiontext), 371 TPF_EFNT | TPF_NOSHADOW, 372 A1_X, A1_Y, E_WIDTH, E_HEIGHT, 373 MFCD::Retrieve("EBTN-UP.SHP"), 374 MFCD::Retrieve("EBTN-DN.SHP")); 375 char action2text[ENTRY_SIZE] = ""; 376 TDropListClass<ActionChoiceClass *> action2list(ACTION_LIST2, action2text, sizeof(action2text), 377 TPF_EFNT | TPF_NOSHADOW, 378 A2_X, A2_Y, E_WIDTH, E_HEIGHT, 379 MFCD::Retrieve("EBTN-UP.SHP"), 380 MFCD::Retrieve("EBTN-DN.SHP")); 381 for (TActionType action = TACTION_FIRST; action < TACTION_COUNT; action++) { 382 action1list.Add_Item(&ActionChoices[action]); 383 action2list.Add_Item(&ActionChoices[action]); 384 } 385 386 PBubble_Sort(&action1list[0], action1list.Count()); 387 PBubble_Sort(&action2list[0], action2list.Count()); 388 389 if (Action1.Action == ACTION_NONE) Action1.Action = TACTION_FIRST; 390 action1list.Set_Selected_Index(&ActionChoices[Action1.Action]); 391 if (Action2.Action == ACTION_NONE) Action2.Action = TACTION_FIRST; 392 action2list.Set_Selected_Index(&ActionChoices[Action2.Action]); 393 394 /* 395 ** Optional waypoint entry field. 396 */ 397 char way1[WAYPOINT_SIZE] = "A"; 398 EditClass way1data(DATA_EDIT, way1, sizeof(way1), TPF_EFNT | TPF_NOSHADOW, 399 ED1_X, ED1_Y, ED_WIDTH, 9, EditClass::ALPHA); 400 if (Event_Needs(Event1.Event) == NEED_WAYPOINT) { 401 if (Event1.Data.Value < 26) { 402 sprintf(way1data.Get_Text(), "%c", Event1.Data.Value + 'A'); 403 } else { 404 sprintf(way1data.Get_Text(), "%c%c", (Event1.Data.Value / 26) + 'A'-1, (Event1.Data.Value % 26) + 'A'); 405 } 406 } 407 408 char way2[WAYPOINT_SIZE] = "A"; 409 EditClass way2data(DATA_EDIT2, way2, sizeof(way2), TPF_EFNT | TPF_NOSHADOW, 410 ED2_X, ED2_Y, ED_WIDTH, 9, EditClass::ALPHA); 411 if (Event_Needs(Event2.Event) == NEED_WAYPOINT) { 412 if (Event2.Data.Value < 26) { 413 sprintf(way2data.Get_Text(), "%c", Event2.Data.Value + 'A'); 414 } else { 415 sprintf(way2data.Get_Text(), "%c%c", (Event2.Data.Value / 26) + 'A'-1, (Event2.Data.Value % 26) + 'A'); 416 } 417 } 418 419 char way3[WAYPOINT_SIZE] = "A"; 420 EditClass way3data(DATA_EDIT3, way3, sizeof(way3), TPF_EFNT | TPF_NOSHADOW, 421 AD1_X, AD1_Y, ED_WIDTH, 9, EditClass::ALPHA); 422 if (Action_Needs(Action1.Action) == NEED_WAYPOINT) { 423 if (Action1.Data.Value < 26) { 424 sprintf(way3data.Get_Text(), "%c", Action1.Data.Value + 'A'); 425 } else { 426 sprintf(way3data.Get_Text(), "%c%c", (Action1.Data.Value / 26) + 'A'-1, (Action1.Data.Value % 26) + 'A'); 427 } 428 } 429 430 char way4[WAYPOINT_SIZE] = "A"; 431 EditClass way4data(DATA_EDIT4, way4, sizeof(way4), TPF_EFNT | TPF_NOSHADOW, 432 AD2_X, AD2_Y, ED_WIDTH, 9, EditClass::ALPHA); 433 if (Action_Needs(Action2.Action) == NEED_WAYPOINT) { 434 if (Action2.Data.Value < 26) { 435 sprintf(way4data.Get_Text(), "%c", Action2.Data.Value + 'A'); 436 } else { 437 sprintf(way4data.Get_Text(), "%c%c", (Action2.Data.Value / 26) + 'A'-1, (Action2.Data.Value % 26) + 'A'); 438 } 439 } 440 441 /* 442 ** Optional event data entry field. 443 */ 444 char databuf1[GENERAL_SIZE] = ""; 445 EditClass event1data(DATA_GENERAL1, databuf1, sizeof(databuf1), 446 TPF_EFNT | TPF_NOSHADOW, 447 ED1_X, ED1_Y, ED_WIDTH, 9, EditClass::NUMERIC); 448 switch (Event_Needs(Event1.Event)) { 449 case NEED_TIME: 450 case NEED_NUMBER: 451 sprintf(event1data.Get_Text(), "%d", Event1.Data.Value); 452 break; 453 } 454 455 char databuf2[GENERAL_SIZE] = ""; 456 EditClass event2data(DATA_GENERAL2, databuf2, sizeof(databuf2), 457 TPF_EFNT | TPF_NOSHADOW, 458 ED2_X, ED2_Y, ED_WIDTH, 9, EditClass::NUMERIC); 459 switch (Event_Needs(Event2.Event)) { 460 case NEED_TIME: 461 case NEED_NUMBER: 462 sprintf(event2data.Get_Text(), "%d", Event2.Data.Value); 463 break; 464 } 465 466 char actionbuf1[GENERAL_SIZE] = ""; 467 EditClass action1data(DATA_GENERAL3, actionbuf1, sizeof(actionbuf1), 468 TPF_EFNT | TPF_NOSHADOW, 469 AD1_X, AD1_Y, ED_WIDTH, 9, EditClass::NUMERIC); 470 switch (Action_Needs(Action1.Action)) { 471 case NEED_NUMBER: 472 sprintf(action1data.Get_Text(), "%d", Action1.Data.Value); 473 break; 474 } 475 476 char actionbuf2[GENERAL_SIZE] = ""; 477 EditClass action2data(DATA_GENERAL4, actionbuf2, sizeof(actionbuf2), 478 TPF_EFNT | TPF_NOSHADOW, 479 AD2_X, AD2_Y, ED_WIDTH, 9, EditClass::NUMERIC); 480 switch (Action_Needs(Action2.Action)) { 481 case NEED_NUMBER: 482 sprintf(action2data.Get_Text(), "%d", Action2.Data.Value); 483 break; 484 } 485 486 /* 487 ** Optional team entry list. 488 */ 489 char tbuf1[TEAM_SIZE] = ""; 490 DropListClass ttype1list(DATA_TTYPE1, tbuf1, sizeof(tbuf1), 491 TPF_EFNT | TPF_NOSHADOW, 492 ED1_X, ED1_Y, ED_WIDTH, ED_HEIGHT, 493 MFCD::Retrieve("EBTN-UP.SHP"), 494 MFCD::Retrieve("EBTN-DN.SHP")); 495 char tbuf2[TEAM_SIZE] = ""; 496 DropListClass ttype2list(DATA_TTYPE2, tbuf2, sizeof(tbuf2), 497 TPF_EFNT | TPF_NOSHADOW, 498 ED2_X, ED2_Y, ED_WIDTH, ED_HEIGHT, 499 MFCD::Retrieve("EBTN-UP.SHP"), 500 MFCD::Retrieve("EBTN-DN.SHP")); 501 char tbuf3[TEAM_SIZE] = ""; 502 DropListClass ttype3list(DATA_TTYPE3, tbuf3, sizeof(tbuf3), 503 TPF_EFNT | TPF_NOSHADOW, 504 AD1_X, AD1_Y, ED_WIDTH, ED_HEIGHT, 505 MFCD::Retrieve("EBTN-UP.SHP"), 506 MFCD::Retrieve("EBTN-DN.SHP")); 507 char tbuf4[TEAM_SIZE] = ""; 508 DropListClass ttype4list(DATA_TTYPE4, tbuf4, sizeof(tbuf4), 509 TPF_EFNT | TPF_NOSHADOW, 510 AD2_X, AD2_Y, ED_WIDTH, ED_HEIGHT, 511 MFCD::Retrieve("EBTN-UP.SHP"), 512 MFCD::Retrieve("EBTN-DN.SHP")); 513 514 for (int index = 0; index < TeamTypes.Count(); index++) { 515 ttype1list.Add_Item(TeamTypes.Ptr(index)->IniName); 516 ttype2list.Add_Item(TeamTypes.Ptr(index)->IniName); 517 ttype3list.Add_Item(TeamTypes.Ptr(index)->IniName); 518 ttype4list.Add_Item(TeamTypes.Ptr(index)->IniName); 519 } 520 521 if (Event1.Team.Is_Valid()) { 522 ttype1list.Set_Selected_Index(Event1.Team->IniName); 523 } else { 524 ttype1list.Set_Selected_Index(0); 525 } 526 if (Event2.Team.Is_Valid()) { 527 ttype2list.Set_Selected_Index(Event2.Team->IniName); 528 } else { 529 ttype2list.Set_Selected_Index(0); 530 } 531 if (Action1.Team.Is_Valid()) { 532 ttype3list.Set_Selected_Index(Action1.Team->IniName); 533 } else { 534 ttype3list.Set_Selected_Index(0); 535 } 536 if (Action2.Team.Is_Valid()) { 537 ttype4list.Set_Selected_Index(Action2.Team->IniName); 538 } else { 539 ttype4list.Set_Selected_Index(0); 540 } 541 542 /* 543 ** Optional trigger entry list. 544 */ 545 char trbuf1[TEAM_SIZE] = ""; 546 DropListClass trtype1list(DATA_TRTYPE1, trbuf1, sizeof(trbuf1), 547 TPF_EFNT | TPF_NOSHADOW, 548 AD1_X, AD1_Y, ED_WIDTH, ED_HEIGHT, 549 MFCD::Retrieve("EBTN-UP.SHP"), 550 MFCD::Retrieve("EBTN-DN.SHP")); 551 char trbuf2[TEAM_SIZE] = ""; 552 DropListClass trtype2list(DATA_TRTYPE2, trbuf2, sizeof(trbuf2), 553 TPF_EFNT | TPF_NOSHADOW, 554 AD2_X, AD2_Y, ED_WIDTH, ED_HEIGHT, 555 MFCD::Retrieve("EBTN-UP.SHP"), 556 MFCD::Retrieve("EBTN-DN.SHP")); 557 558 for (index = 0; index < TriggerTypes.Count(); index++) { 559 trtype1list.Add_Item(TriggerTypes.Ptr(index)->IniName); 560 trtype2list.Add_Item(TriggerTypes.Ptr(index)->IniName); 561 } 562 563 if (Action1.Trigger.Is_Valid()) { 564 trtype1list.Set_Selected_Index(Action1.Trigger->IniName); 565 } else { 566 trtype1list.Set_Selected_Index(0); 567 } 568 if (Action2.Trigger.Is_Valid()) { 569 trtype2list.Set_Selected_Index(Action2.Trigger->IniName); 570 } else { 571 trtype2list.Set_Selected_Index(0); 572 } 573 574 /* 575 ** Optional boolean value list. 576 */ 577 char boolbuf1[TEAM_SIZE] = ""; 578 DropListClass booltype1list(DATA_BOOLTYPE1, boolbuf1, sizeof(boolbuf1), 579 TPF_EFNT | TPF_NOSHADOW, 580 AD1_X, AD1_Y, ED_WIDTH, ED_HEIGHT, 581 MFCD::Retrieve("EBTN-UP.SHP"), 582 MFCD::Retrieve("EBTN-DN.SHP")); 583 char boolbuf2[TEAM_SIZE] = ""; 584 DropListClass booltype2list(DATA_BOOLTYPE2, boolbuf2, sizeof(boolbuf2), 585 TPF_EFNT | TPF_NOSHADOW, 586 AD2_X, AD2_Y, ED_WIDTH, ED_HEIGHT, 587 MFCD::Retrieve("EBTN-UP.SHP"), 588 MFCD::Retrieve("EBTN-DN.SHP")); 589 590 booltype1list.Add_Item("OFF"); 591 booltype1list.Add_Item("ON"); 592 booltype2list.Add_Item("OFF"); 593 booltype2list.Add_Item("ON"); 594 595 booltype1list.Set_Selected_Index(Action1.Data.Bool); 596 booltype2list.Set_Selected_Index(Action2.Data.Bool); 597 598 /* 599 ** Optional musical theme choice list. 600 */ 601 char themebuf1[DESC_SIZE] = ""; 602 DropListClass themetype1list(DATA_THEME1, themebuf1, sizeof(themebuf1), 603 TPF_EFNT | TPF_NOSHADOW, 604 AD1_X, AD1_Y, ED_WIDTH, ED_HEIGHT, 605 MFCD::Retrieve("EBTN-UP.SHP"), 606 MFCD::Retrieve("EBTN-DN.SHP")); 607 char themebuf2[DESC_SIZE] = ""; 608 DropListClass themetype2list(DATA_THEME2, themebuf2, sizeof(themebuf2), 609 TPF_EFNT | TPF_NOSHADOW, 610 AD2_X, AD2_Y, ED_WIDTH, ED_HEIGHT, 611 MFCD::Retrieve("EBTN-UP.SHP"), 612 MFCD::Retrieve("EBTN-DN.SHP")); 613 614 for (ThemeType theme = THEME_FIRST; theme < THEME_COUNT; theme++) { 615 themetype1list.Add_Item(Theme.Full_Name(theme)); 616 themetype2list.Add_Item(Theme.Full_Name(theme)); 617 } 618 619 if (Action_Needs(Action1.Action) == NEED_THEME) { 620 themetype1list.Set_Selected_Index(Action1.Data.Theme); 621 } else { 622 themetype1list.Set_Selected_Index(0); 623 } 624 if (Action_Needs(Action2.Action) == NEED_THEME) { 625 themetype2list.Set_Selected_Index(Action2.Data.Theme); 626 } else { 627 themetype2list.Set_Selected_Index(0); 628 } 629 630 /* 631 ** Optional movie list. 632 */ 633 char moviebuf1[DESC_SIZE] = ""; 634 DropListClass movietype1list(DATA_MOVIE1, moviebuf1, sizeof(moviebuf1), 635 TPF_EFNT | TPF_NOSHADOW, 636 AD1_X, AD1_Y, ED_WIDTH, ED_HEIGHT, 637 MFCD::Retrieve("EBTN-UP.SHP"), 638 MFCD::Retrieve("EBTN-DN.SHP")); 639 char moviebuf2[DESC_SIZE] = ""; 640 DropListClass movietype2list(DATA_MOVIE2, moviebuf2, sizeof(moviebuf2), 641 TPF_EFNT | TPF_NOSHADOW, 642 AD2_X, AD2_Y, ED_WIDTH, ED_HEIGHT, 643 MFCD::Retrieve("EBTN-UP.SHP"), 644 MFCD::Retrieve("EBTN-DN.SHP")); 645 646 for (VQType movie = VQ_FIRST; movie < VQ_COUNT; movie++) { 647 movietype1list.Add_Item(VQName[movie]); 648 movietype2list.Add_Item(VQName[movie]); 649 } 650 651 if (Action_Needs(Action1.Action) == NEED_MOVIE) { 652 movietype1list.Set_Selected_Index(Action1.Data.Movie); 653 } else { 654 movietype1list.Set_Selected_Index(0); 655 } 656 if (Action_Needs(Action2.Action) == NEED_MOVIE) { 657 movietype2list.Set_Selected_Index(Action2.Data.Movie); 658 } else { 659 movietype2list.Set_Selected_Index(0); 660 } 661 662 /* 663 ** Optional sound effect list. 664 */ 665 char soundbuf1[DESC_SIZE] = ""; 666 DropListClass soundtype1list(DATA_SOUND1, soundbuf1, sizeof(soundbuf1), 667 TPF_EFNT | TPF_NOSHADOW, 668 AD1_X, AD1_Y, ED_WIDTH, ED_HEIGHT, 669 MFCD::Retrieve("EBTN-UP.SHP"), 670 MFCD::Retrieve("EBTN-DN.SHP")); 671 char soundbuf2[DESC_SIZE] = ""; 672 DropListClass soundtype2list(DATA_SOUND2, soundbuf2, sizeof(soundbuf2), 673 TPF_EFNT | TPF_NOSHADOW, 674 AD2_X, AD2_Y, ED_WIDTH, ED_HEIGHT, 675 MFCD::Retrieve("EBTN-UP.SHP"), 676 MFCD::Retrieve("EBTN-DN.SHP")); 677 678 for (VocType sound = VOC_FIRST; sound < VOC_COUNT; sound++) { 679 soundtype1list.Add_Item(Voc_Name(sound)); 680 soundtype2list.Add_Item(Voc_Name(sound)); 681 } 682 683 if (Action_Needs(Action1.Action) == NEED_SOUND) { 684 soundtype1list.Set_Selected_Index(Action1.Data.Sound); 685 } else { 686 soundtype1list.Set_Selected_Index(0); 687 } 688 if (Action_Needs(Action2.Action) == NEED_SOUND) { 689 soundtype2list.Set_Selected_Index(Action2.Data.Sound); 690 } else { 691 soundtype2list.Set_Selected_Index(0); 692 } 693 694 /* 695 ** Optional speech effect list. 696 */ 697 char speechbuf1[DESC_SIZE] = ""; 698 DropListClass speechtype1list(DATA_SPEECH1, speechbuf1, sizeof(speechbuf1), 699 TPF_EFNT | TPF_NOSHADOW, 700 AD1_X, AD1_Y, ED_WIDTH, ED_HEIGHT, 701 MFCD::Retrieve("EBTN-UP.SHP"), 702 MFCD::Retrieve("EBTN-DN.SHP")); 703 char speechbuf2[DESC_SIZE] = ""; 704 DropListClass speechtype2list(DATA_SPEECH2, speechbuf2, sizeof(speechbuf2), 705 TPF_EFNT | TPF_NOSHADOW, 706 AD2_X, AD2_Y, ED_WIDTH, ED_HEIGHT, 707 MFCD::Retrieve("EBTN-UP.SHP"), 708 MFCD::Retrieve("EBTN-DN.SHP")); 709 710 for (VoxType speech = VOX_FIRST; speech < VOX_COUNT; speech++) { 711 speechtype1list.Add_Item(Speech_Name(speech)); 712 speechtype2list.Add_Item(Speech_Name(speech)); 713 } 714 715 if (Action_Needs(Action1.Action) == NEED_SPEECH) { 716 speechtype1list.Set_Selected_Index(Action1.Data.Speech); 717 } else { 718 speechtype1list.Set_Selected_Index(0); 719 } 720 if (Action_Needs(Action2.Action) == NEED_SPEECH) { 721 speechtype2list.Set_Selected_Index(Action2.Data.Speech); 722 } else { 723 speechtype2list.Set_Selected_Index(0); 724 } 725 726 /* 727 ** Optional building type entry list. 728 */ 729 char bbuf1[DESC_SIZE] = ""; 730 DropListClass btype1list(DATA_BTYPE1, bbuf1, sizeof(bbuf1), 731 TPF_EFNT | TPF_NOSHADOW, 732 ED1_X, ED1_Y, ED_WIDTH, ED_HEIGHT, 733 MFCD::Retrieve("EBTN-UP.SHP"), 734 MFCD::Retrieve("EBTN-DN.SHP")); 735 char bbuf2[DESC_SIZE] = ""; 736 DropListClass btype2list(DATA_BTYPE2, bbuf2, sizeof(bbuf2), 737 TPF_EFNT | TPF_NOSHADOW, 738 ED2_X, ED2_Y, ED_WIDTH, ED_HEIGHT, 739 MFCD::Retrieve("EBTN-UP.SHP"), 740 MFCD::Retrieve("EBTN-DN.SHP")); 741 742 for (StructType ss = STRUCT_FIRST; ss < STRUCT_COUNT; ss++) { 743 btype1list.Add_Item(Text_String(BuildingTypeClass::As_Reference(ss).Full_Name())); 744 btype2list.Add_Item(Text_String(BuildingTypeClass::As_Reference(ss).Full_Name())); 745 } 746 747 if (Event_Needs(Event1.Event) == NEED_STRUCTURE) { 748 btype1list.Set_Selected_Index(Event1.Data.Structure); 749 } else { 750 btype1list.Set_Selected_Index(0); 751 } 752 if (Event_Needs(Event2.Event) == NEED_STRUCTURE) { 753 btype2list.Set_Selected_Index(Event2.Data.Structure); 754 } else { 755 btype2list.Set_Selected_Index(0); 756 } 757 758 /* 759 ** Optional infantry type entry list. 760 */ 761 char ibuf1[DESC_SIZE] = ""; 762 DropListClass itype1list(DATA_ITYPE1, ibuf1, sizeof(ibuf1), 763 TPF_EFNT | TPF_NOSHADOW, 764 ED1_X, ED1_Y, ED_WIDTH, ED_HEIGHT, 765 MFCD::Retrieve("EBTN-UP.SHP"), 766 MFCD::Retrieve("EBTN-DN.SHP")); 767 char ibuf2[DESC_SIZE] = ""; 768 DropListClass itype2list(DATA_ITYPE2, ibuf2, sizeof(ibuf2), 769 TPF_EFNT | TPF_NOSHADOW, 770 ED2_X, ED2_Y, ED_WIDTH, ED_HEIGHT, 771 MFCD::Retrieve("EBTN-UP.SHP"), 772 MFCD::Retrieve("EBTN-DN.SHP")); 773 774 for (InfantryType ii = INFANTRY_FIRST; ii < INFANTRY_COUNT; ii++) { 775 itype1list.Add_Item(Text_String(InfantryTypeClass::As_Reference(ii).Full_Name())); 776 itype2list.Add_Item(Text_String(InfantryTypeClass::As_Reference(ii).Full_Name())); 777 } 778 779 if (Event_Needs(Event1.Event) == NEED_INFANTRY) { 780 itype1list.Set_Selected_Index(Event1.Data.Infantry); 781 } else { 782 itype1list.Set_Selected_Index(0); 783 } 784 if (Event_Needs(Event2.Event) == NEED_INFANTRY) { 785 itype2list.Set_Selected_Index(Event2.Data.Infantry); 786 } else { 787 itype2list.Set_Selected_Index(0); 788 } 789 790 /* 791 ** Optional aircraft type entry list. 792 */ 793 char abuf1[DESC_SIZE] = ""; 794 DropListClass atype1list(DATA_ATYPE1, abuf1, sizeof(abuf1), 795 TPF_EFNT | TPF_NOSHADOW, 796 ED1_X, ED1_Y, ED_WIDTH, ED_HEIGHT, 797 MFCD::Retrieve("EBTN-UP.SHP"), 798 MFCD::Retrieve("EBTN-DN.SHP")); 799 char abuf2[DESC_SIZE] = ""; 800 DropListClass atype2list(DATA_ATYPE2, abuf2, sizeof(abuf2), 801 TPF_EFNT | TPF_NOSHADOW, 802 ED2_X, ED2_Y, ED_WIDTH, ED_HEIGHT, 803 MFCD::Retrieve("EBTN-UP.SHP"), 804 MFCD::Retrieve("EBTN-DN.SHP")); 805 806 for (AircraftType aa = AIRCRAFT_FIRST; aa < AIRCRAFT_COUNT; aa++) { 807 atype1list.Add_Item(Text_String(AircraftTypeClass::As_Reference(aa).Full_Name())); 808 atype2list.Add_Item(Text_String(AircraftTypeClass::As_Reference(aa).Full_Name())); 809 } 810 811 if (Event_Needs(Event1.Event) == NEED_AIRCRAFT) { 812 atype1list.Set_Selected_Index(Event1.Data.Aircraft); 813 } else { 814 atype1list.Set_Selected_Index(0); 815 } 816 if (Event_Needs(Event2.Event) == NEED_AIRCRAFT) { 817 atype2list.Set_Selected_Index(Event2.Data.Aircraft); 818 } else { 819 atype2list.Set_Selected_Index(0); 820 } 821 822 /* 823 ** Optional unit type entry list. 824 */ 825 char ubuf1[DESC_SIZE] = ""; 826 DropListClass utype1list(DATA_UTYPE1, ubuf1, sizeof(ubuf1), 827 TPF_EFNT | TPF_NOSHADOW, 828 ED1_X, ED1_Y, ED_WIDTH, ED_HEIGHT, 829 MFCD::Retrieve("EBTN-UP.SHP"), 830 MFCD::Retrieve("EBTN-DN.SHP")); 831 char ubuf2[DESC_SIZE] = ""; 832 DropListClass utype2list(DATA_UTYPE2, ubuf2, sizeof(ubuf2), 833 TPF_EFNT | TPF_NOSHADOW, 834 ED2_X, ED2_Y, ED_WIDTH, ED_HEIGHT, 835 MFCD::Retrieve("EBTN-UP.SHP"), 836 MFCD::Retrieve("EBTN-DN.SHP")); 837 838 for (UnitType uu = UNIT_FIRST; uu < UNIT_COUNT; uu++) { 839 utype1list.Add_Item(Text_String(UnitTypeClass::As_Reference(uu).Full_Name())); 840 utype2list.Add_Item(Text_String(UnitTypeClass::As_Reference(uu).Full_Name())); 841 } 842 843 if (Event_Needs(Event1.Event) == NEED_UNIT) { 844 utype1list.Set_Selected_Index(Event1.Data.Unit); 845 } else { 846 utype1list.Set_Selected_Index(0); 847 } 848 if (Event_Needs(Event2.Event) == NEED_UNIT) { 849 utype2list.Set_Selected_Index(Event2.Data.Unit); 850 } else { 851 utype2list.Set_Selected_Index(0); 852 } 853 854 /* 855 ** Optional house type entry list. 856 */ 857 char housebuf1[DESC_SIZE] = ""; 858 DropListClass htype1list(DATA_HTYPE1, housebuf1, sizeof(housebuf1), 859 TPF_EFNT | TPF_NOSHADOW, 860 ED1_X, ED1_Y, ED_WIDTH, ED_HEIGHT, 861 MFCD::Retrieve("EBTN-UP.SHP"), 862 MFCD::Retrieve("EBTN-DN.SHP")); 863 char housebuf2[DESC_SIZE] = ""; 864 DropListClass htype2list(DATA_HTYPE2, housebuf2, sizeof(housebuf2), 865 TPF_EFNT | TPF_NOSHADOW, 866 ED2_X, ED2_Y, ED_WIDTH, ED_HEIGHT, 867 MFCD::Retrieve("EBTN-UP.SHP"), 868 MFCD::Retrieve("EBTN-DN.SHP")); 869 char housebuf3[DESC_SIZE] = ""; 870 DropListClass htype3list(DATA_HTYPE3, housebuf3, sizeof(housebuf3), 871 TPF_EFNT | TPF_NOSHADOW, 872 AD1_X, AD1_Y, ED_WIDTH, ED_HEIGHT, 873 MFCD::Retrieve("EBTN-UP.SHP"), 874 MFCD::Retrieve("EBTN-DN.SHP")); 875 char housebuf4[DESC_SIZE] = ""; 876 DropListClass htype4list(DATA_HTYPE4, housebuf4, sizeof(housebuf4), 877 TPF_EFNT | TPF_NOSHADOW, 878 AD2_X, AD2_Y, ED_WIDTH, ED_HEIGHT, 879 MFCD::Retrieve("EBTN-UP.SHP"), 880 MFCD::Retrieve("EBTN-DN.SHP")); 881 882 for (HousesType hh = HOUSE_FIRST; hh < HOUSE_COUNT; hh++) { 883 htype1list.Add_Item(HouseTypeClass::As_Reference(hh).IniName); 884 htype2list.Add_Item(HouseTypeClass::As_Reference(hh).IniName); 885 htype3list.Add_Item(HouseTypeClass::As_Reference(hh).IniName); 886 htype4list.Add_Item(HouseTypeClass::As_Reference(hh).IniName); 887 } 888 889 if (Event_Needs(Event1.Event) == NEED_HOUSE) { 890 htype1list.Set_Selected_Index(Event1.Data.House); 891 } else { 892 htype1list.Set_Selected_Index(0); 893 } 894 if (Event_Needs(Event2.Event) == NEED_HOUSE) { 895 htype2list.Set_Selected_Index(Event2.Data.House); 896 } else { 897 htype2list.Set_Selected_Index(0); 898 } 899 if (Action_Needs(Action1.Action) == NEED_HOUSE) { 900 htype3list.Set_Selected_Index(Action1.Data.House); 901 } else { 902 htype3list.Set_Selected_Index(0); 903 } 904 if (Action_Needs(Action2.Action) == NEED_HOUSE) { 905 htype4list.Set_Selected_Index(Action2.Data.House); 906 } else { 907 htype4list.Set_Selected_Index(0); 908 } 909 910 /* 911 ** Optional special weapon list. 912 */ 913 char special1[DESC_SIZE] = ""; 914 DropListClass spc1(DATA_SPECIAL1, special1, sizeof(special1), 915 TPF_EFNT | TPF_NOSHADOW, 916 AD1_X, AD1_Y, ED_WIDTH, ED_HEIGHT, 917 MFCD::Retrieve("EBTN-UP.SHP"), 918 MFCD::Retrieve("EBTN-DN.SHP")); 919 char special2[DESC_SIZE] = ""; 920 DropListClass spc2(DATA_SPECIAL2, special2, sizeof(special2), 921 TPF_EFNT | TPF_NOSHADOW, 922 AD2_X, AD2_Y, ED_WIDTH, ED_HEIGHT, 923 MFCD::Retrieve("EBTN-UP.SHP"), 924 MFCD::Retrieve("EBTN-DN.SHP")); 925 for (SpecialWeaponType spec = SPC_FIRST; spec < SPC_COUNT; spec++) { 926 spc1.Add_Item(SpecialWeaponName[spec]); 927 spc2.Add_Item(SpecialWeaponName[spec]); 928 } 929 if ((unsigned)Action1.Data.Special < SPC_COUNT) { 930 spc1.Set_Selected_Index(Action1.Data.Special); 931 } else { 932 spc1.Set_Selected_Index(0); 933 } 934 if ((unsigned)Action2.Data.Special < SPC_COUNT) { 935 spc2.Set_Selected_Index(Action2.Data.Special); 936 } else { 937 spc2.Set_Selected_Index(0); 938 } 939 940 /* 941 ** Optional quarry type. 942 */ 943 char quarry1[DESC_SIZE] = ""; 944 DropListClass qlist1(DATA_SPECIAL1, quarry1, sizeof(quarry1), 945 TPF_EFNT | TPF_NOSHADOW, 946 AD1_X, AD1_Y, ED_WIDTH, ED_HEIGHT, 947 MFCD::Retrieve("EBTN-UP.SHP"), 948 MFCD::Retrieve("EBTN-DN.SHP")); 949 char quarry2[DESC_SIZE] = ""; 950 DropListClass qlist2(DATA_SPECIAL2, quarry2, sizeof(quarry2), 951 TPF_EFNT | TPF_NOSHADOW, 952 AD2_X, AD2_Y, ED_WIDTH, ED_HEIGHT, 953 MFCD::Retrieve("EBTN-UP.SHP"), 954 MFCD::Retrieve("EBTN-DN.SHP")); 955 for (QuarryType q = QUARRY_FIRST; q < QUARRY_COUNT; q++) { 956 qlist1.Add_Item(QuarryName[q]); 957 qlist2.Add_Item(QuarryName[q]); 958 } 959 if ((unsigned)Action1.Data.Quarry < QUARRY_COUNT) { 960 qlist1.Set_Selected_Index(Action1.Data.Quarry); 961 } else { 962 qlist1.Set_Selected_Index(0); 963 } 964 if ((unsigned)Action2.Data.Quarry < QUARRY_COUNT) { 965 qlist2.Set_Selected_Index(Action2.Data.Quarry); 966 } else { 967 qlist2.Set_Selected_Index(0); 968 } 969 970 /* 971 ** Name of this trigger text edit field. 972 */ 973 char namebuf[5] = ""; 974 EditClass name_edt(NAME_EDIT, namebuf, sizeof(namebuf), TPF_EFNT | TPF_NOSHADOW, D_DIALOG_X+40, D_DIALOG_Y+30, 40, 9, EditClass::ALPHANUMERIC); 975 strcpy(namebuf, IniName); // Name 976 977 /* 978 ** Create the list of house's allowed for trigger. 979 */ 980 char housetext[DESC_SIZE] = ""; 981 DropListClass housebtn(BUTTON_HOUSE, housetext, sizeof(housetext), 982 TPF_EFNT | TPF_NOSHADOW, 983 name_edt.X+name_edt.Width+20, name_edt.Y, 95, 8*5, 984 MFCD::Retrieve("EBTN-UP.SHP"), 985 MFCD::Retrieve("EBTN-DN.SHP")); 986 for (HousesType house = HOUSE_FIRST; house < HOUSE_COUNT; house++) { 987 housebtn.Add_Item(HouseTypeClass::As_Reference(house).IniName); 988 } 989 if (House == HOUSE_NONE) House = HOUSE_GOOD; 990 housebtn.Set_Selected_Index(House); 991 992 /* 993 ** Must match order and number of PersistantType specified in 994 ** TriggerTypeClass definition. 995 */ 996 char perstext[DESC_SIZE] = ""; 997 static char * _perstext[3] = { 998 "Volatile", 999 "Semi-persistent", 1000 "Persistent" 1001 }; 1002 DropListClass persbtn(BUTTON_PERSISTANCE, perstext, sizeof(perstext), 1003 TPF_EFNT | TPF_NOSHADOW, 1004 housebtn.X+housebtn.Width+20, housebtn.Y, 105, 8*5, 1005 MFCD::Retrieve("EBTN-UP.SHP"), 1006 MFCD::Retrieve("EBTN-DN.SHP")); 1007 for (i = 0; i < sizeof(_perstext)/sizeof(_perstext[0]); i++) { 1008 persbtn.Add_Item(_perstext[i]); 1009 } 1010 persbtn.Set_Selected_Index(IsPersistant); 1011 1012 /* 1013 ** This button controls the existence and relationship of a second trigger 1014 ** event. 1015 */ 1016 int eventflag = EventControl; 1017 TextButtonClass eventbtn(BUTTON_EVENT, TXT_TRIGGER_JUST_EVENT, TPF_EBUTTON, event1list.X, event1list.Y+11, 100, 9); 1018 1019 /* 1020 ** This button controls the existence of a secondary action. 1021 */ 1022 bool actionflag = ActionControl; 1023 TextButtonClass actionbtn(BUTTON_ACTION, TXT_TRIGGER_JUST_ACTION, TPF_EBUTTON, action1list.X, action1list.Y+11, 100, 9); 1024 1025 /* 1026 ** Create the ubiquitous OK and Cancel buttons. 1027 */ 1028 TextButtonClass okbtn(BUTTON_OK, TXT_OK, TPF_EBUTTON, D_DIALOG_X+35, D_DIALOG_Y+D_DIALOG_H-30, 45, 9); 1029 TextButtonClass cancelbtn(BUTTON_CANCEL, TXT_CANCEL, TPF_EBUTTON, D_DIALOG_X+D_DIALOG_W-80, D_DIALOG_Y+D_DIALOG_H-30, 45, 9); 1030 1031 /* 1032 ** Initialize 1033 */ 1034 Set_Logic_Page(SeenBuff); 1035 1036 /* 1037 ** Build the button list 1038 */ 1039 commands = &okbtn; 1040 cancelbtn.Add_Tail(*commands); 1041 event1list.Add_Tail(*commands); 1042 action1list.Add_Tail(*commands); 1043 eventbtn.Add_Tail(*commands); 1044 actionbtn.Add_Tail(*commands); 1045 name_edt.Add_Tail(*commands); 1046 persbtn.Add_Tail(*commands); 1047 housebtn.Add_Tail(*commands); 1048 1049 /* 1050 ** Main Processing Loop 1051 */ 1052 bool display = true; 1053 bool process = true; 1054 while (process) { 1055 1056 /* 1057 ** Invoke game callback 1058 */ 1059 Call_Back(); 1060 1061 /* 1062 ** Refresh display if needed 1063 */ 1064 if (display /*&& LogicPage->Lock()*/) { 1065 1066 /* 1067 ** Display the dialog box 1068 */ 1069 Hide_Mouse(); 1070 Dialog_Box(D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W, D_DIALOG_H); 1071 Draw_Caption(TXT_TRIGGER_EDITOR, D_DIALOG_X, D_DIALOG_Y, D_DIALOG_W); 1072 1073 /* 1074 ** Draw the captions 1075 */ 1076 Fancy_Text_Print("Trigger Event:", event1list.X, event1list.Y - 7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW); 1077 Fancy_Text_Print("Action to Perform:", action1list.X, action1list.Y - 7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW); 1078 Fancy_Text_Print("House:", housebtn.X, housebtn.Y - 7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW); 1079 Fancy_Text_Print("Name:", name_edt.X, name_edt.Y - 7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW); 1080 Fancy_Text_Print("Persistence:", persbtn.X, persbtn.Y - 7, scheme, TBLACK, TPF_EFNT | TPF_NOSHADOW); 1081 1082 if (eventflag == 3) { 1083 LogicPage->Draw_Line(event1list.X-1, event1list.Y+3, event1list.X-2*RESFACTOR, event1list.Y+3, WHITE); 1084 LogicPage->Draw_Line(event1list.X-2*RESFACTOR, event1list.Y+3, action1list.X-2*RESFACTOR, action1list.Y+3, WHITE); 1085 LogicPage->Draw_Line(action1list.X-1, action1list.Y+3, action1list.X-2*RESFACTOR, action1list.Y+3, WHITE); 1086 1087 LogicPage->Draw_Line(event2list.X-1, event2list.Y+3, event2list.X-5*RESFACTOR, event2list.Y+3, WHITE); 1088 LogicPage->Draw_Line(event2list.X-5*RESFACTOR, event2list.Y+3, action2list.X-5*RESFACTOR, action2list.Y+3, WHITE); 1089 LogicPage->Draw_Line(action2list.X-1, action2list.Y+3, action2list.X-5*RESFACTOR, action2list.Y+3, WHITE); 1090 } 1091 1092 /* 1093 ** Adjust the button list to match current control settings. 1094 */ 1095 event2list.Remove(); 1096 switch (eventflag) { 1097 case 0: 1098 eventbtn.Set_Text(TXT_TRIGGER_JUST_EVENT); 1099 break; 1100 1101 case 1: 1102 eventbtn.Set_Text(TXT_TRIGGER_AND); 1103 event2list.Add(*commands); 1104 break; 1105 1106 case 2: 1107 eventbtn.Set_Text(TXT_TRIGGER_OR); 1108 event2list.Add(*commands); 1109 break; 1110 1111 case 3: 1112 eventbtn.Set_Text(TXT_TRIGGER_LINKED); 1113 event2list.Add(*commands); 1114 break; 1115 } 1116 1117 /* 1118 ** Prepare the primary event data field. 1119 */ 1120 htype1list.Remove(); 1121 way1data.Remove(); 1122 event1data.Remove(); 1123 btype1list.Remove(); 1124 itype1list.Remove(); 1125 atype1list.Remove(); 1126 utype1list.Remove(); 1127 ttype1list.Remove(); 1128 switch (Event_Needs(*event1list.Current_Item())) { 1129 case NEED_HOUSE: 1130 htype1list.Add(*commands); 1131 break; 1132 1133 case NEED_TEAM: 1134 ttype1list.Add(*commands); 1135 break; 1136 1137 case NEED_WAYPOINT: 1138 way1data.Add(*commands); 1139 break; 1140 1141 case NEED_TIME: 1142 case NEED_NUMBER: 1143 event1data.Add(*commands); 1144 break; 1145 1146 case NEED_STRUCTURE: 1147 btype1list.Add(*commands); 1148 break; 1149 1150 case NEED_INFANTRY: 1151 itype1list.Add(*commands); 1152 break; 1153 1154 case NEED_AIRCRAFT: 1155 atype1list.Add(*commands); 1156 break; 1157 1158 case NEED_UNIT: 1159 utype1list.Add(*commands); 1160 break; 1161 1162 default: 1163 break; 1164 } 1165 1166 /* 1167 ** Prepare the secondary event data field. 1168 */ 1169 htype2list.Remove(); 1170 way2data.Remove(); 1171 event2data.Remove(); 1172 btype2list.Remove(); 1173 itype2list.Remove(); 1174 atype2list.Remove(); 1175 utype2list.Remove(); 1176 ttype2list.Remove(); 1177 if (commands->Extract_Gadget(EVENT_LIST2)) { 1178 switch (Event_Needs(*event2list.Current_Item())) { 1179 case NEED_HOUSE: 1180 htype2list.Add(*commands); 1181 break; 1182 1183 case NEED_TEAM: 1184 ttype2list.Add(*commands); 1185 break; 1186 1187 case NEED_WAYPOINT: 1188 way2data.Add(*commands); 1189 break; 1190 1191 case NEED_TIME: 1192 case NEED_NUMBER: 1193 event2data.Add(*commands); 1194 break; 1195 1196 case NEED_STRUCTURE: 1197 btype2list.Add(*commands); 1198 break; 1199 1200 case NEED_INFANTRY: 1201 itype2list.Add(*commands); 1202 break; 1203 1204 case NEED_AIRCRAFT: 1205 atype2list.Add(*commands); 1206 break; 1207 1208 case NEED_UNIT: 1209 utype2list.Add(*commands); 1210 break; 1211 1212 default: 1213 break; 1214 } 1215 } 1216 1217 /* 1218 ** Setup the action buttons and associated data entry fields. 1219 */ 1220 actionbtn.Remove(); 1221 action2list.Remove(); 1222 if (eventflag == 3) { 1223 action2list.Add(*commands); 1224 } else { 1225 actionbtn.Add(*commands); 1226 if (actionflag) { 1227 actionbtn.Set_Text(TXT_TRIGGER_AND); 1228 action2list.Add(*commands); 1229 } else { 1230 actionbtn.Set_Text(TXT_TRIGGER_JUST_ACTION); 1231 } 1232 } 1233 1234 qlist1.Remove(); 1235 spc1.Remove(); 1236 htype3list.Remove(); 1237 booltype1list.Remove(); 1238 trtype1list.Remove(); 1239 way3data.Remove(); 1240 action1data.Remove(); 1241 ttype3list.Remove(); 1242 themetype1list.Remove(); 1243 soundtype1list.Remove(); 1244 movietype1list.Remove(); 1245 speechtype1list.Remove(); 1246 switch (Action_Needs(*action1list.Current_Item())) { 1247 case NEED_MOVIE: 1248 movietype1list.Add(*commands); 1249 break; 1250 1251 case NEED_SPECIAL: 1252 spc1.Add(*commands); 1253 break; 1254 1255 case NEED_HOUSE: 1256 htype3list.Add(*commands); 1257 break; 1258 1259 case NEED_BOOL: 1260 booltype1list.Add(*commands); 1261 break; 1262 1263 case NEED_TRIGGER: 1264 trtype1list.Add(*commands); 1265 break; 1266 1267 case NEED_TEAM: 1268 ttype3list.Add(*commands); 1269 break; 1270 1271 case NEED_NUMBER: 1272 action1data.Add(*commands); 1273 break; 1274 1275 case NEED_WAYPOINT: 1276 way3data.Add(*commands); 1277 break; 1278 1279 case NEED_THEME: 1280 themetype1list.Add(*commands); 1281 break; 1282 1283 case NEED_SOUND: 1284 soundtype1list.Add(*commands); 1285 break; 1286 1287 case NEED_SPEECH: 1288 speechtype1list.Add(*commands); 1289 break; 1290 1291 case NEED_QUARRY: 1292 qlist1.Add(*commands); 1293 break; 1294 } 1295 1296 qlist2.Remove(); 1297 spc2.Remove(); 1298 htype4list.Remove(); 1299 booltype2list.Remove(); 1300 trtype2list.Remove(); 1301 way4data.Remove(); 1302 action2data.Remove(); 1303 ttype4list.Remove(); 1304 themetype2list.Remove(); 1305 soundtype2list.Remove(); 1306 movietype2list.Remove(); 1307 speechtype2list.Remove(); 1308 if (commands->Extract_Gadget(ACTION_LIST2)) { 1309 switch (Action_Needs(*action2list.Current_Item())) { 1310 case NEED_MOVIE: 1311 movietype2list.Add(*commands); 1312 break; 1313 1314 case NEED_SPECIAL: 1315 spc2.Add(*commands); 1316 break; 1317 1318 case NEED_HOUSE: 1319 htype4list.Add(*commands); 1320 break; 1321 1322 case NEED_BOOL: 1323 booltype2list.Add(*commands); 1324 break; 1325 1326 case NEED_TRIGGER: 1327 trtype2list.Add(*commands); 1328 break; 1329 1330 case NEED_TEAM: 1331 ttype4list.Add(*commands); 1332 break; 1333 1334 case NEED_NUMBER: 1335 action2data.Add(*commands); 1336 break; 1337 1338 case NEED_WAYPOINT: 1339 way4data.Add(*commands); 1340 break; 1341 1342 case NEED_THEME: 1343 themetype2list.Add(*commands); 1344 break; 1345 1346 case NEED_SOUND: 1347 soundtype2list.Add(*commands); 1348 break; 1349 1350 case NEED_SPEECH: 1351 speechtype2list.Add(*commands); 1352 break; 1353 1354 case NEED_QUARRY: 1355 qlist2.Add(*commands); 1356 break; 1357 } 1358 } 1359 1360 /* 1361 ** Collapse any dropped down list boxes. 1362 */ 1363 spc1.Collapse(); 1364 spc2.Collapse(); 1365 qlist1.Collapse(); 1366 qlist2.Collapse(); 1367 htype1list.Collapse(); 1368 htype2list.Collapse(); 1369 htype3list.Collapse(); 1370 htype4list.Collapse(); 1371 ttype1list.Collapse(); 1372 ttype2list.Collapse(); 1373 ttype3list.Collapse(); 1374 ttype4list.Collapse(); 1375 btype1list.Collapse(); 1376 btype2list.Collapse(); 1377 utype1list.Collapse(); 1378 utype2list.Collapse(); 1379 itype1list.Collapse(); 1380 itype2list.Collapse(); 1381 atype1list.Collapse(); 1382 atype2list.Collapse(); 1383 trtype1list.Collapse(); 1384 trtype2list.Collapse(); 1385 action1list.Collapse(); 1386 action2list.Collapse(); 1387 event1list.Collapse(); 1388 event2list.Collapse(); 1389 housebtn.Collapse(); 1390 persbtn.Collapse(); 1391 booltype1list.Collapse(); 1392 booltype2list.Collapse(); 1393 themetype1list.Collapse(); 1394 themetype2list.Collapse(); 1395 soundtype1list.Collapse(); 1396 soundtype2list.Collapse(); 1397 movietype1list.Collapse(); 1398 movietype2list.Collapse(); 1399 speechtype1list.Collapse(); 1400 speechtype2list.Collapse(); 1401 commands->Flag_List_To_Redraw(); 1402 Show_Mouse(); 1403 display = false; 1404 // LogicPage->Unlock(); 1405 } 1406 1407 /* 1408 ** Get user input 1409 */ 1410 KeyNumType input = commands->Input(); 1411 1412 /* 1413 ** Process input 1414 */ 1415 switch (input) { 1416 case BUTTON_EVENT | KN_BUTTON: 1417 eventflag = (eventflag+1) % 4; 1418 display = true; 1419 break; 1420 1421 case BUTTON_ACTION | KN_BUTTON: 1422 actionflag = (actionflag == false); 1423 display = true; 1424 break; 1425 1426 case DATA_SPEECH1 | KN_BUTTON: 1427 Speak(VoxType(speechtype1list.Current_Index())); 1428 display = true; 1429 break; 1430 1431 case DATA_SPEECH2 | KN_BUTTON: 1432 Speak(VoxType(speechtype2list.Current_Index())); 1433 display = true; 1434 break; 1435 1436 case DATA_SOUND1 | KN_BUTTON: 1437 Sound_Effect(VocType(soundtype1list.Current_Index())); 1438 display = true; 1439 break; 1440 1441 case DATA_SOUND2 | KN_BUTTON: 1442 Sound_Effect(VocType(soundtype2list.Current_Index())); 1443 display = true; 1444 break; 1445 1446 /* 1447 ** Transfer all the necessary values from the edit fields into their 1448 ** respective positions within the trigger object. 1449 */ 1450 case KN_RETURN: 1451 case BUTTON_OK | KN_BUTTON: 1452 House = HousesType(housebtn.Current_Index()); 1453 IsPersistant = PersistantType(persbtn.Current_Index()); 1454 if (strlen(namebuf)==0) { 1455 Set_Name("____"); 1456 } else { 1457 Set_Name(namebuf); 1458 } 1459 1460 /* 1461 ** Primary event specific data retrieval. 1462 */ 1463 EventControl = MultiStyleType(eventflag); 1464 Event1.Event = *event1list.Current_Item(); 1465 switch (Event_Needs(Event1.Event)) { 1466 case NEED_HOUSE: 1467 Event1.Data.House = HousesType(htype1list.Current_Index()); 1468 break; 1469 1470 case NEED_TIME: 1471 Event1.Data.Value = atoi(event1data.Get_Text()); 1472 break; 1473 1474 case NEED_NUMBER: 1475 Event1.Data.Value = atoi(event1data.Get_Text()); 1476 break; 1477 1478 case NEED_STRUCTURE: 1479 Event1.Data.Structure = StructType(btype1list.Current_Index()); 1480 break; 1481 1482 case NEED_UNIT: 1483 Event1.Data.Unit = UnitType(utype1list.Current_Index()); 1484 break; 1485 1486 case NEED_INFANTRY: 1487 Event1.Data.Infantry = InfantryType(itype1list.Current_Index()); 1488 break; 1489 1490 case NEED_AIRCRAFT: 1491 Event1.Data.Aircraft = AircraftType(atype1list.Current_Index()); 1492 break; 1493 1494 case NEED_WAYPOINT: 1495 Event1.Data.Value = toupper(way1[0]) - 'A'; 1496 if (way1[1] != '\0') { 1497 Event1.Data.Value = (Event1.Data.Value+1)*26; 1498 Event1.Data.Value += toupper(way1[1]) - 'A'; 1499 } 1500 break; 1501 1502 case NEED_TEAM: 1503 Event1.Team = TeamTypeClass::From_Name(ttype1list.Current_Item()); 1504 break; 1505 } 1506 1507 /* 1508 ** Secondary event specific data retrieval. 1509 */ 1510 Event2.Event = *event2list.Current_Item(); 1511 switch (Event_Needs(Event2.Event)) { 1512 case NEED_HOUSE: 1513 Event2.Data.House = HousesType(htype2list.Current_Index()); 1514 break; 1515 1516 case NEED_TIME: 1517 Event2.Data.Value = atoi(event2data.Get_Text()); 1518 break; 1519 1520 case NEED_NUMBER: 1521 Event2.Data.Value = atoi(event2data.Get_Text()); 1522 break; 1523 1524 case NEED_STRUCTURE: 1525 Event2.Data.Structure = StructType(btype2list.Current_Index()); 1526 break; 1527 1528 case NEED_UNIT: 1529 Event2.Data.Unit = UnitType(utype2list.Current_Index()); 1530 break; 1531 1532 case NEED_INFANTRY: 1533 Event2.Data.Infantry = InfantryType(itype2list.Current_Index()); 1534 break; 1535 1536 case NEED_AIRCRAFT: 1537 Event2.Data.Aircraft = AircraftType(atype2list.Current_Index()); 1538 break; 1539 1540 case NEED_WAYPOINT: 1541 Event2.Data.Value = toupper(way2[0]) - 'A'; 1542 if (way2[1] != '\0') { 1543 Event2.Data.Value = (Event2.Data.Value+1)*26; 1544 Event2.Data.Value += toupper(way2[1]) - 'A'; 1545 } 1546 break; 1547 1548 case NEED_TEAM: 1549 Event2.Team = TeamTypeClass::As_Pointer(ttype2list.Current_Item()); 1550 break; 1551 } 1552 1553 /* 1554 ** Primary action data retrieval. 1555 */ 1556 ActionControl = MultiStyleType(actionflag); 1557 Action1.Action = *action1list.Current_Item(); 1558 switch (Action_Needs(Action1.Action)) { 1559 case NEED_SPECIAL: 1560 Action1.Data.Special = SpecialWeaponType(spc1.Current_Index()); 1561 break; 1562 1563 case NEED_HOUSE: 1564 Action1.Data.House = HousesType(htype3list.Current_Index()); 1565 break; 1566 1567 case NEED_TRIGGER: 1568 Action1.Trigger = TriggerTypeClass::From_Name(trtype1list.Current_Item()); 1569 break; 1570 1571 case NEED_TEAM: 1572 Action1.Team = TeamTypeClass::From_Name(ttype3list.Current_Item()); 1573 break; 1574 1575 case NEED_NUMBER: 1576 Action1.Data.Value = atoi(action1data.Get_Text()); 1577 break; 1578 1579 case NEED_WAYPOINT: 1580 Action1.Data.Value = toupper(way3[0]) - 'A'; 1581 if (way3[1] != '\0') { 1582 Action1.Data.Value = (Action1.Data.Value+1)*26; 1583 Action1.Data.Value += toupper(way3[1]) - 'A'; 1584 } 1585 break; 1586 1587 case NEED_BOOL: 1588 Action1.Data.Bool = booltype1list.Current_Index(); 1589 break; 1590 1591 case NEED_THEME: 1592 Action1.Data.Theme = ThemeType(themetype1list.Current_Index()); 1593 break; 1594 1595 case NEED_SOUND: 1596 Action1.Data.Sound = VocType(soundtype1list.Current_Index()); 1597 break; 1598 1599 case NEED_MOVIE: 1600 Action1.Data.Movie = VQType(movietype1list.Current_Index()); 1601 break; 1602 1603 case NEED_SPEECH: 1604 Action1.Data.Speech = VoxType(speechtype1list.Current_Index()); 1605 break; 1606 1607 case NEED_QUARRY: 1608 Action1.Data.Quarry = QuarryType(qlist1.Current_Index()); 1609 break; 1610 } 1611 1612 /* 1613 ** Secondary action data retrieval. 1614 */ 1615 Action2.Action = *action2list.Current_Item(); 1616 switch (Action_Needs(Action2.Action)) { 1617 case NEED_SPECIAL: 1618 Action2.Data.Special = SpecialWeaponType(spc2.Current_Index()); 1619 break; 1620 1621 case NEED_HOUSE: 1622 Action2.Data.House = HousesType(htype4list.Current_Index()); 1623 break; 1624 1625 case NEED_TRIGGER: 1626 Action2.Trigger = TriggerTypeClass::From_Name(trtype2list.Current_Item()); 1627 break; 1628 1629 case NEED_TEAM: 1630 Action2.Team = TeamTypeClass::From_Name(ttype4list.Current_Item()); 1631 break; 1632 1633 case NEED_NUMBER: 1634 Action2.Data.Value = atoi(action2data.Get_Text()); 1635 break; 1636 1637 case NEED_WAYPOINT: 1638 Action2.Data.Value = toupper(way4[0]) - 'A'; 1639 if (way4[1] != '\0') { 1640 Action2.Data.Value = (Action2.Data.Value+1)*26; 1641 Action2.Data.Value += toupper(way4[1]) - 'A'; 1642 } 1643 break; 1644 1645 case NEED_BOOL: 1646 Action2.Data.Bool = booltype2list.Current_Index(); 1647 break; 1648 1649 case NEED_THEME: 1650 Action2.Data.Theme = ThemeType(themetype2list.Current_Index()); 1651 break; 1652 1653 case NEED_MOVIE: 1654 Action2.Data.Movie = VQType(movietype2list.Current_Index()); 1655 break; 1656 1657 case NEED_SOUND: 1658 Action2.Data.Sound = VocType(soundtype2list.Current_Index()); 1659 break; 1660 1661 case NEED_SPEECH: 1662 Action2.Data.Speech = VoxType(speechtype2list.Current_Index()); 1663 break; 1664 1665 case NEED_QUARRY: 1666 Action2.Data.Quarry = QuarryType(qlist1.Current_Index()); 1667 break; 1668 } 1669 return(true); 1670 1671 case KN_ESC: 1672 case BUTTON_CANCEL | KN_BUTTON: 1673 process = false; 1674 1675 /* 1676 ** Always signal a redraw if any of the buttons were touched. This 1677 ** can be determined by examining the button bit flag in the input 1678 ** return value. 1679 */ 1680 default: 1681 if (input & KN_BUTTON) { 1682 display = true; 1683 } 1684 break; 1685 } 1686 } 1687 return(false); 1688 } 1689 #endif 1690 1691 1692 #if defined(CHEAT_KEYS) || defined(SCENARIO_EDITOR) 1693 /*********************************************************************************************** 1694 * TriggerTypeClass::Description -- Build a text description of the trigger type. * 1695 * * 1696 * This will build a (static) text description of the trigger type. Use this description * 1697 * when displaying this trigger in a list box. * 1698 * * 1699 * INPUT: none * 1700 * * 1701 * OUTPUT: Returns with a pointer to a one line text description of this trigger. * 1702 * * 1703 * WARNINGS: The pointer returned actually points to a static buffer. The pointer is only * 1704 * valid until this routine is called again. * 1705 * * 1706 * HISTORY: * 1707 * 07/09/1996 JLB : Created. * 1708 *=============================================================================================*/ 1709 char const * TriggerTypeClass::Description(void) const 1710 { 1711 static char _buffer[128]; 1712 1713 char special; 1714 switch (EventControl) { 1715 case MULTI_AND: 1716 special = '&'; 1717 break; 1718 1719 case MULTI_OR: 1720 special = '|'; 1721 break; 1722 1723 case MULTI_LINKED: 1724 special = '='; 1725 break; 1726 1727 default: 1728 special = '.'; 1729 break; 1730 } 1731 1732 char special2 = '.'; 1733 if (ActionControl == MULTI_AND) { 1734 special2 = '&'; 1735 } 1736 1737 char tbuf[32]; 1738 char const * added = ""; 1739 switch (Event_Needs(Event1.Event)) { 1740 case NEED_NUMBER: 1741 sprintf(tbuf, "%d", Event1.Data.Value); 1742 added = tbuf; 1743 break; 1744 1745 case NEED_UNIT: 1746 added = Text_String(UnitTypeClass::As_Reference(Event1.Data.Unit).Full_Name());; 1747 break; 1748 1749 case NEED_AIRCRAFT: 1750 added = Text_String(AircraftTypeClass::As_Reference(Event1.Data.Aircraft).Full_Name());; 1751 break; 1752 1753 case NEED_STRUCTURE: 1754 added = Text_String(BuildingTypeClass::As_Reference(Event1.Data.Structure).Full_Name()); 1755 break; 1756 1757 case NEED_INFANTRY: 1758 added = Text_String(InfantryTypeClass::As_Reference(Event1.Data.Infantry).Full_Name()); 1759 break; 1760 1761 case NEED_WAYPOINT: 1762 if (Event1.Data.Value < 26) { 1763 sprintf(tbuf, "'%c'", Event1.Data.Value + 'A'); 1764 } else { 1765 sprintf(tbuf, "'%c%c'", (Event1.Data.Value / 26) + 'A'-1, (Event1.Data.Value % 26) + 'A'); 1766 } 1767 added = tbuf; 1768 break; 1769 1770 default: 1771 break; 1772 } 1773 1774 /* 1775 ** Persistence indicator value. 1776 */ 1777 char pers = 'V'; 1778 if (IsPersistant == SEMIPERSISTANT) pers = 'S'; 1779 if (IsPersistant == PERSISTANT) pers = 'P'; 1780 1781 sprintf(_buffer, "%4.4s\t %s %c%c%c %s%s", 1782 IniName, 1783 HouseTypeClass::As_Reference(House).Suffix, 1784 pers, 1785 special, 1786 special2, 1787 Name_From_Event(Event1.Event), 1788 added); 1789 return(_buffer); 1790 } 1791 1792 #endif 1793 1794 1795 /*********************************************************************************************** 1796 * TriggerTypeClass::Attaches_To -- Determines what trigger can attach to. * 1797 * * 1798 * This routine will examine the trigger events and return with a composit bitfield that * 1799 * indicates what this trigger can be attached to. This is used for trigger placement * 1800 * and logic processing. * 1801 * * 1802 * INPUT: none * 1803 * * 1804 * OUTPUT: Returns with AttachType bitfield representing what this trigger can be attached * 1805 * to. * 1806 * * 1807 * WARNINGS: none * 1808 * * 1809 * HISTORY: * 1810 * 11/30/1995 JLB : Created. * 1811 *=============================================================================================*/ 1812 AttachType TriggerTypeClass::Attaches_To(void) const 1813 { 1814 AttachType attach = ::Attaches_To(Event1.Event); 1815 1816 if (EventControl != MULTI_ONLY) { 1817 attach = attach | ::Attaches_To(Event2.Event); 1818 } 1819 return(attach); 1820 } 1821 1822 1823 /*********************************************************************************************** 1824 * TriggerTypeClass::Read_INI -- reads triggers from the INI file * 1825 * * 1826 * INI entry format: * 1827 * Triggername = Eventname, Actionname, Data, Housename, TeamName, IsPersistant * 1828 * * 1829 * This routine reads in the triggers & creates them. Then, other classes can * 1830 * get pointers to the triggers they're linked to. * 1831 * * 1832 * The routine relies on the TeamTypeClasses already being loaded so it can resolve * 1833 * references to teams in this function. * 1834 * * 1835 * Cell Trigger pointers & IsTrigger flags are set in DisplayClass::Read_INI(), * 1836 * and cleared in the Map::Init() routine (which clears all cell objects to 0's). * 1837 * * 1838 * Object's pointers are set in: * 1839 * InfantryClass::Read_INI() * 1840 * BuildingClass::Read_INI() * 1841 * UnitClass::Read_INI() * 1842 * TerrainClass::Read_INI() * 1843 * The object trigger pointers are cleared in the ObjectClass constructor. * 1844 * * 1845 * The House's EMSListOf triggers is set in this routine, and cleared in the * 1846 * HouseClass::Init() routine. * 1847 * * 1848 * INPUT: * 1849 * buffer buffer to hold the INI data * 1850 * * 1851 * OUTPUT: * 1852 * none. * 1853 * * 1854 * WARNINGS: * 1855 * This function must be called before any other class's Read_INI. * 1856 * * 1857 * HISTORY: * 1858 * 11/28/1994 BR : Created. * 1859 *=============================================================================================*/ 1860 void TriggerTypeClass::Read_INI(CCINIClass & ini) 1861 { 1862 TriggerTypeClass *trigger; // Working trigger pointer. 1863 char buf[128]; 1864 1865 int len = ini.Entry_Count(INI_Name()); 1866 for (int index = 0; index < len; index++) { 1867 char const * entry = ini.Get_Entry(INI_Name(), index); 1868 1869 /* 1870 ** Create a new trigger. 1871 */ 1872 trigger = new TriggerTypeClass(); 1873 1874 /* 1875 ** Get the trigger entry. 1876 */ 1877 ini.Get_String(INI_Name(), entry, NULL, buf, sizeof(buf)); 1878 1879 /* 1880 ** Fill in the trigger. 1881 */ 1882 trigger->Fill_In((char *)entry, buf); 1883 } 1884 1885 if (NewINIFormat < 2) { 1886 /* 1887 ** Fix up the self-referential trigger pointers. 1888 */ 1889 for (int trig_index = 0; trig_index < TriggerTypes.Count(); trig_index++) { 1890 TriggerTypeClass * trigger = TriggerTypes.Ptr(trig_index); 1891 1892 char * ptr = (char *)trigger->Action1.Trigger.Raw(); 1893 if (ptr /*&& trigger->Action1.Trigger.Raw() != -1*/) { 1894 trigger->Action1.Trigger = TriggerTypeClass::From_Name(ptr); 1895 free(ptr); 1896 } 1897 1898 ptr = (char *)trigger->Action2.Trigger.Raw(); 1899 if (ptr /*&& trigger->Action2.Trigger.Raw() != -1*/) { 1900 trigger->Action2.Trigger = TriggerTypeClass::From_Name(ptr); 1901 free(ptr); 1902 } 1903 } 1904 } 1905 } 1906 1907 1908 /*********************************************************************************************** 1909 * TriggerTypeClass::Fill_In -- fills in trigger from the given INI entry * 1910 * * 1911 * This routine fills in the given trigger with the given name, and values from * 1912 * the given INI entry. * 1913 * * 1914 * (This routine is used by the scenario editor, to import teams from the MASTER.INI file.) * 1915 * * 1916 * INI entry format: * 1917 * Triggername = Eventname, Actionname, Data, Housename, TeamName, IsPersistant * 1918 * * 1919 * INPUT: * 1920 * name mnemonic for the desired trigger * 1921 * entry INI entry to parse * 1922 * * 1923 * OUTPUT: * 1924 * none. * 1925 * * 1926 * WARNINGS: * 1927 * none. * 1928 * * 1929 * HISTORY: * 1930 * 11/28/1994 BR : Created. * 1931 *=============================================================================================*/ 1932 void TriggerTypeClass::Fill_In(char * name, char * entry) 1933 { 1934 assert(TriggerTypes.ID(this) == ID); 1935 1936 /* 1937 ** Set its name. 1938 */ 1939 Set_Name(name); 1940 1941 IsPersistant = PersistantType(atoi(strtok(entry, ","))); 1942 House = HousesType(atoi(strtok(NULL, ","))); 1943 EventControl = MultiStyleType(atoi(strtok(NULL, ","))); 1944 ActionControl = MultiStyleType(atoi(strtok(NULL, ","))); 1945 1946 Event1.Read_INI(); 1947 Event2.Read_INI(); 1948 Action1.Read_INI(); 1949 Action2.Read_INI(); 1950 } 1951 1952 1953 /*********************************************************************************************** 1954 * TriggerTypeClass::Write_INI -- Stores all trigger types to the INI database specified. * 1955 * * 1956 * This routine will write out all trigger type objects to the INI database. Any existing * 1957 * trigger types in the database will be cleared out. * 1958 * * 1959 * INPUT: ini -- Reference to the INI database to have the trigger types added. * 1960 * * 1961 * OUTPUT: none * 1962 * * 1963 * WARNINGS: none * 1964 * * 1965 * HISTORY: * 1966 * 07/09/1996 JLB : Created. * 1967 *=============================================================================================*/ 1968 void TriggerTypeClass::Write_INI(CCINIClass & ini) 1969 { 1970 ini.Clear("Triggers"); 1971 ini.Clear(INI_Name()); 1972 1973 /* 1974 ** Now write all the trigger data out 1975 */ 1976 for (int index = 0; index < TriggerTypes.Count(); index++) { 1977 // for (int index = TriggerTypes.Count()-1; index >= 0; index--) { 1978 char buf[256]; 1979 TriggerTypeClass * trigger = TriggerTypes.Ptr(index); 1980 1981 trigger->Build_INI_Entry(buf); 1982 ini.Put_String(INI_Name(), trigger->IniName, buf); 1983 } 1984 } 1985 1986 1987 /*********************************************************************************************** 1988 * TriggerTypeClass::Build_INI_Entry -- Construct the INI entry into the buffer specified. * 1989 * * 1990 * This low level routine will take the information in this trigger type and store it * 1991 * into a buffer such that the resultant string can be stored into an INI database for * 1992 * later retrieval. * 1993 * * 1994 * INPUT: buffer -- Pointer to the buffer to store the INI entry string. * 1995 * * 1996 * OUTPUT: none * 1997 * * 1998 * WARNINGS: Be sure the buffer is big enough. Usually 128 bytes is more than sufficient. * 1999 * * 2000 * HISTORY: * 2001 * 07/09/1996 JLB : Created. * 2002 *=============================================================================================*/ 2003 void TriggerTypeClass::Build_INI_Entry(char * buffer) const 2004 { 2005 /* 2006 ** Build the root portion of the trigger event. 2007 */ 2008 sprintf(buffer, "%d,%d,%d,%d,", IsPersistant, House, EventControl, ActionControl); 2009 2010 /* 2011 ** Append the event and action values. 2012 */ 2013 buffer += strlen(buffer); 2014 Event1.Build_INI_Entry(buffer); 2015 2016 strcat(buffer, ","); 2017 buffer += strlen(buffer); 2018 Event2.Build_INI_Entry(buffer); 2019 2020 strcat(buffer, ","); 2021 buffer += strlen(buffer); 2022 Action1.Build_INI_Entry(buffer); 2023 2024 strcat(buffer, ","); 2025 buffer += strlen(buffer); 2026 Action2.Build_INI_Entry(buffer); 2027 } 2028 2029 2030 #if defined(CHEAT_KEYS) || defined(SCENARIO_EDITOR) 2031 /*********************************************************************************************** 2032 * TriggerTypeClass::Draw_It -- Draws this trigger as if it were a line in a list box. * 2033 * * 2034 * This routine is called when triggers are assigned to a list box and then must be drawn. * 2035 * It will display an identifying text string with as much information as is useful. * 2036 * * 2037 * INPUT: index -- The index number of this line in the list box. * 2038 * * 2039 * x,y -- The pixel coordinate of the upper left corner of the text box. * 2040 * * 2041 * width,height -- The dimensions of the text box to display the description in. * 2042 * * 2043 * selected -- Is this a selected line? If so, then it should be highlighted. * 2044 * * 2045 * flags -- The text print flags to use to display this text string. * 2046 * * 2047 * OUTPUT: none * 2048 * * 2049 * WARNINGS: none * 2050 * * 2051 * HISTORY: * 2052 * 07/09/1996 JLB : Created. * 2053 *=============================================================================================*/ 2054 void TriggerTypeClass::Draw_It(int , int x, int y, int width, int height, bool selected, TextPrintType flags) const 2055 { 2056 RemapControlType * scheme = GadgetClass::Get_Color_Scheme(); 2057 static int _tabs[] = {13,40}; 2058 if ((flags & 0x0F) == TPF_6PT_GRAD || (flags & 0x0F) == TPF_EFNT) { 2059 2060 if (selected) { 2061 flags = flags | TPF_BRIGHT_COLOR; 2062 LogicPage->Fill_Rect(x, y, x + width - 1, y + height - 1, scheme->Shadow); 2063 } else { 2064 if (!(flags & TPF_USE_GRAD_PAL)) { 2065 flags = flags | TPF_MEDIUM_COLOR; 2066 } 2067 } 2068 2069 Conquer_Clip_Text_Print(Description(), x, y, scheme, TBLACK, flags, width, _tabs); 2070 } else { 2071 Conquer_Clip_Text_Print(Description(), x, y, (selected ? &ColorRemaps[PCOLOR_DIALOG_BLUE] : &ColorRemaps[PCOLOR_GREY]), TBLACK, flags, width, _tabs); 2072 } 2073 } 2074 #endif 2075 2076 2077 /*********************************************************************************************** 2078 * TriggerTypeClass::Init -- Initialize the trigger type object management system. * 2079 * * 2080 * This routine should be called to initialize the trigger type object system. It should * 2081 * be called when clearing out a scenario. * 2082 * * 2083 * INPUT: none * 2084 * * 2085 * OUTPUT: none * 2086 * * 2087 * WARNINGS: All trigger types will be destroyed by this routine. * 2088 * * 2089 * HISTORY: * 2090 * 07/09/1996 JLB : Created. * 2091 *=============================================================================================*/ 2092 void TriggerTypeClass::Init(void) 2093 { 2094 TriggerTypes.Free_All(); 2095 } 2096 2097 2098 /*********************************************************************************************** 2099 * TriggerTypeClass::From_Name -- Convert an ASCII name into a trigger type pointer. * 2100 * * 2101 * Given just an ASCII representation of the trigger type, this routine will return with * 2102 * a pointer to the trigger type it refers to. Typical use of this is when parsing * 2103 * scenario INI files. * 2104 * * 2105 * INPUT: name -- Pointer to the name to use to identify the trigger type class object to * 2106 * be looked up. * 2107 * * 2108 * OUTPUT: Returns with a pointer to the trigger type class object that matches the name * 2109 * specified. If no match could be found, then NULL is returned. * 2110 * * 2111 * WARNINGS: none * 2112 * * 2113 * HISTORY: * 2114 * 07/09/1996 JLB : Created. * 2115 *=============================================================================================*/ 2116 TriggerTypeClass * TriggerTypeClass::From_Name(char const * name) 2117 { 2118 if (name != NULL) { 2119 for (int index = 0; index < TriggerTypes.Count(); index++) { 2120 if (stricmp(TriggerTypes.Ptr(index)->Name(), name) == 0) { 2121 return(TriggerTypes.Ptr(index)); 2122 } 2123 } 2124 } 2125 return(NULL); 2126 }