TACTION.CPP (36070B)
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/TACTION.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 : ACTION.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : 11/28/95 * 28 * * 29 * Last Update : July 17, 1996 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * Action_From_Name -- retrieves ActionType for given name * 34 * Action_Needs -- Figures out what data an action object needs. * 35 * Name_From_Action -- retrieves name for ActionType * 36 * TActionClass::Build_INI_Entry -- Builds an INI entry for this trigger action. * 37 * TActionClass::Code_Pointers -- Convert embedded pointers into a transportable format. * 38 * TActionClass::Decode_Pointers -- Converts coded pointers into usable format. * 39 * TActionClass::Detach -- Removes any attachment from associated action. * 40 * TActionClass::Read_INI -- Converts INI text into appropriate action data. * 41 * TActionClass::operator -- Performs the action that this object does. * 42 * ActionChoiceClass::Draw_It -- Display the action choice as part of a list box. * 43 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 44 45 #include "function.h" 46 47 /* 48 ** New sidebar for GlyphX multiplayer. ST - 8/7/2019 10:10AM 49 */ 50 #include "SidebarGlyphx.h" 51 52 /* 53 ** These are the text names for the various actions. If the action name ends with "..." then 54 ** this means that additional data is probably required. 55 */ 56 static const char * ActionText[TACTION_COUNT] = { 57 "-No Action-", 58 "Winner is...", 59 "Loser is...", 60 "Production Begins", 61 "Create Team...", 62 "Destroy All Teams", 63 "All to Hunt...", 64 "Reinforcement (team)...", 65 "Drop Zone Flare (waypoint)...", 66 "Fire Sale...", 67 "Play Movie...", 68 "Text Trigger (ID num)...", 69 "Destroy Trigger...", 70 "Autocreate Begins...", 71 "~don't use~", 72 "Allow Win", 73 "Reveal all map", 74 "Reveal around waypoint...", 75 "Reveal zone of waypoint...", 76 "Play sound effect...", 77 "Play music theme...", 78 "Play speech...", 79 "Force Trigger...", 80 "Timer Start", 81 "Timer Stop", 82 "Timer Extend (1/10th min)...", 83 "Timer Shorten (1/10th min)...", 84 "Timer Set (1/10th min)...", 85 "Global Set...", 86 "Global Clear...", 87 "Auto Base Building...", 88 "Grow shroud one 'step'", 89 "Destroy attached building", 90 "Add 1-time special weapon...", 91 "Add repeating special weapon...", 92 "Preferred target...", 93 "Launch Nukes" 94 }; 95 96 97 ActionChoiceClass ActionChoices[TACTION_COUNT] = { 98 {TACTION_NONE}, 99 {TACTION_WIN}, 100 {TACTION_LOSE}, 101 {TACTION_BEGIN_PRODUCTION}, 102 {TACTION_CREATE_TEAM}, 103 {TACTION_DESTROY_TEAM}, 104 {TACTION_ALL_HUNT}, 105 {TACTION_REINFORCEMENTS}, 106 {TACTION_DZ}, 107 {TACTION_FIRE_SALE}, 108 {TACTION_PLAY_MOVIE}, 109 {TACTION_TEXT_TRIGGER}, 110 {TACTION_DESTROY_TRIGGER}, 111 {TACTION_AUTOCREATE}, 112 {TACTION_WINLOSE}, 113 {TACTION_ALLOWWIN}, 114 {TACTION_REVEAL_ALL}, 115 {TACTION_REVEAL_SOME}, 116 {TACTION_REVEAL_ZONE}, 117 {TACTION_PLAY_SOUND}, 118 {TACTION_PLAY_MUSIC}, 119 {TACTION_PLAY_SPEECH}, 120 {TACTION_FORCE_TRIGGER}, 121 {TACTION_START_TIMER}, 122 {TACTION_STOP_TIMER}, 123 {TACTION_ADD_TIMER}, 124 {TACTION_SUB_TIMER}, 125 {TACTION_SET_TIMER}, 126 {TACTION_SET_GLOBAL}, 127 {TACTION_CLEAR_GLOBAL}, 128 {TACTION_BASE_BUILDING}, 129 {TACTION_CREEP_SHADOW}, 130 {TACTION_DESTROY_OBJECT}, 131 {TACTION_1_SPECIAL}, 132 {TACTION_FULL_SPECIAL}, 133 {TACTION_PREFERRED_TARGET}, 134 {TACTION_LAUNCH_NUKES} 135 }; 136 137 138 /*********************************************************************************************** 139 * ActionChoiceClass::Draw_It -- Display the action choice as part of a list box. * 140 * * 141 * This is a support routine only used to display this object when it is part of a list * 142 * box. * 143 * * 144 * INPUT: x,y -- The coordinate (upper left) to display the description. * 145 * * 146 * width,height -- Dimensions of the area to display the description. * 147 * * 148 * selected -- Is this item highlighted? * 149 * * 150 * flags -- The text print flags to use. * 151 * * 152 * OUTPUT: none * 153 * * 154 * WARNINGS: none * 155 * * 156 * HISTORY: * 157 * 07/17/1996 JLB : Created. * 158 *=============================================================================================*/ 159 void ActionChoiceClass::Draw_It(int , int x, int y, int width, int height, bool selected, TextPrintType flags) const 160 { 161 RemapControlType * scheme = GadgetClass::Get_Color_Scheme(); 162 static int _tabs[] = {13,40}; 163 if ((flags & 0x0F) == TPF_6PT_GRAD || (flags & 0x0F) == TPF_EFNT) { 164 165 if (selected) { 166 flags = flags | TPF_BRIGHT_COLOR; 167 LogicPage->Fill_Rect(x, y, x + width - 1, y + height - 1, scheme->Shadow); 168 } else { 169 if (!(flags & TPF_USE_GRAD_PAL)) { 170 flags = flags | TPF_MEDIUM_COLOR; 171 } 172 } 173 174 Conquer_Clip_Text_Print(Description(), x, y, scheme, TBLACK, flags, width, _tabs); 175 } else { 176 Conquer_Clip_Text_Print(Description(), x, y, (selected ? &ColorRemaps[PCOLOR_DIALOG_BLUE] : &ColorRemaps[PCOLOR_GREY]), TBLACK, flags, width, _tabs); 177 } 178 } 179 180 181 /*********************************************************************************************** 182 * TActionClass::Detach -- Removes any attachment from associated action. * 183 * * 184 * This routine will remove any action reference to the team type specified. This routine * 185 * is called when the team type is being destroyed. All references to that team type must * 186 * also be severed. This routine does that with respect to trigger actions. * 187 * * 188 * INPUT: target-- The target object or type to remove from this taction object. * 189 * * 190 * OUTPUT: none * 191 * * 192 * WARNINGS: none * 193 * * 194 * HISTORY: * 195 * 02/22/1996 JLB : Created. * 196 *=============================================================================================*/ 197 void TActionClass::Detach(TARGET target) 198 { 199 if (Is_Target_TeamType(target) && Team == As_TeamType(target)) { 200 Team = NULL; 201 } 202 if (Is_Target_TriggerType(target) && Trigger == As_TriggerType(target)) { 203 Trigger = NULL; 204 } 205 } 206 207 208 /*********************************************************************************************** 209 * TActionClass::Build_INI_Entry -- Builds an INI entry for this trigger action. * 210 * * 211 * This routine will build the text (INI entry) format for the data of this trigger * 212 * action object. Typical use of this is when the INI file is being written. * 213 * * 214 * INPUT: ptr -- Pointer to the location to build the INI text to. The buffer is presumed * 215 * to be big enough. * 216 * * 217 * OUTPUT: none * 218 * * 219 * WARNINGS: The buffer passed to this routine must be big enough to hold the largest * 220 * text that will be created into it. * 221 * * 222 * HISTORY: * 223 * 02/22/1996 JLB : Created. * 224 *=============================================================================================*/ 225 void TActionClass::Build_INI_Entry(char * ptr) const 226 { 227 sprintf(ptr, "%d,%d,%d,%d", Action, TeamTypes.Logical_ID(Team), TriggerTypes.Logical_ID(Trigger), Data.Value); 228 } 229 230 231 /*********************************************************************************************** 232 * TActionClass::Read_INI -- Converts INI text into appropriate action data. * 233 * * 234 * This routine will convert INI data into the right values within this trigger action * 235 * object. Typical use of this routine is when the INI file is being read. It is the * 236 * counterpart to the Build_INI_Entry function. * 237 * * 238 * INPUT: none * 239 * * 240 * OUTPUT: none * 241 * * 242 * WARNINGS: none * 243 * * 244 * HISTORY: * 245 * 02/22/1996 JLB : Created. * 246 *=============================================================================================*/ 247 void TActionClass::Read_INI(void) 248 { 249 switch (NewINIFormat) { 250 default: 251 Action = TActionType(atoi(strtok(NULL, ","))); 252 Team.Set_Raw(atoi(strtok(NULL, ","))); 253 Trigger.Set_Raw(atoi(strtok(NULL, ","))); 254 Data.Value = atoi(strtok(NULL, ",")); 255 break; 256 257 case 1: 258 case 0: 259 Action = TActionType(atoi(strtok(NULL, ","))); 260 261 char const * ptr = strtok(NULL, ","); 262 Team = TeamTypeClass::From_Name(ptr); 263 assert(Action_Needs(Action) != NEED_TEAM || Team.Is_Valid()); 264 265 /* 266 ** Since triggers refer to other triggers, only record a copy of the trigger text 267 ** name. This will be fixed up later. 268 */ 269 Trigger.Set_Raw((long)strdup(strtok(NULL, ","))); 270 271 Data.Value = atoi(strtok(NULL, ",")); 272 break; 273 } 274 } 275 276 277 /*********************************************************************************************** 278 * TActionClass::Code_Pointers -- Convert embedded pointers into a transportable format. * 279 * * 280 * This routine is called prior to saving the game. It will convert any pointers into a * 281 * format that is safe for persistent storage. * 282 * * 283 * INPUT: none * 284 * * 285 * OUTPUT: none * 286 * * 287 * WARNINGS: This routine makes the object unfit for use. The Decode_Pointers() routine * 288 * must be called prior to using this object. * 289 * * 290 * HISTORY: * 291 * 02/22/1996 JLB : Created. * 292 *=============================================================================================*/ 293 void TActionClass::Code_Pointers(void) 294 { 295 } 296 297 298 /*********************************************************************************************** 299 * TActionClass::Decode_Pointers -- Converts coded pointers into usable format. * 300 * * 301 * This routine is called after a game has been loaded. The encoded pointers will be * 302 * converted back into usable format by this routine. * 303 * * 304 * INPUT: none * 305 * * 306 * OUTPUT: none * 307 * * 308 * WARNINGS: This routine will NOT work unless the pointer are, in fact, coded. There is * 309 * no prevention check to protect against calling this routine twice. * 310 * * 311 * HISTORY: * 312 * 02/22/1996 JLB : Created. * 313 *=============================================================================================*/ 314 void TActionClass::Decode_Pointers(void) 315 { 316 } 317 318 319 /*********************************************************************************************** 320 * TActionClass::operator -- Performs the action that this object does. * 321 * * 322 * This routine is called when the action associated with this action object must be * 323 * performed. Typically, this occurs when a trigger has "sprung" and now it must take * 324 * effect. The action object is what carries out this effect. * 325 * * 326 * INPUT: house -- The owner of this action. This information is necessary since some * 327 * actions depend on who the trigger was owned by. * 328 * * 329 * object-- Pointer to the object that the springing trigger was attached to. If * 330 * this parameter is null, then the trigger wasn't attached to any object. * 331 * * 332 * id -- Trigger ID (only if forced) otherwise -1. * 333 * * 334 * cell -- The cell this trigger is attached to (if any). * 335 * * 336 * OUTPUT: bool; Was this action able to perform what it needed to do? Failure could be * 337 * because a reinforcement couldn't be generated, for example. * 338 * * 339 * WARNINGS: none * 340 * * 341 * HISTORY: * 342 * 02/22/1996 JLB : Created. * 343 * 04/10/1996 JLB : Added the ID parameter. * 344 *=============================================================================================*/ 345 bool TActionClass::operator() (HousesType house, ObjectClass * object, int id, CELL cell) 346 { 347 /* 348 ** Otherwise, take an appropriate action. 349 */ 350 HouseClass * hptr = HouseClass::As_Pointer(house); 351 TriggerClass * trig = NULL; 352 if (id != -1) { 353 trig = Triggers.Raw_Ptr(id); 354 } 355 bool success = true; 356 // TeamTypeClass * ttype = Team; 357 358 /* 359 ** Ensure that the specified object is not actually dead. A dead object could 360 ** be passed to this routine in the case of a multiple event trigger that 361 ** had the first event kill the object. 362 */ 363 if (object && !object->IsActive) { 364 object = 0; 365 } 366 367 switch (Action) { 368 /* 369 ** Display a text message overlayed onto the tactical map. 370 */ 371 case TACTION_TEXT_TRIGGER: 372 Session.Messages.Add_Message(NULL, Data.Value, (char *)TutorialText[Data.Value], PCOLOR_GREEN, TPF_6PT_GRAD|TPF_USE_GRAD_PAL|TPF_FULLSHADOW, Rule.MessageDelay * TICKS_PER_MINUTE); 373 break; 374 375 /* 376 ** Launch nuclear missiles (duds) from all mslo's 377 */ 378 case TACTION_LAUNCH_NUKES: 379 { 380 for(int index = 0; index < Buildings.Count(); index++) { 381 BuildingClass *bldg = Buildings.Ptr(index); 382 if (*bldg == STRUCT_MSLO) { 383 bldg->Assign_Mission(MISSION_MISSILE); 384 } 385 } 386 break; 387 } 388 389 /* 390 ** Set the preferred target for the house. 391 */ 392 case TACTION_PREFERRED_TARGET: 393 if (hptr) { 394 hptr->PreferredTarget = Data.Quarry; 395 } 396 break; 397 398 /* 399 ** Initiate (or disable) the computer AI. When active, the computer will 400 ** build bases and units. 401 */ 402 case TACTION_BASE_BUILDING: 403 if (Data.Bool) { 404 hptr->IsBaseBuilding = true; 405 } else { 406 hptr->IsBaseBuilding = false; 407 } 408 break; 409 410 /* 411 ** Cause the shadow to creep back one step. 412 */ 413 case TACTION_CREEP_SHADOW: 414 Map.Encroach_Shadow(PlayerPtr); 415 break; 416 417 /* 418 ** Set a scenario global. 419 */ 420 case TACTION_SET_GLOBAL: 421 Scen.Set_Global_To(Data.Value, true); 422 break; 423 424 /* 425 ** Clear a scenario global. 426 */ 427 case TACTION_CLEAR_GLOBAL: 428 Scen.Set_Global_To(Data.Value, false); 429 break; 430 431 /* 432 ** Reveal the map around the area specified. 433 */ 434 case TACTION_REVEAL_SOME: 435 if (!PlayerPtr->IsVisionary) { 436 Map.Sight_From(Scen.Waypoint[Data.Value], Rule.GapShroudRadius, PlayerPtr, false); 437 } 438 break; 439 440 /* 441 ** Reveal all cells of the zone that the specified waypoint is located 442 ** in. This can be used to reveal whole islands or bodies of water 443 */ 444 case TACTION_REVEAL_ZONE: 445 if (!PlayerPtr->IsVisionary) { 446 int zone = Map[Scen.Waypoint[Data.Value]].Zones[MZONE_CRUSHER]; 447 448 for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { 449 if (Map[cell].Zones[MZONE_CRUSHER] == zone) { 450 Map.Map_Cell(cell, PlayerPtr); 451 } 452 } 453 454 } 455 break; 456 457 /* 458 ** Reveal the entire map. 459 */ 460 case TACTION_REVEAL_ALL: 461 if (!PlayerPtr->IsVisionary) { 462 PlayerPtr->IsVisionary = true; 463 for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) { 464 Map.Map_Cell(cell, PlayerPtr); 465 } 466 } 467 break; 468 469 /* 470 ** Star the mission timer. 471 */ 472 case TACTION_START_TIMER: 473 if (!Scen.MissionTimer.Is_Active()) { 474 Scen.MissionTimer.Start(); 475 Map.Redraw_Tab(); 476 } 477 break; 478 479 /* 480 ** Stop the mission timer. This will really just 481 ** suspend the timer. 482 */ 483 case TACTION_STOP_TIMER: 484 if (Scen.MissionTimer.Is_Active()) { 485 Scen.MissionTimer.Stop(); 486 Map.Redraw_Tab(); 487 } 488 break; 489 490 /* 491 ** Add time to the mission timer. 492 */ 493 case TACTION_ADD_TIMER: 494 Scen.MissionTimer = Scen.MissionTimer + (Data.Value * (TICKS_PER_MINUTE/10)); 495 Map.Redraw_Tab(); 496 break; 497 498 /* 499 ** Remove time from the mission timer. 500 */ 501 case TACTION_SUB_TIMER: 502 if ((int)Scen.MissionTimer <= Data.Value * (TICKS_PER_MINUTE/10)) { 503 Scen.MissionTimer = 0; 504 } else { 505 Scen.MissionTimer = Scen.MissionTimer - (Data.Value * (TICKS_PER_MINUTE/10)); 506 } 507 Map.Redraw_Tab(); 508 break; 509 510 /* 511 ** Set the mission timer to the value specified. 512 */ 513 case TACTION_SET_TIMER: 514 Scen.MissionTimer = Data.Value * (TICKS_PER_MINUTE/10); 515 Scen.MissionTimer.Start(); 516 Map.Redraw_Tab(); 517 break; 518 519 /* 520 ** Play a movie immediately. The game is temporarily 521 ** suspended while the movie plays. 522 */ 523 case TACTION_PLAY_MOVIE: 524 Hide_Mouse(); 525 SeenPage.Clear(); 526 Play_Movie(VQType(char(Data.Movie)), THEME_NONE, true, true); 527 GamePalette.Set(); 528 Map.Flag_To_Redraw(true); 529 Show_Mouse(); 530 break; 531 532 /* 533 ** Play a sound effect. 534 */ 535 case TACTION_PLAY_SOUND: 536 Sound_Effect(Data.Sound); 537 break; 538 539 /* 540 ** Play a musical theme. 541 */ 542 case TACTION_PLAY_MUSIC: 543 Theme.Queue_Song(Data.Theme); 544 break; 545 546 /* 547 ** Play the speech data specified. 548 */ 549 case TACTION_PLAY_SPEECH: 550 Speak(Data.Speech); 551 break; 552 553 /* 554 ** Give the special weapon to the house. 555 */ 556 case TACTION_1_SPECIAL: 557 case TACTION_FULL_SPECIAL: 558 hptr->SuperWeapon[Data.Special].Enable(Action==TACTION_1_SPECIAL, false); 559 // hptr->SuperWeapon[Data.Special].Forced_Charge(PlayerPtr == hptr); 560 561 // Add to Glyphx multiplayer sidebar. ST - 8/7/2019 10:13AM 562 if (Session.Type == GAME_GLYPHX_MULTIPLAYER) { 563 if (hptr->IsHuman) { 564 Sidebar_Glyphx_Add(RTTI_SPECIAL, Data.Special, hptr); 565 } 566 } 567 else { 568 if (PlayerPtr == hptr) { 569 Map.Add(RTTI_SPECIAL, Data.Special); 570 Map.Column[1].Flag_To_Redraw(); 571 } 572 } 573 break; 574 575 /* 576 ** Destroying a trigger means that all triggers of that type will be destroyed. 577 */ 578 case TACTION_DESTROY_TRIGGER: 579 if (Trigger.Is_Valid()) { 580 for (int index = 0; index < Triggers.Count(); index++) { 581 if (Triggers.Ptr(index)->Class == Trigger) { 582 Detach_This_From_All(Triggers.Ptr(index)->As_Target()); 583 delete Triggers.Ptr(index); 584 index--; 585 } 586 } 587 } 588 break; 589 590 /* 591 ** A forced trigger will force an existing trigger of that type or 592 ** will create a trigger of that type and then force it to be sprung. 593 */ 594 case TACTION_FORCE_TRIGGER: 595 if (Trigger.Is_Valid()) { 596 Find_Or_Make(Trigger)->Spring(TEVENT_ANY, 0, 0, true); 597 } 598 break; 599 600 /* 601 ** Place a smoke marker at the waypoint specified. 602 */ 603 case TACTION_DZ: 604 new AnimClass(ANIM_LZ_SMOKE, Cell_Coord(Scen.Waypoint[Data.Value])); 605 break; 606 607 /* 608 ** Flag the house specified as the winner. Really the house value 609 ** is only used to determine if it is the player or the computer. 610 */ 611 case TACTION_WIN: 612 if (Data.House == PlayerPtr->Class->House) { 613 PlayerPtr->Flag_To_Win(); 614 } else { 615 PlayerPtr->Flag_To_Lose(); 616 } 617 break; 618 619 /* 620 ** Flag the house specified as the loser. The house parameter is only 621 ** used to determine if it refers to the player or the computer. 622 */ 623 case TACTION_LOSE: 624 if (Data.House != PlayerPtr->Class->House) { 625 PlayerPtr->Flag_To_Win(); 626 } else { 627 PlayerPtr->Flag_To_Lose(); 628 } 629 break; 630 631 /* 632 ** This will enable production to begin for the house specified. 633 */ 634 case TACTION_BEGIN_PRODUCTION: 635 if (Data.House != HOUSE_NONE) { 636 HouseClass * specified_house = HouseClass::As_Pointer(Data.House); 637 specified_house->Begin_Production(); 638 } 639 break; 640 641 /* 642 ** Cause all buildings to be sold and all units to go into 643 ** hunt mode. 644 */ 645 case TACTION_FIRE_SALE: 646 if (Data.House != HOUSE_NONE) { 647 HouseClass * specified_house = HouseClass::As_Pointer(Data.House); 648 specified_house->State = STATE_ENDGAME; 649 } 650 break; 651 652 /* 653 ** Begin the team autocreate logic for the house specified. 654 */ 655 case TACTION_AUTOCREATE: 656 if (Data.House != HOUSE_NONE) { 657 HouseClass * specified_house = HouseClass::As_Pointer(Data.House); 658 specified_house->IsAlerted = true; 659 } 660 break; 661 662 /* 663 ** Manually create the team specified. 664 */ 665 case TACTION_CREATE_TEAM: 666 ScenarioInit++; 667 Team->Create_One_Of(); 668 ScenarioInit--; 669 break; 670 671 /* 672 ** Destroy all teams of the type specified. 673 */ 674 case TACTION_DESTROY_TEAM: 675 Team->Destroy_All_Of(); 676 break; 677 678 /* 679 ** Create a reinforcement of the team specified. 680 */ 681 case TACTION_REINFORCEMENTS: 682 success = Do_Reinforcements(&*Team); 683 break; 684 685 /* 686 ** Force all units of the house specified to go into 687 ** hunt mode. 688 */ 689 case TACTION_ALL_HUNT: 690 HouseClass::As_Pointer(Data.House)->Do_All_To_Hunt(); 691 break; 692 693 /* 694 ** This will destroy all objects that this trigger is 695 ** attached to. 696 */ 697 case TACTION_DESTROY_OBJECT: 698 if (object) { 699 int damage = object->Strength; 700 object->Take_Damage(damage, 0, WARHEAD_AP, 0, true); 701 } else { 702 success = false; 703 } 704 705 /* 706 ** If the trigger is attached to a bridge, then the bridge 707 ** gets destroyed regardless of whether the trigger was a 708 ** forced or natural spring event. 709 */ 710 if (cell != 0) { 711 Map.Destroy_Bridge_At(cell); 712 } 713 714 /* 715 ** Loop through and destroy all objects that have this trigger 716 ** attached to them. 717 */ 718 if (trig) { 719 for (int u_index = 0; u_index < Units.Count(); u_index++) { 720 UnitClass * unit = Units.Ptr(u_index); 721 722 if (unit && unit->Trigger == trig) { 723 unit->Trigger = NULL; 724 int damage = unit->Strength; 725 unit->Take_Damage(damage, 0, WARHEAD_AP, 0, true); 726 } 727 } 728 729 for (int i_index = 0; i_index < Infantry.Count(); i_index++) { 730 InfantryClass * infantry = Infantry.Ptr(i_index); 731 732 if (infantry && infantry->Trigger == trig) { 733 infantry->Trigger = NULL; 734 int damage = infantry->Strength; 735 infantry->Take_Damage(damage, 0, WARHEAD_AP, 0, true); 736 } 737 } 738 739 for (int a_index = 0; a_index < Aircraft.Count(); a_index++) { 740 AircraftClass * aircraft = Aircraft.Ptr(a_index); 741 742 if (aircraft && aircraft->Trigger == trig) { 743 aircraft->Trigger = NULL; 744 int damage = aircraft->Strength; 745 aircraft->Take_Damage(damage, 0, WARHEAD_AP, 0, true); 746 } 747 } 748 749 for (int b_index = 0; b_index < Buildings.Count(); b_index++) { 750 BuildingClass * building = Buildings.Ptr(b_index); 751 752 if (building && building->Trigger == trig) { 753 building->Trigger = NULL; 754 int damage = building->Strength; 755 building->Take_Damage(damage, 0, WARHEAD_AP, 0, true); 756 } 757 } 758 } 759 break; 760 761 /* 762 ** Do no action at all. 763 */ 764 case TACTION_NONE: 765 default: 766 break; 767 } 768 return(success); 769 } 770 771 772 /*********************************************************************************************** 773 * Action_From_Name -- retrieves ActionType for given name * 774 * * 775 * INPUT: * 776 * name name to get ActionType for * 777 * * 778 * OUTPUT: * 779 * ActionType for given name * 780 * * 781 * WARNINGS: * 782 * none. * 783 * * 784 * HISTORY: * 785 * 11/29/1994 BR : Created. * 786 *=============================================================================================*/ 787 TActionType Action_From_Name (char const * name) 788 { 789 if (name == NULL) { 790 return(TACTION_NONE); 791 } 792 793 for (TActionType i = TACTION_NONE; i < TACTION_COUNT; i++) { 794 if (!stricmp(name, ActionText[i])) { 795 return(i); 796 } 797 } 798 799 return(TACTION_NONE); 800 } 801 802 803 /*********************************************************************************************** 804 * Name_From_Action -- retrieves name for ActionType * 805 * * 806 * INPUT: * 807 * action ActionType to get name for * 808 * * 809 * OUTPUT: * 810 * name of ActionType * 811 * * 812 * WARNINGS: * 813 * none. * 814 * * 815 * HISTORY: * 816 * 11/29/1994 BR : Created. * 817 *=============================================================================================*/ 818 char const * Name_From_Action(TActionType action) 819 { 820 return(ActionText[action]); 821 } 822 823 824 /*********************************************************************************************** 825 * Action_Needs -- Figures out what data an action object needs. * 826 * * 827 * Use this routine to determine what extra data is needed for the specified action. This * 828 * data will be prompted for in the scenario editor. * 829 * * 830 * INPUT: action -- The action that is to be queried. * 831 * * 832 * OUTPUT: Returns with the data type (enumeration) needed for this action type. * 833 * * 834 * WARNINGS: none * 835 * * 836 * HISTORY: * 837 * 02/22/1996 JLB : Created. * 838 *=============================================================================================*/ 839 NeedType Action_Needs(TActionType action) 840 { 841 switch (action) { 842 case TACTION_1_SPECIAL: 843 case TACTION_FULL_SPECIAL: 844 return(NEED_SPECIAL); 845 846 case TACTION_FIRE_SALE: 847 case TACTION_WIN: 848 case TACTION_LOSE: 849 case TACTION_ALL_HUNT: 850 case TACTION_BEGIN_PRODUCTION: 851 case TACTION_AUTOCREATE: 852 return(NEED_HOUSE); 853 854 case TACTION_BASE_BUILDING: 855 return(NEED_BOOL); 856 857 case TACTION_CREATE_TEAM: 858 case TACTION_DESTROY_TEAM: 859 case TACTION_REINFORCEMENTS: 860 return(NEED_TEAM); 861 862 case TACTION_FORCE_TRIGGER: 863 case TACTION_DESTROY_TRIGGER: 864 return(NEED_TRIGGER); 865 866 case TACTION_DZ: 867 return(NEED_WAYPOINT); 868 869 case TACTION_REVEAL_SOME: 870 case TACTION_REVEAL_ZONE: 871 return(NEED_WAYPOINT); 872 873 case TACTION_PLAY_MUSIC: 874 return(NEED_THEME); 875 876 case TACTION_PLAY_MOVIE: 877 return(NEED_MOVIE); 878 879 case TACTION_PLAY_SOUND: 880 return(NEED_SOUND); 881 882 case TACTION_PLAY_SPEECH: 883 return(NEED_SPEECH); 884 885 case TACTION_TEXT_TRIGGER: 886 case TACTION_ADD_TIMER: 887 case TACTION_SUB_TIMER: 888 case TACTION_SET_TIMER: 889 case TACTION_SET_GLOBAL: 890 case TACTION_CLEAR_GLOBAL: 891 return(NEED_NUMBER); 892 893 case TACTION_PREFERRED_TARGET: 894 return(NEED_QUARRY); 895 896 default: 897 break; 898 } 899 return(NEED_NONE); 900 } 901 902