CnC_Remastered_Collection

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

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