CnC_Remastered_Collection

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

TRIGGER.CPP (64079B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header:   F:\projects\c&c\vcs\code\trigger.cpv   2.17   16 Oct 1995 16:51:20   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 : TRIGGER.CPP                                                  *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : 11/12/94                                                     *
     28  *                                                                                             *
     29  *                  Last Update : August 27, 1995 [JLB]                                        *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   Do_All_To_Hunt -- Forces all computer controlled units into hunt mode.                    *
     34  *   TriggerClass::Action_From_Name -- retrieves ActionType for given name                     *
     35  *   TriggerClass::Action_Need_Team -- Determines if this action event requires a team.        *
     36  *   TriggerClass::As_Pointer -- returns pointer for the given trigger name                    *
     37  *   TriggerClass::As_Target -- Converts trigger to a target value                             *
     38  *   TriggerClass::Event_From_Name -- retrieves EventType for given name                       *
     39  *   TriggerClass::Event_Need_Data -- Determines if this event requires a data value.          *
     40  *   TriggerClass::Event_Need_House -- Determines if this event requires a house identifier.   *
     41  *   TriggerClass::Event_Need_Object -- Determines if the specified event requires an object.  *
     42  *   TriggerClass::Init -- clears triggers for new scenario                                    *
     43  *   TriggerClass::Name_From_Action -- retrieves name for ActionType                           *
     44  *   TriggerClass::Name_From_Event -- retrieves name for EventType                             *
     45  *   TriggerClass::Read_INI -- reads triggers from the INI file                                *
     46  *   TriggerClass::Remove -- removes this trigger from the game                                *
     47  *   TriggerClass::Spring -- Trigger processing routine for cell-based triggers                *
     48  *   TriggerClass::Spring -- Trigger processing routine for house-based triggers               *
     49  *   TriggerClass::Spring -- Trigger processing routine for object-based triggers              *
     50  *   TriggerClass::TriggerClass -- constructor                                                 *
     51  *   TriggerClass::Validate -- validates trigger pointer													  *
     52  *   TriggerClass::Write_INI -- writes triggers to the INI file                                *
     53  *   TriggerClass::operator delete -- 'delete' operator                                        *
     54  *   TriggerClass::operator new -- 'new' operator                                              *
     55  *   TriggerClass::~TriggerClass -- Destructor for trigger objects.                            *
     56  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     57 
     58 #include "function.h"
     59 
     60 static void Do_All_To_Hunt(void);
     61 
     62 #define	FIXUP		0
     63 
     64 /*
     65 ********************************** Globals **********************************
     66 */
     67 static const char * EventText[EVENT_COUNT + 1] = {
     68 	"None",
     69 	"Player Enters",
     70 	"Discovered",
     71 	"Attacked",
     72 	"Destroyed",
     73 	"Any",
     74 	"House Discov.",
     75 	"Units Destr.",
     76 	"Bldgs Destr.",
     77 	"All Destr.",
     78 	"Credits",
     79 	"Time",
     80 	"# Bldgs Dstr.",
     81 	"# Units Dstr.",
     82 	"No Factories",
     83 	"Civ. Evac.",
     84 	"Built It"
     85 };
     86 
     87 
     88 static const char * ActionText[TriggerClass::ACTION_COUNT + 1] = {
     89 	"None",
     90 	"Win",
     91 	"Lose",
     92 	"Production",
     93 	"Create Team",
     94 	"Dstry Teams",
     95 	"All to Hunt",
     96 	"Reinforce.",
     97 	"DZ at 'Z'",
     98 	"Airstrike",
     99 	"Nuclear Missile",
    100 	"Ion Cannon",
    101 	"Dstry Trig 'XXXX'",
    102 	"Dstry Trig 'YYYY'",
    103 	"Dstry Trig 'ZZZZ'",
    104 	"Autocreate",
    105 	"Cap=Win/Des=Lose",
    106 	"Allow Win"
    107 };
    108 
    109 
    110 /***********************************************************************************************
    111  * TriggerClass::Validate -- validates trigger pointer													  *
    112  *                                                                                             *
    113  * INPUT:                                                                                      *
    114  *		none.																												  *
    115  *                                                                                             *
    116  * OUTPUT:                                                                                     *
    117  *		1 = ok, 0 = error																								  *
    118  *                                                                                             *
    119  * WARNINGS:                                                                                   *
    120  *		none.																												  *
    121  *                                                                                             *
    122  * HISTORY:                                                                                    *
    123  *   08/09/1995 BRR : Created.                                                                 *
    124  *=============================================================================================*/
    125 #ifdef CHEAT_KEYS
    126 int TriggerClass::Validate(void) const
    127 {
    128 	int num;
    129 
    130 	num = Triggers.ID(this);
    131 	if (num < 0 || num >= TRIGGER_MAX) {
    132 		Validate_Error("TRIGGER");
    133 		return (0);
    134 	}
    135 	else
    136 		return (1);
    137 }
    138 #else
    139 #define	Validate()
    140 #endif
    141 
    142 
    143 /***********************************************************************************************
    144  * TriggerClass::Event_Need_Object -- Determines if the specified event requires an object.    *
    145  *                                                                                             *
    146  *    This routine determines if the specified event must be attached to an object. Such       *
    147  *    events can only exist in a parasitic fashion attached to object(s) in the game.          *
    148  *                                                                                             *
    149  * INPUT:   event -- The event type to examine.                                                *
    150  *                                                                                             *
    151  * OUTPUT:  Does the specified event require attachement to an object?                         *
    152  *                                                                                             *
    153  * WARNINGS:   none                                                                            *
    154  *                                                                                             *
    155  * HISTORY:                                                                                    *
    156  *   08/27/1995 JLB : Created.                                                                 *
    157  *=============================================================================================*/
    158 bool TriggerClass::Event_Need_Object(EventType event)
    159 {
    160 	switch (event) {
    161 		case EVENT_PLAYER_ENTERED:
    162 		case EVENT_DISCOVERED:
    163 		case EVENT_ATTACKED:
    164 		case EVENT_DESTROYED:
    165 		case EVENT_ANY:
    166 			return(true);
    167 	}
    168 	return(false);
    169 }
    170 
    171 
    172 /***********************************************************************************************
    173  * TriggerClass::Event_Need_House -- Determines if this event requires a house identifier.     *
    174  *                                                                                             *
    175  *    This routine is used to determine if the specified event requires a house identifier.    *
    176  *    All trigger events that affect a house will require a house identifier.                  *
    177  *                                                                                             *
    178  * INPUT:   event -- The event type to examine.                                                *
    179  *                                                                                             *
    180  * OUTPUT:  Does the specified event type require a house identifier?                          *
    181  *                                                                                             *
    182  * WARNINGS:   none                                                                            *
    183  *                                                                                             *
    184  * HISTORY:                                                                                    *
    185  *   08/27/1995 JLB : Created.                                                                 *
    186  *=============================================================================================*/
    187 bool TriggerClass::Event_Need_House(EventType event)
    188 {
    189 	switch (event) {
    190 		case EVENT_PLAYER_ENTERED:
    191 		case EVENT_HOUSE_DISCOVERED:
    192 		case EVENT_UNITS_DESTROYED:
    193 		case EVENT_BUILDINGS_DESTROYED:
    194 		case EVENT_ALL_DESTROYED:
    195 		case EVENT_CREDITS:
    196 		case EVENT_TIME:
    197 		case EVENT_NBUILDINGS_DESTROYED:
    198 		case EVENT_NUNITS_DESTROYED:
    199 		case EVENT_NOFACTORIES:
    200 		case EVENT_EVAC_CIVILIAN:
    201 		case EVENT_BUILD:
    202 			return(true);
    203 	}
    204 	return(false);
    205 }
    206 
    207 
    208 /***********************************************************************************************
    209  * TriggerClass::Event_Need_Data -- Determines if this event requires a data value.            *
    210  *                                                                                             *
    211  *    This routine will determine if the specified event requires a data number parameter.     *
    212  *    This is commonly needed for trigger events.                                              *
    213  *                                                                                             *
    214  * INPUT:   event -- The event to examine.                                                     *
    215  *                                                                                             *
    216  * OUTPUT:  Does the specified event require a data number parameter?                          *
    217  *                                                                                             *
    218  * WARNINGS:   none                                                                            *
    219  *                                                                                             *
    220  * HISTORY:                                                                                    *
    221  *   08/27/1995 JLB : Created.                                                                 *
    222  *=============================================================================================*/
    223 bool TriggerClass::Event_Need_Data(EventType event)
    224 {
    225 	switch (event) {
    226 		case EVENT_CREDITS:
    227 		case EVENT_TIME:
    228 		case EVENT_NBUILDINGS_DESTROYED:
    229 		case EVENT_NUNITS_DESTROYED:
    230 		case EVENT_BUILD:
    231 			return(true);
    232 	}
    233 	return(false);
    234 }
    235 
    236 
    237 /***********************************************************************************************
    238  * TriggerClass::Action_Need_Team -- Determines if this action event requires a team.          *
    239  *                                                                                             *
    240  *    This routine will determine if the specified action requires a team name parameter.      *
    241  *    Typically, this is needed for reinforcements or other trigger events that affect         *
    242  *    a particular team type.                                                                  *
    243  *                                                                                             *
    244  * INPUT:   action   -- The action that is to be examined.                                     *
    245  *                                                                                             *
    246  * OUTPUT:  Does the specified action require a team type name?                                *
    247  *                                                                                             *
    248  * WARNINGS:   none                                                                            *
    249  *                                                                                             *
    250  * HISTORY:                                                                                    *
    251  *   08/27/1995 JLB : Created.                                                                 *
    252  *=============================================================================================*/
    253 bool TriggerClass::Action_Need_Team(TriggerClass::ActionType action)
    254 {
    255 	switch (action) {
    256 		case ACTION_CREATE_TEAM:
    257 		case ACTION_DESTROY_TEAM:
    258 		case ACTION_REINFORCEMENTS:
    259 			return(true);
    260 	}
    261 	return(false);
    262 }
    263 
    264 
    265 /***********************************************************************************************
    266  * TriggerClass::TriggerClass -- constructor                                                   *
    267  *                                                                                             *
    268  * INPUT:                                                                                      *
    269  *      none.                                                                                  *
    270  *                                                                                             *
    271  * OUTPUT:                                                                                     *
    272  *      none.                                                                                  *
    273  *                                                                                             *
    274  * WARNINGS:                                                                                   *
    275  *      none.                                                                                  *
    276  *                                                                                             *
    277  * HISTORY:                                                                                    *
    278  *   11/28/1994 BR : Created.                                                                  *
    279  *=============================================================================================*/
    280 TriggerClass::TriggerClass(void)
    281 {
    282 	IsPersistant = VOLATILE;
    283 	AttachCount = 0;
    284 	Event = EVENT_NONE;
    285 	Action = ACTION_NONE;
    286 	House = HOUSE_NONE;
    287 	DataCopy = Data = 0L;
    288 	Name[0] = '\0';
    289 	Team = NULL;
    290 }
    291 
    292 
    293 /***********************************************************************************************
    294  * TriggerClass::~TriggerClass -- Destructor for trigger objects.                              *
    295  *                                                                                             *
    296  *    This destructor will update the house blockage value if necessary. No other action need  *
    297  *    be performed on trigger destruction.                                                     *
    298  *                                                                                             *
    299  * INPUT:   none                                                                               *
    300  *                                                                                             *
    301  * OUTPUT:  none                                                                               *
    302  *                                                                                             *
    303  * WARNINGS:   none                                                                            *
    304  *                                                                                             *
    305  * HISTORY:                                                                                    *
    306  *   07/29/1995 JLB : Created.                                                                 *
    307  *=============================================================================================*/
    308 TriggerClass::~TriggerClass(void)
    309 {
    310 	if (GameActive && House != HOUSE_NONE && Action == ACTION_ALLOWWIN) {
    311 		if (Houses.Ptr(House)->Blockage) Houses.Ptr(House)->Blockage--;
    312 		Houses.Ptr(House)->BorrowedTime = TICKS_PER_SECOND*4;
    313 	}
    314 }
    315 
    316 
    317 /***********************************************************************************************
    318  * TriggerClass::Init -- clears triggers for new scenario                                      *
    319  *                                                                                             *
    320  * INPUT:                                                                                      *
    321  *      none.                                                                                  *
    322  *                                                                                             *
    323  * OUTPUT:                                                                                     *
    324  *      none.                                                                                  *
    325  *                                                                                             *
    326  * WARNINGS:                                                                                   *
    327  *      none.                                                                                  *
    328  *                                                                                             *
    329  * HISTORY:                                                                                    *
    330  *   11/29/1994 BR : Created.                                                                  *
    331  *=============================================================================================*/
    332 void TriggerClass::Init(void)
    333 {
    334 	Triggers.Free_All();
    335 }
    336 
    337 
    338 /***********************************************************************************************
    339  * TriggerClass::Spring -- Trigger processing routine                                          *
    340  *                                                                                             *
    341  * Checks whether this trigger should "spring" for the given event & object;                   *
    342  * If it should, then some really cool undocumented stuff magically happens.                   *
    343  *                                                                                             *
    344  * INPUT:                                                                                      *
    345  *      event      EventType: What happened?                                                   *
    346  *      object   Ptr to object containing this trigger: What did it happen to?                 *
    347  *                                                                                             *
    348  * OUTPUT:                                                                                     *
    349  *      0 = nothing happened; 1 = the trigger was sprung                                       *
    350  *                                                                                             *
    351  * WARNINGS:                                                                                   *
    352  *      none.                                                                                  *
    353  *                                                                                             *
    354  * HISTORY:                                                                                    *
    355  *   12/06/1994 BR : Created.                                                                  *
    356  *   06/25/1995 JLB : Added more trigger events.                                               *
    357  *=============================================================================================*/
    358 bool TriggerClass::Spring(EventType event, ObjectClass *obj)
    359 {
    360 	Validate();
    361 	/*
    362 	**	If this is not the event for this trigger, just return.
    363 	*/
    364 	if (event != Event && Event != EVENT_ANY) {
    365 		return(false);
    366 	}
    367 
    368 	/*
    369 	**	If time-based, decrement the minute counter; return if it's not time yet
    370 	*/
    371 	if (Event == EVENT_TIME) {
    372 		Data--;
    373 		if (Data > 0) {
    374 			return(false);
    375 		}
    376 		Data = DataCopy;
    377 	}
    378 
    379 	/*
    380 	**	Semi-persistant trigger: first detach it from the calling object, then
    381 	**	see if this is the last object we're attached to; if so, the trigger
    382 	**	will spring.
    383 	*/
    384 	if (IsPersistant == SEMIPERSISTANT) {
    385 
    386 		/*
    387 		** Detach ourselves from the object
    388 		*/
    389 		obj->Trigger = NULL;
    390 
    391 		/*
    392 		** Decrement our attachment counter
    393 		*/
    394 		AttachCount--;
    395 
    396 		/*
    397 		** If we're attached to more objects, don't spring; otherwise, spring.
    398 		** And, mark ourselves as volatile so we'll completely remove ourselves
    399 		** from the game after we go off.
    400 		*/
    401 		if (AttachCount > 0) {
    402 			return(false);
    403 		} else {
    404 			IsPersistant = VOLATILE;
    405 		}
    406 	}
    407 
    408 	/*
    409 	**	Otherwise, take an appropriate action.
    410 	*/
    411 	bool success = true;
    412 	TriggerClass * trig = NULL;
    413 	switch (Action) {
    414 		case ACTION_NUKE:
    415 			HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Enable(true, false);
    416 			HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Forced_Charge(PlayerPtr->Class->House == HOUSE_BAD);
    417 			break;
    418 
    419 		case ACTION_ION:
    420 			HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Enable(true, false);
    421 			HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Forced_Charge(PlayerPtr->Class->House == HOUSE_GOOD);
    422 			break;
    423 
    424 		case ACTION_WINLOSE:
    425 			switch (event) {
    426 				case EVENT_DESTROYED:
    427 					if (!PlayerPtr->IsToWin || PlayerPtr->Blockage > 0) PlayerPtr->Flag_To_Lose();
    428 					success = true;
    429 					break;
    430 
    431 				case EVENT_PLAYER_ENTERED:
    432 					if (!PlayerPtr->IsToLose) PlayerPtr->Flag_To_Win();
    433 					success = true;
    434 					break;
    435 
    436 				default:
    437 					success = false;
    438 					break;
    439 			}
    440 			break;
    441 
    442 		case ACTION_DESTROY_XXXX:
    443 			trig = As_Pointer("XXXX");
    444 			if (trig) {
    445 				trig->Remove();
    446 			}
    447 			delete trig;
    448 			break;
    449 
    450 		case ACTION_DESTROY_YYYY:
    451 			trig = As_Pointer("YYYY");
    452 			if (trig) {
    453 				trig->Remove();
    454 			}
    455 			delete trig;
    456 			break;
    457 
    458 		case ACTION_DESTROY_ZZZZ:
    459 			trig = As_Pointer("ZZZZ");
    460 			if (trig) {
    461 				trig->Remove();
    462 			}
    463 			delete trig;
    464 			break;
    465 
    466 		case ACTION_AIRSTRIKE:
    467 			PlayerPtr->IsAirstrikePending = true;
    468 //			PlayerPtr->Make_Air_Strike_Available(true);
    469 			break;
    470 
    471 		case ACTION_DZ:
    472 			new AnimClass(ANIM_LZ_SMOKE, Cell_Coord(Waypoint[25]));
    473 			break;
    474 
    475 		case ACTION_NONE:
    476 			break;
    477 
    478 		case ACTION_WIN:
    479 			PlayerPtr->Flag_To_Win();
    480 			break;
    481 
    482 		case ACTION_LOSE:
    483 			PlayerPtr->Flag_To_Lose();
    484 			break;
    485 
    486 		case ACTION_BEGIN_PRODUCTION:
    487 			HouseClass::As_Pointer(House)->Begin_Production();
    488 			break;
    489 
    490 		case ACTION_AUTOCREATE:
    491 			if (obj && obj->Is_Techno()) {
    492 				((TechnoClass *)obj)->House->IsAlerted = true;
    493 			}
    494 			break;
    495 
    496 		case ACTION_CREATE_TEAM:
    497 			if (Team) {
    498 				ScenarioInit++;
    499 				Team->Create_One_Of();
    500 				ScenarioInit--;
    501 			}
    502 			break;
    503 
    504 		case ACTION_DESTROY_TEAM:
    505 			if (Team) {
    506 				Team->Destroy_All_Of();
    507 			}
    508 			break;
    509 
    510 		case ACTION_REINFORCEMENTS:
    511 			if (Team) {
    512 				success = Do_Reinforcements(Team);
    513 			}
    514 			break;
    515 
    516 		case ACTION_ALL_HUNT:
    517 			Do_All_To_Hunt();
    518 			break;
    519 
    520 		default:
    521 			break;
    522 	}
    523 
    524 	if (!success && Event == EVENT_TIME) Data = 1;
    525 
    526 	/*
    527 	**	Remove trigger from the game.
    528 	*/
    529 	if (success && IsPersistant == VOLATILE) {
    530 		Remove();
    531 	}
    532 
    533 	return(true);
    534 }
    535 
    536 
    537 /***********************************************************************************************
    538  * TriggerClass::Spring -- Trigger processing routine                                          *
    539  *                                                                                             *
    540  * This version of Spring is for cell-based triggers.                                          *
    541  *                                                                                             *
    542  * INPUT:                                                                                      *
    543  *      data      elapsed time, or credits, depending on what 'Event' is.                      *
    544  *                                                                                             *
    545  * OUTPUT:                                                                                     *
    546  *      0 = nothing happened; 1 = the trigger was sprung                                       *
    547  *                                                                                             *
    548  * WARNINGS:                                                                                   *
    549  *      none.                                                                                  *
    550  *                                                                                             *
    551  * HISTORY:                                                                                    *
    552  *   12/06/1994 BR : Created.                                                                  *
    553  *=============================================================================================*/
    554 bool TriggerClass::Spring(EventType event, CELL cell)
    555 {
    556 	Validate();
    557 	/*
    558 	**	If this is not the event for this trigger, just return.
    559 	*/
    560 	if (event != Event) {
    561 		return(false);
    562 	}
    563 
    564 	/*
    565 	**	If time-based, decrement the minute counter; return if it's not time yet
    566 	*/
    567 	if (Event == EVENT_TIME) {
    568 		Data--;
    569 		if (Data > 0) {
    570 			return(false);
    571 		}
    572 		Data = DataCopy;
    573 	}
    574 
    575 	/*
    576 	**	Semi-persistant trigger: first detach it from the calling cell, then
    577 	**	see if this is the last cell we're attached to; if so, the trigger
    578 	**	will spring.
    579 	*/
    580 	if (IsPersistant == SEMIPERSISTANT) {
    581 
    582 		/*
    583 		** Detach ourselves from the cell
    584 		*/
    585 		Map[cell].IsTrigger = 0;
    586 
    587 		/*
    588 		** Decrement our attachment counter
    589 		*/
    590 		AttachCount--;
    591 
    592 		/*
    593 		** If we're attached to more cells, don't spring; otherwise, spring.
    594 		** And, mark ourselves as volatile so we'll completely remove ourselves
    595 		** from the game after we go off.
    596 		*/
    597 		if (AttachCount > 0) {
    598 			return(false);
    599 		} else {
    600 			IsPersistant = VOLATILE;
    601 		}
    602 	}
    603 
    604 	/*
    605 	**	Otherwise, take an appropriate action.
    606 	*/
    607 	bool success = true;
    608 	TriggerClass * trig = NULL;
    609 	int index;
    610 	switch (Action) {
    611 		case ACTION_NUKE:
    612 			HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Enable(true, false);
    613 			HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Forced_Charge(PlayerPtr->Class->House == HOUSE_BAD);
    614 			break;
    615 
    616 		case ACTION_ION:
    617 			HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Enable(true, false);
    618 			HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Forced_Charge(PlayerPtr->Class->House == HOUSE_GOOD);
    619 			break;
    620 
    621 		case ACTION_AUTOCREATE:
    622 			for (index = 0; index < Houses.Count(); index++) {
    623 				Houses.Ptr(index)->IsAlerted = true;
    624 			}
    625 			break;
    626 
    627 		case ACTION_DESTROY_XXXX:
    628 			trig = As_Pointer("XXXX");
    629 			if (trig) {
    630 				trig->Remove();
    631 			}
    632 			delete trig;
    633 			break;
    634 
    635 		case ACTION_DESTROY_YYYY:
    636 			trig = As_Pointer("YYYY");
    637 			if (trig) {
    638 				trig->Remove();
    639 			}
    640 			delete trig;
    641 			break;
    642 
    643 		case ACTION_DESTROY_ZZZZ:
    644 			trig = As_Pointer("ZZZZ");
    645 			if (trig) {
    646 				trig->Remove();
    647 			}
    648 			delete trig;
    649 			break;
    650 
    651 		case ACTION_AIRSTRIKE:
    652 			HouseClass::As_Pointer(House)->AirStrike.Enable(false, true);
    653 			if (House == PlayerPtr->Class->House) {
    654 				PlayerPtr->AirStrike.Forced_Charge(true);
    655 				Map.Add(RTTI_SPECIAL, SPC_AIR_STRIKE);
    656 				Map.Column[1].Flag_To_Redraw();
    657 			}
    658 //			PlayerPtr->Make_Air_Strike_Available(true);
    659 			break;
    660 
    661 		case ACTION_DZ:
    662 			new AnimClass(ANIM_LZ_SMOKE, Cell_Coord(Waypoint[25]));
    663 			break;
    664 
    665 		case ACTION_NONE:
    666 			break;
    667 
    668 		case ACTION_WIN:
    669 			PlayerPtr->Flag_To_Win();
    670 			break;
    671 
    672 		case ACTION_LOSE:
    673 			PlayerPtr->Flag_To_Lose();
    674 			break;
    675 
    676 		case ACTION_BEGIN_PRODUCTION:
    677 			if (PlayerPtr->Class->House == HOUSE_GOOD) {
    678 				HouseClass::As_Pointer(HOUSE_BAD)->Begin_Production();
    679 			} else {
    680 				HouseClass::As_Pointer(HOUSE_GOOD)->Begin_Production();
    681 			}
    682 			break;
    683 
    684 		case ACTION_CREATE_TEAM:
    685 			if (Team) {
    686 				ScenarioInit++;
    687 				Team->Create_One_Of();
    688 				ScenarioInit--;
    689 			}
    690 			break;
    691 
    692 		case ACTION_DESTROY_TEAM:
    693 			if (Team) {
    694 				Team->Destroy_All_Of();
    695 			}
    696 			break;
    697 
    698 		case ACTION_REINFORCEMENTS:
    699 			if (Team) {
    700 				success = Do_Reinforcements(Team);
    701 			}
    702 			break;
    703 
    704 		case ACTION_ALL_HUNT:
    705 			Do_All_To_Hunt();
    706 			break;
    707 
    708 		default:
    709 			break;
    710 	}
    711 
    712 	if (!success && Event == EVENT_TIME) Data = 1;
    713 
    714 	/*
    715 	**	Remove trigger from the game.
    716 	*/
    717 	if (success && IsPersistant == VOLATILE) {
    718 		Remove();
    719 	}
    720 
    721 	return(true);
    722 }
    723 
    724 
    725 /***********************************************************************************************
    726  * TriggerClass::Spring -- Trigger processing routine                                          *
    727  *                                                                                             *
    728  * This version of Spring is for house-specific triggers.                                      *
    729  * For a time-based trigger, 'data' will the the current TickCount.                            *
    730  * For a credit-based trigger, 'data' will be the credits for the HouseClass                   *
    731  * containing this trigger.                                                                    *
    732  *                                                                                             *
    733  * INPUT:                                                                                      *
    734  *      event      the event that happened                                                     *
    735  *      house      house that this event relates to                                            *
    736  *      data      elapsed time, or credits, depending on what 'Event' is.                      *
    737  *                                                                                             *
    738  * OUTPUT:                                                                                     *
    739  *      0 = nothing happened; 1 = the trigger was sprung                                       *
    740  *                                                                                             *
    741  * WARNINGS:                                                                                   *
    742  *      none.                                                                                  *
    743  *                                                                                             *
    744  * HISTORY:                                                                                    *
    745  *   12/06/1994 BR : Created.                                                                  *
    746  *   06/25/1995 JLB : Added more trigger events.                                               *
    747  *=============================================================================================*/
    748 bool TriggerClass::Spring(EventType event, HousesType house, long data)
    749 {
    750 	Validate();
    751 	/*
    752 	**	If this is not the event for this trigger, just return.
    753 	*/
    754 	if (event != Event || house != House) {
    755 		return(false);
    756 	}
    757 
    758 	/*
    759 	**	If credits-based, check 'data'
    760 	*/
    761 	if (Event == EVENT_CREDITS && data < Data) {
    762 		return(false);
    763 	}
    764 
    765 	/*
    766 	**	Building event check to ensure that the building number matches.
    767 	*/
    768 	if (Event == EVENT_BUILD && data != Data) {
    769 		return(false);
    770 	}
    771 
    772 	/*
    773 	**	Number of objects destroyed checker. If the data supplied indicates that
    774 	**	the correct number of objects have been destroyed, then this trigger
    775 	**	will succeed.
    776 	*/
    777 	if (Event == EVENT_NBUILDINGS_DESTROYED || Event == EVENT_NUNITS_DESTROYED) {
    778 		if (data < Data) {
    779 			return(false);
    780 		}
    781 	}
    782 
    783 	/*
    784 	**	If time-based, decrement the minute counter; return if it's not time yet
    785 	*/
    786 	if (Event == EVENT_TIME) {
    787 		Data--;
    788 		if (Data > 0) {
    789 			return(false);
    790 		}
    791 		Data = DataCopy;
    792 	}
    793 
    794 	/*
    795 	**	The trigger has gone off; take appropriate action
    796 	*/
    797 	bool success = true;
    798 	TriggerClass * trig = NULL;
    799 	switch (Action) {
    800 
    801 		case ACTION_NUKE:
    802 			HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Enable(true, false);
    803 			HouseClass::As_Pointer(HOUSE_BAD)->NukeStrike.Forced_Charge(PlayerPtr->Class->House == HOUSE_BAD);
    804 			break;
    805 
    806 		case ACTION_ION:
    807 			HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Enable(true, false);
    808 			HouseClass::As_Pointer(HOUSE_GOOD)->IonCannon.Forced_Charge(PlayerPtr->Class->House == HOUSE_GOOD);
    809 			break;
    810 
    811 		/*
    812 		**	This will remove a blockage to the win condition. No action need
    813 		**	be performed here since the act of deleting the trigger will
    814 		**	remove the blockage.
    815 		*/
    816 		case ACTION_ALLOWWIN:
    817 			break;
    818 
    819 		case ACTION_AUTOCREATE:
    820 			HouseClass::As_Pointer(House)->IsAlerted = true;
    821 			break;
    822 
    823 		case ACTION_DESTROY_XXXX:
    824 			trig = As_Pointer("XXXX");
    825 			if (trig) {
    826 				trig->Remove();
    827 			}
    828 			delete trig;
    829 			break;
    830 
    831 		case ACTION_DESTROY_YYYY:
    832 			trig = As_Pointer("YYYY");
    833 			if (trig) {
    834 				trig->Remove();
    835 			}
    836 			delete trig;
    837 			break;
    838 
    839 		case ACTION_DESTROY_ZZZZ:
    840 			trig = As_Pointer("ZZZZ");
    841 			if (trig) {
    842 				trig->Remove();
    843 			}
    844 			delete trig;
    845 			break;
    846 
    847 		case ACTION_AIRSTRIKE:
    848 			PlayerPtr->AirStrike.Enable(false, true);
    849 			if (House == PlayerPtr->Class->House) {
    850 				PlayerPtr->AirStrike.Forced_Charge(true);
    851 				Map.Add(RTTI_SPECIAL, SPC_AIR_STRIKE);
    852 				Map.Column[1].Flag_To_Redraw();
    853 			}
    854 			break;
    855 
    856 		case ACTION_NONE:
    857 			break;
    858 
    859 		case ACTION_DZ:
    860 			new AnimClass(ANIM_LZ_SMOKE, Cell_Coord(Waypoint[25]));
    861 			break;
    862 
    863 		case ACTION_WIN:
    864 			PlayerPtr->Flag_To_Win();
    865 			break;
    866 
    867 		case ACTION_LOSE:
    868 			PlayerPtr->Flag_To_Lose();
    869 			break;
    870 
    871 		case ACTION_BEGIN_PRODUCTION:
    872 			HouseClass::As_Pointer(House)->Begin_Production();
    873 			break;
    874 
    875 		case ACTION_CREATE_TEAM:
    876 			if (Team) {
    877 				ScenarioInit++;
    878 				Team->Create_One_Of();
    879 				ScenarioInit--;
    880 			}
    881 			break;
    882 
    883 		case ACTION_DESTROY_TEAM:
    884 			if (Team) {
    885 				Team->Destroy_All_Of();
    886 			}
    887 			break;
    888 
    889 		case ACTION_REINFORCEMENTS:
    890 			if (Team) {
    891 				success = Do_Reinforcements(Team);
    892 			}
    893 			break;
    894 
    895 		case ACTION_ALL_HUNT:
    896 			Do_All_To_Hunt();
    897 			break;
    898 
    899 		default:
    900 			break;
    901 	}
    902 
    903 	if (!success && Event == EVENT_TIME) Data = 1;
    904 
    905 	/*
    906 	**	Remove trigger from the game.
    907 	*/
    908 	if (success && IsPersistant == VOLATILE) {
    909 		Remove();
    910 	}
    911 
    912 	return(true);
    913 }
    914 
    915 
    916 /***********************************************************************************************
    917  * TriggerClass::Remove -- removes this trigger from the game                                  *
    918  *                                                                                             *
    919  * INPUT:                                                                                      *
    920  *      none.                                                                                  *
    921  *                                                                                             *
    922  * OUTPUT:                                                                                     *
    923  *      1 = trigger was removed, 0 = it wasn't                                                 *
    924  *                                                                                             *
    925  * WARNINGS:                                                                                   *
    926  *      none.                                                                                  *
    927  *                                                                                             *
    928  * HISTORY:                                                                                    *
    929  *   12/06/1994 BR : Created.                                                                  *
    930  *=============================================================================================*/
    931 bool TriggerClass::Remove(void)
    932 {
    933 	Validate();
    934 	CELL cell;
    935 	HousesType h;
    936 	int index;
    937 
    938 	/*
    939 	**	Loop through all cells; remove any reference to this trigger
    940 	*/
    941 	for (cell = 0; cell < MAP_CELL_TOTAL; cell++) {
    942 		if (Map[cell].IsTrigger) {
    943 			if (CellTriggers[cell] == this) {
    944 				Map[cell].IsTrigger = 0;
    945 				CellTriggers[cell] = NULL;
    946 			}
    947 		}
    948 	}
    949 
    950 	/*
    951 	**	Loop through all objects, removing any reference to this trigger
    952 	*/
    953 	for (index = 0; index < Infantry.Count(); index++) {
    954 		if (Infantry.Ptr(index)->Trigger == this) {
    955 			Infantry.Ptr(index)->Trigger = NULL;
    956 		}
    957 	}
    958 	for (index = 0; index < Buildings.Count(); index++) {
    959 		if (Buildings.Ptr(index)->Trigger == this) {
    960 			Buildings.Ptr(index)->Trigger = NULL;
    961 		}
    962 	}
    963 	for (index = 0; index < Units.Count(); index++) {
    964 		if (Units.Ptr(index)->Trigger == this) {
    965 			Units.Ptr(index)->Trigger = NULL;
    966 		}
    967 	}
    968 	for (index = 0; index < Terrains.Count(); index++) {
    969 		if (Terrains.Ptr(index)->Trigger == this) {
    970 			Terrains.Ptr(index)->Trigger = NULL;
    971 		}
    972 	}
    973 
    974 	/*
    975 	**	Remove this trigger from any house list it's in. Invoking '-=' with a
    976 	**	pointer not in the list has no effect; loop through all houses just to
    977 	**	be on the safe side.
    978 	*/
    979 	for (h = HOUSE_FIRST; h < HOUSE_COUNT; h++) {
    980 		HouseTriggers[h].Delete(this);
    981 	}
    982 
    983 	delete this;
    984 
    985 	return(true);
    986 }
    987 
    988 
    989 /***********************************************************************************************
    990  * TriggerClass::Read_INI -- reads triggers from the INI file                                  *
    991  *                                                                                             *
    992  *    INI entry format:                                                                        *
    993  *      Triggername = Eventname, Actionname, Data, Housename, TeamName, IsPersistant           *
    994  *                                                                                             *
    995  * This routine reads in the triggers & creates them. Then, other classes can                  *
    996  * get pointers to the triggers they're linked to.                                             *
    997  *                                                                                             *
    998  * The routine relies on the TeamTypeClasses already being loaded so it can resolve            *
    999  * references to teams in this function.                                                       *
   1000  *                                                                                             *
   1001  * Cell Trigger pointers & IsTrigger flags are set in DisplayClass::Read_INI(),                *
   1002  * and cleared in the Map::Init() routine (which clears all cell objects to 0's).              *
   1003  *                                                                                             *
   1004  * Object's pointers are set in:                                                               *
   1005  *      InfantryClass::Read_INI()                                                              *
   1006  *      BuildingClass::Read_INI()                                                              *
   1007  *      UnitClass::Read_INI()                                                                  *
   1008  *      TerrainClass::Read_INI()                                                               *
   1009  * The object trigger pointers are cleared in the ObjectClass constructor.                     *
   1010  *                                                                                             *
   1011  * The House's EMSListOf triggers is set in this routine, and cleared in the                   *
   1012  * HouseClass::Init() routine.                                                                 *
   1013  *                                                                                             *
   1014  * INPUT:                                                                                      *
   1015  *      buffer      buffer to hold the INI data                                                *
   1016  *                                                                                             *
   1017  * OUTPUT:                                                                                     *
   1018  *      none.                                                                                  *
   1019  *                                                                                             *
   1020  * WARNINGS:                                                                                   *
   1021  *      This function must be called before any other class's Read_INI.                        *
   1022  *                                                                                             *
   1023  * HISTORY:                                                                                    *
   1024  *   11/28/1994 BR : Created.                                                                  *
   1025  *=============================================================================================*/
   1026 void TriggerClass::Read_INI(char *buffer)
   1027 {
   1028 	TriggerClass *trigger;				// Working trigger pointer.
   1029 	char *tbuffer;							// Accumulation buffer of trigger IDs.
   1030 	int len;									// Length of data in buffer.
   1031 	char buf[128];
   1032 
   1033 	/*
   1034 	**	Set 'tbuffer' to point just past the INI buffer
   1035 	*/
   1036 	len = strlen(buffer) + 2;
   1037 	tbuffer = buffer + len;
   1038 
   1039 	/*
   1040 	**	Read all TRIGGER entry names into 'tbuffer'
   1041 	*/
   1042 	WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer);
   1043 
   1044 	/*
   1045 	**	Loop for all trigger entries.
   1046 	*/
   1047 	while (*tbuffer != '\0') {
   1048 
   1049 		/*
   1050 		**	Create a new trigger.
   1051 		*/
   1052 		trigger = new TriggerClass();
   1053 
   1054 		/*
   1055 		**	Set its name.
   1056 		*/
   1057 		trigger->Set_Name (tbuffer);
   1058 
   1059 		/*
   1060 		**	Get the trigger entry.
   1061 		*/
   1062 		WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer);
   1063 
   1064 		/*
   1065 		**	Fill in the trigger.
   1066 		*/
   1067 		trigger->Fill_In(tbuffer,buf);
   1068 
   1069 		/*
   1070 		**	Add 'trigger' to the House's list.
   1071 		*/
   1072 //		if (trigger->House != HOUSE_NONE && trigger->Event != EVENT_PLAYER_ENTERED) {
   1073 //		if (Event_Need_House(trigger->Event) && !Event_Need_Object(trigger->Event)) {
   1074 		if (trigger->House != HOUSE_NONE) {
   1075 			if (trigger->Action == ACTION_ALLOWWIN) HouseClass::As_Pointer(trigger->House)->Blockage++;
   1076 			HouseTriggers[trigger->House].Add(trigger);
   1077 			trigger->AttachCount++;
   1078 		}
   1079 
   1080 		/*
   1081 		**	Go to next entry.
   1082 		*/
   1083 		tbuffer += strlen(tbuffer)+1;
   1084 	}
   1085 }
   1086 
   1087 
   1088 /***********************************************************************************************
   1089  * TriggerClass::Fill_In -- fills in trigger from the given INI entry                          *
   1090  *                                                                                             *
   1091  * This routine fills in the given trigger with the given name, and values from                *
   1092  * the given INI entry.                                                                        *
   1093  *                                                                                             *
   1094  * (This routine is used by the scenario editor, to import teams from the MASTER.INI file.)    *
   1095  *                                                                                             *
   1096  *    INI entry format:                                                                        *
   1097  *      Triggername = Eventname, Actionname, Data, Housename, TeamName, IsPersistant           *
   1098  *                                                                                             *
   1099  * INPUT:                                                                                      *
   1100  *      name      mnemonic for the desired trigger                                             *
   1101  *      entry      INI entry to parse                                                          *
   1102  *                                                                                             *
   1103  * OUTPUT:                                                                                     *
   1104  *      none.                                                                                  *
   1105  *                                                                                             *
   1106  * WARNINGS:                                                                                   *
   1107  *      none.                                                                                  *
   1108  *                                                                                             *
   1109  * HISTORY:                                                                                    *
   1110  *   11/28/1994 BR : Created.                                                                  *
   1111  *=============================================================================================*/
   1112 void TriggerClass::Fill_In(char * name, char *entry)
   1113 {
   1114 	Validate();
   1115 	char *p;
   1116 
   1117 	/*
   1118 	**	Set its name.
   1119 	*/
   1120 	Set_Name(name);
   1121 
   1122 	/*
   1123 	**	1st token: Event.
   1124 	*/
   1125 	Event = Event_From_Name(strtok(entry, ","));
   1126 
   1127 	/*
   1128 	**	2nd token: Action.
   1129 	*/
   1130 	Action = Action_From_Name(strtok(NULL, ","));
   1131 
   1132 	/*
   1133 	**	3rd token: Data.
   1134 	*/
   1135 	DataCopy = Data = atol(strtok(NULL, ","));
   1136 
   1137 	/*
   1138 	**	4th token: House.
   1139 	*/
   1140 	House = HouseTypeClass::From_Name(strtok(NULL, ","));
   1141 	if (House == HOUSE_NONE && Event == EVENT_PLAYER_ENTERED) {
   1142 		House = PlayerPtr->Class->House;
   1143 	}
   1144 
   1145 	/*
   1146 	**	5th token: Team.
   1147 	*/
   1148 	Team = TeamTypeClass::As_Pointer(strtok(NULL, ","));
   1149 
   1150 	/*
   1151 	** 6th token: IsPersistant.  This token was added later, so we must check
   1152 	** for its existence.
   1153 	*/
   1154 	p = strtok(NULL, ",");
   1155 	if (p) {
   1156 		IsPersistant = (PersistantType)atoi(p);
   1157 	} else {
   1158 		IsPersistant = VOLATILE;
   1159 	}
   1160 }
   1161 
   1162 
   1163 /***********************************************************************************************
   1164  * TriggerClass::Write_INI -- writes triggers to the INI file                                  *
   1165  *                                                                                             *
   1166  *    INI entry format:                                                                        *
   1167  *      Triggername = Eventname, Actionname, Data, Housename, TeamName, IsPersistant           *
   1168  *                                                                                             *
   1169  * INPUT:                                                                                      *
   1170  *      buffer      buffer to hold the INI data                                                *
   1171  *                                                                                             *
   1172  * OUTPUT:                                                                                     *
   1173  *      none.                                                                                  *
   1174  *                                                                                             *
   1175  * WARNINGS:                                                                                   *
   1176  *      none.                                                                                  *
   1177  *                                                                                             *
   1178  * HISTORY:                                                                                    *
   1179  *   11/28/1994 BR : Created.                                                                  *
   1180  *=============================================================================================*/
   1181 void TriggerClass::Write_INI(char *buffer, bool refresh)
   1182 {
   1183 	int index;
   1184 	char buf[128];
   1185 	TriggerClass *trigger;
   1186 	char const *hname;
   1187 	char const *tname;
   1188 
   1189 	/*
   1190 	**	First, clear out all existing trigger data from the INI file.
   1191 	*/
   1192 	if (refresh) {
   1193 		WWWritePrivateProfileString(INI_Name(), NULL, NULL, buffer);
   1194 	}
   1195 
   1196 	/*
   1197 	**	Now write all the trigger data out
   1198 	*/
   1199 	for (index = 0; index < Triggers.Count(); index++) {
   1200 
   1201 		/*
   1202 		**	Get ptr to next active trigger.
   1203 		*/
   1204 		trigger = Triggers.Ptr(index);
   1205 
   1206 		/*
   1207 		**	Generate INI entry.
   1208 		*/
   1209 		if (trigger->House==HOUSE_NONE) {
   1210 			hname = "None";
   1211 		} else {
   1212 			hname = HouseClass::As_Pointer(trigger->House)->Class->IniName;
   1213 		}
   1214 
   1215 		if (trigger->Team==NULL) {
   1216 			tname = "None";
   1217 		} else {
   1218 			tname = trigger->Team->IniName;
   1219 		}
   1220 
   1221 		sprintf(buf,"%s,%s,%ld,%s,%s,%d",
   1222 			TriggerClass::Name_From_Event(trigger->Event),
   1223 			TriggerClass::Name_From_Action(trigger->Action),
   1224 			trigger->Data,
   1225 			hname,
   1226 			tname,
   1227 			trigger->IsPersistant);
   1228 		WWWritePrivateProfileString(INI_Name(), trigger->Get_Name(), buf, buffer);
   1229 	}
   1230 }
   1231 
   1232 
   1233 /***********************************************************************************************
   1234  * TriggerClass::As_Pointer -- returns pointer for the given trigger name                      *
   1235  *                                                                                             *
   1236  * This function is designed for use at initialization time, ie when the                       *
   1237  * trigger mnemonics are read from the INI and the Read_INI functions need                     *
   1238  * to get a pointer to that trigger.                                                           *
   1239  *                                                                                             *
   1240  * INPUT:                                                                                      *
   1241  *      name      mnemonic for the desired trigger                                             *
   1242  *                                                                                             *
   1243  * OUTPUT:                                                                                     *
   1244  *      near pointer to that trigger, NULL if not found                                        *
   1245  *                                                                                             *
   1246  * WARNINGS:                                                                                   *
   1247  *      none.                                                                                  *
   1248  *                                                                                             *
   1249  * HISTORY:                                                                                    *
   1250  *   11/28/1994 BR : Created.                                                                  *
   1251  *=============================================================================================*/
   1252 TriggerClass * TriggerClass::As_Pointer(char const * name)
   1253 {
   1254 	if (name == NULL) {
   1255 		return(NULL);
   1256 	}
   1257 
   1258 	for (int i = 0; i < Triggers.Count(); i++) {
   1259 		TriggerClass * trigger = Triggers.Ptr(i);
   1260 
   1261 		if (!stricmp(name, trigger->Name)) {
   1262 			return(trigger);
   1263 		}
   1264 	}
   1265 
   1266 	return(NULL);
   1267 }
   1268 
   1269 
   1270 /***********************************************************************************************
   1271  * TriggerClass::operator new -- 'new' operator                                                *
   1272  *                                                                                             *
   1273  * INPUT:                                                                                      *
   1274  *      none.                                                                                  *
   1275  *                                                                                             *
   1276  * OUTPUT:                                                                                     *
   1277  *      pointer to new trigger                                                                 *
   1278  *                                                                                             *
   1279  * WARNINGS:                                                                                   *
   1280  *      none.                                                                                  *
   1281  *                                                                                             *
   1282  * HISTORY:                                                                                    *
   1283  *   11/28/1994 BR : Created.                                                                  *
   1284  *=============================================================================================*/
   1285 void * TriggerClass::operator new(size_t )
   1286 {
   1287 	void * ptr = Triggers.Allocate();
   1288 	if (ptr) {
   1289 		((TriggerClass *)ptr)->IsActive = true;
   1290 	}
   1291 	return(ptr);
   1292 }
   1293 
   1294 
   1295 /***********************************************************************************************
   1296  * TriggerClass::operator delete -- 'delete' operator                                          *
   1297  *                                                                                             *
   1298  * INPUT:                                                                                      *
   1299  *      ptr      pointer to delete                                                             *
   1300  *                                                                                             *
   1301  * OUTPUT:                                                                                     *
   1302  *      none.                                                                                  *
   1303  *                                                                                             *
   1304  * WARNINGS:                                                                                   *
   1305  *      none.                                                                                  *
   1306  *                                                                                             *
   1307  * HISTORY:                                                                                    *
   1308  *   11/28/1994 BR : Created.                                                                  *
   1309  *=============================================================================================*/
   1310 void TriggerClass::operator delete(void *ptr)
   1311 {
   1312 	if (ptr) {
   1313 		((TriggerClass *)ptr)->IsActive = false;
   1314 	}
   1315 	Triggers.Free((TriggerClass *)ptr);
   1316 }
   1317 
   1318 
   1319 /***********************************************************************************************
   1320  * TriggerClass::Event_From_Name -- retrieves EventType for given name                         *
   1321  *                                                                                             *
   1322  * INPUT:                                                                                      *
   1323  *      name      name to get event for                                                        *
   1324  *                                                                                             *
   1325  * OUTPUT:                                                                                     *
   1326  *      EventType for given name                                                               *
   1327  *                                                                                             *
   1328  * WARNINGS:                                                                                   *
   1329  *      none.                                                                                  *
   1330  *                                                                                             *
   1331  * HISTORY:                                                                                    *
   1332  *   11/29/1994 BR : Created.                                                                  *
   1333  *=============================================================================================*/
   1334 EventType TriggerClass::Event_From_Name (char const *name)
   1335 {
   1336 	int i;
   1337 
   1338 	if (name == NULL) {
   1339 		return(EVENT_NONE);
   1340 	}
   1341 
   1342 	for (i = EVENT_NONE; i < EVENT_COUNT; i++) {
   1343 		if (!stricmp(name,EventText[i + 1])) {
   1344 			return((EventType)i);
   1345 		}
   1346 	}
   1347 
   1348 	return(EVENT_NONE);
   1349 }
   1350 
   1351 
   1352 /***********************************************************************************************
   1353  * TriggerClass::Name_From_Event -- retrieves name for EventType                               *
   1354  *                                                                                             *
   1355  * INPUT:                                                                                      *
   1356  *      event      EventType to get name for                                                   *
   1357  *                                                                                             *
   1358  * OUTPUT:                                                                                     *
   1359  *      name for EventType                                                                     *
   1360  *                                                                                             *
   1361  * WARNINGS:                                                                                   *
   1362  *      none.                                                                                  *
   1363  *                                                                                             *
   1364  * HISTORY:                                                                                    *
   1365  *   11/29/1994 BR : Created.                                                                  *
   1366  *=============================================================================================*/
   1367 char const *TriggerClass::Name_From_Event(EventType event)
   1368 {
   1369 	return(EventText[event + 1]);
   1370 }
   1371 
   1372 
   1373 /***********************************************************************************************
   1374  * TriggerClass::Action_From_Name -- retrieves ActionType for given name                       *
   1375  *                                                                                             *
   1376  * INPUT:                                                                                      *
   1377  *      name         name to get ActionType for                                                *
   1378  *                                                                                             *
   1379  * OUTPUT:                                                                                     *
   1380  *      ActionType for given name                                                              *
   1381  *                                                                                             *
   1382  * WARNINGS:                                                                                   *
   1383  *      none.                                                                                  *
   1384  *                                                                                             *
   1385  * HISTORY:                                                                                    *
   1386  *   11/29/1994 BR : Created.                                                                  *
   1387  *=============================================================================================*/
   1388 TriggerClass::ActionType TriggerClass::Action_From_Name (char const *name)
   1389 {
   1390 	int i;
   1391 
   1392 	if (name == NULL) {
   1393 		return(ACTION_NONE);
   1394 	}
   1395 
   1396 	for (i = ACTION_NONE; i < ACTION_COUNT; i++) {
   1397 		if (!stricmp(name,ActionText[i + 1])) {
   1398 			return((ActionType)i);
   1399 		}
   1400 	}
   1401 
   1402 	return(ACTION_NONE);
   1403 }
   1404 
   1405 
   1406 /***********************************************************************************************
   1407  * TriggerClass::Name_From_Action -- retrieves name for ActionType                             *
   1408  *                                                                                             *
   1409  * INPUT:                                                                                      *
   1410  *      action      ActionType to get name for                                                 *
   1411  *                                                                                             *
   1412  * OUTPUT:                                                                                     *
   1413  *      name of ActionType                                                                     *
   1414  *                                                                                             *
   1415  * WARNINGS:                                                                                   *
   1416  *      none.                                                                                  *
   1417  *                                                                                             *
   1418  * HISTORY:                                                                                    *
   1419  *   11/29/1994 BR : Created.                                                                  *
   1420  *=============================================================================================*/
   1421 char const *TriggerClass::Name_From_Action(ActionType action)
   1422 {
   1423 	return(ActionText[action + 1]);
   1424 }
   1425 
   1426 
   1427 /***********************************************************************************************
   1428  * TriggerClass::As_Target -- Converts trigger to a target value                               *
   1429  *                                                                                             *
   1430  * INPUT:   none                                                                               *
   1431  *                                                                                             *
   1432  * OUTPUT:  TARGET value                                                                       *
   1433  *                                                                                             *
   1434  * WARNINGS:   none                                                                            *
   1435  *                                                                                             *
   1436  * HISTORY:                                                                                    *
   1437  *   09/19/1994 JLB : Created.                                                                 *
   1438  *=============================================================================================*/
   1439 TARGET TriggerClass::As_Target(void) const
   1440 {
   1441 	Validate();
   1442 	return(Build_Target(KIND_TRIGGER, Triggers.ID(this)));
   1443 }
   1444 
   1445 
   1446 /***********************************************************************************************
   1447  * Do_All_To_Hunt -- Forces all computer controlled units into hunt mode.                      *
   1448  *                                                                                             *
   1449  *    This trigger action will cause the computer units and infantry to go into hunt mode.     *
   1450  *    Use it to bring a scenario to a sudden conclusion.                                       *
   1451  *                                                                                             *
   1452  * INPUT:   none                                                                               *
   1453  *                                                                                             *
   1454  * OUTPUT:  none                                                                               *
   1455  *                                                                                             *
   1456  * WARNINGS:   none                                                                            *
   1457  *                                                                                             *
   1458  * HISTORY:                                                                                    *
   1459  *   04/20/1995 JLB : Created.                                                                 *
   1460  *   08/14/1995 JLB : Removes the member from a team if necessary.                             *
   1461  *=============================================================================================*/
   1462 static void Do_All_To_Hunt(void)
   1463 {
   1464 	int index;
   1465 
   1466 	for (index = 0; index < Units.Count(); index++) {
   1467 		UnitClass * unit = Units.Ptr(index);
   1468 
   1469 		if (!unit->House->IsHuman && unit->IsDown && !unit->IsInLimbo) {
   1470 			if (unit->Team) unit->Team->Remove(unit);
   1471 			unit->Assign_Mission(MISSION_HUNT);
   1472 		}
   1473 	}
   1474 
   1475 	for (index = 0; index < Infantry.Count(); index++) {
   1476 		InfantryClass * infantry = Infantry.Ptr(index);
   1477 
   1478 		if (!infantry->House->IsHuman && infantry->IsDown && !infantry->IsInLimbo) {
   1479 			if (infantry->Team) infantry->Team->Remove(infantry);
   1480 			infantry->Assign_Mission(MISSION_HUNT);
   1481 		}
   1482 	}
   1483 }