CnC_Remastered_Collection

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

TRIGTYPE.CPP (81229B)


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