CnC_Remastered_Collection

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

MISSION.CPP (30951B)


      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/MISSION.CPP 1     3/03/97 10:25a Joe_bostic $ */
     17 /***********************************************************************************************
     18  ***              C O N F I D E N T I A L  ---  W E S T W O O D  S T U D I O S               ***
     19  ***********************************************************************************************
     20  *                                                                                             *
     21  *                 Project Name : Command & Conquer                                            *
     22  *                                                                                             *
     23  *                    File Name : MISSION.CPP                                                  *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : April 23, 1994                                               *
     28  *                                                                                             *
     29  *                  Last Update : September 14, 1996 [JLB]                                     *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   MissionClass::AI -- Processes order script.                                               *
     34  *   MissionClass::Assign_Mission -- Give an order to a unit.                                  *
     35  *   MissionClass::Commence -- Start script with new order.                                    *
     36  *   MissionClass::Debug_Dump -- Dumps status values to mono screen.                           *
     37  *   MissionClass::Get_Mission -- Fetches the mission that this object is acting under.        *
     38  *   MissionClass::MissionClass -- Default constructor for the mission object type.            *
     39  *   MissionClass::Mission_???  -- Stub mission functions that do nothing.                     *
     40  *   MissionClass::Mission_From_Name -- Fetch order pointer from its name.                     *
     41  *   MissionClass::Mission_Name -- Converts a mission number into an ASCII string.             *
     42  *   MissionClass::Override_Mission -- temporarily overrides the units mission                 *
     43  *   MissionClass::Restore_Mission -- Restores overridden mission                              *
     44  *   MissionClass::Set_Mission -- Sets the mission to the specified value.                     *
     45  *   MissionClass::Is_Recruitable_Mission -- Determines if this mission is recruitable for a te*
     46  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     47 
     48 #include	"function.h"
     49 
     50 
     51 /***********************************************************************************************
     52  * MissionClass::MissionClass -- Default constructor for the mission object type.              *
     53  *                                                                                             *
     54  *    This is the default constructor for the mission class object. It sets the mission        *
     55  *    handler into a default -- do nothing -- state.                                           *
     56  *                                                                                             *
     57  * INPUT:   none                                                                               *
     58  *                                                                                             *
     59  * OUTPUT:  none                                                                               *
     60  *                                                                                             *
     61  * WARNINGS:   none                                                                            *
     62  *                                                                                             *
     63  * HISTORY:                                                                                    *
     64  *   01/23/1995 JLB : Created.                                                                 *
     65  *   03/01/1996 JLB : Uses initializer lists.                                                  *
     66  *=============================================================================================*/
     67 MissionClass::MissionClass(RTTIType rtti, int id) :
     68 	ObjectClass(rtti, id),
     69 	Mission(MISSION_NONE),
     70 	SuspendedMission(MISSION_NONE),
     71 	MissionQueue(MISSION_NONE),
     72 	Status(0),
     73 	Timer(0)
     74 {
     75 }
     76 
     77 
     78 /***********************************************************************************************
     79  * MissionClass::Mission_???  -- Stub mission functions that do nothing.                       *
     80  *                                                                                             *
     81  *    These are the stub routines that handle the mission logic. They do nothing at this       *
     82  *    level. Derived classes will override these routine as necessary.                         *
     83  *                                                                                             *
     84  * INPUT:   none                                                                               *
     85  *                                                                                             *
     86  * OUTPUT:  Returns with the number of game frames to delay before calling this mission        *
     87  *          handler again.                                                                     *
     88  *                                                                                             *
     89  * WARNINGS:   none                                                                            *
     90  *                                                                                             *
     91  * HISTORY:                                                                                    *
     92  *   01/23/1995 JLB : Created.                                                                 *
     93  *=============================================================================================*/
     94 int MissionClass::Mission_Sleep(void) {return TICKS_PER_SECOND*30;};
     95 int MissionClass::Mission_Ambush(void) {return TICKS_PER_SECOND*30;};
     96 int MissionClass::Mission_Attack(void) {return TICKS_PER_SECOND*30;};
     97 int MissionClass::Mission_Capture(void) {return TICKS_PER_SECOND*30;};
     98 int MissionClass::Mission_Guard(void) {return TICKS_PER_SECOND*30;};
     99 int MissionClass::Mission_Guard_Area(void) {return TICKS_PER_SECOND*30;};
    100 int MissionClass::Mission_Harvest(void) {return TICKS_PER_SECOND*30;};
    101 int MissionClass::Mission_Hunt(void) {return TICKS_PER_SECOND*30;};
    102 int MissionClass::Mission_Move(void) {return TICKS_PER_SECOND*30;};
    103 int MissionClass::Mission_Retreat(void) {return TICKS_PER_SECOND*30;};
    104 int MissionClass::Mission_Return(void) {return TICKS_PER_SECOND*30;};
    105 int MissionClass::Mission_Stop(void) {return TICKS_PER_SECOND*30;};
    106 int MissionClass::Mission_Unload(void) {return TICKS_PER_SECOND*30;};
    107 int MissionClass::Mission_Enter(void) {return TICKS_PER_SECOND*30;};
    108 int MissionClass::Mission_Construction(void) {return TICKS_PER_SECOND*30;};
    109 int MissionClass::Mission_Deconstruction(void) {return TICKS_PER_SECOND*30;};
    110 int MissionClass::Mission_Repair(void) {return TICKS_PER_SECOND*30;};
    111 int MissionClass::Mission_Missile(void) {return TICKS_PER_SECOND*30;};
    112 
    113 
    114 /***********************************************************************************************
    115  * MissionClass::Set_Mission -- Sets the mission to the specified value.                       *
    116  *                                                                                             *
    117  *    Use this routine to set the current mission for this object. This routine will blast     *
    118  *    over the current mission, bypassing the queue method. Call it when the mission needs     *
    119  *    to be changed immediately.                                                               *
    120  *                                                                                             *
    121  * INPUT:   mission  -- The mission to set to.                                                 *
    122  *                                                                                             *
    123  * OUTPUT:  none                                                                               *
    124  *                                                                                             *
    125  * WARNINGS:   none                                                                            *
    126  *                                                                                             *
    127  * HISTORY:                                                                                    *
    128  *   01/23/1995 JLB : Created.                                                                 *
    129  *=============================================================================================*/
    130 void MissionClass::Set_Mission(MissionType mission)
    131 {
    132 	assert(IsActive);
    133 
    134 	Mission = mission;
    135 	MissionQueue = MISSION_NONE;
    136 }
    137 
    138 
    139 /***********************************************************************************************
    140  * MissionClass::Get_Mission -- Fetches the mission that this object is acting under.          *
    141  *                                                                                             *
    142  *    Use this routine to fetch the mission that this object is CURRENTLY acting under. The    *
    143  *    mission queue may be filled with a imminent mission change, but this routine does not    *
    144  *    consider that. It only returns the CURRENT mission.                                      *
    145  *                                                                                             *
    146  * INPUT:   none                                                                               *
    147  *                                                                                             *
    148  * OUTPUT:  Returns with the mission that this unit is currently following.                    *
    149  *                                                                                             *
    150  * WARNINGS:   none                                                                            *
    151  *                                                                                             *
    152  * HISTORY:                                                                                    *
    153  *   01/23/1995 JLB : Created.                                                                 *
    154  *=============================================================================================*/
    155 MissionType MissionClass::Get_Mission(void) const
    156 {
    157 	assert(IsActive);
    158 
    159 	return(Mission == MISSION_NONE ? MissionQueue : Mission);
    160 }
    161 
    162 
    163 #ifdef CHEAT_KEYS
    164 /***********************************************************************************************
    165  * MissionClass::Debug_Dump -- Dumps status values to mono screen.                             *
    166  *                                                                                             *
    167  *    This is a debugging function that dumps this class' status to the monochrome screen      *
    168  *    for review.                                                                              *
    169  *                                                                                             *
    170  * INPUT:   none                                                                               *
    171  *                                                                                             *
    172  * OUTPUT:  none                                                                               *
    173  *                                                                                             *
    174  * WARNINGS:   none                                                                            *
    175  *                                                                                             *
    176  * HISTORY:                                                                                    *
    177  *   05/28/1994 JLB : Created.                                                                 *
    178  *=============================================================================================*/
    179 void MissionClass::Debug_Dump(MonoClass * mono) const
    180 {
    181 	assert(IsActive);
    182 
    183 	mono->Set_Cursor(1, 9);mono->Printf("%-14s", MissionClass::Mission_Name(Mission));
    184 	mono->Set_Cursor(16, 9);mono->Printf("%-12s", MissionClass::Mission_Name(MissionQueue));
    185 	mono->Set_Cursor(1, 7);mono->Printf("%3d", (long)Timer);
    186 	mono->Set_Cursor(6, 7);mono->Printf("%2d", Status);
    187 
    188 	ObjectClass::Debug_Dump(mono);
    189 }
    190 #endif
    191 
    192 
    193 /***********************************************************************************************
    194  * MissionClass::AI -- Processes order script.                                                 *
    195  *                                                                                             *
    196  *    This routine will process the order script for as much time as                           *
    197  *    possible or until a script delay is detected. This routine should                        *
    198  *    be called for every unit once per game loop (if possible).                               *
    199  *                                                                                             *
    200  * INPUT:   none                                                                               *
    201  *                                                                                             *
    202  * OUTPUT:  none                                                                               *
    203  *                                                                                             *
    204  * WARNINGS:   none                                                                            *
    205  *                                                                                             *
    206  * HISTORY:                                                                                    *
    207  *   04/23/1994 JLB : Created.                                                                 *
    208  *   06/25/1995 JLB : Added new missions.                                                      *
    209  *=============================================================================================*/
    210 void MissionClass::AI(void)
    211 {
    212 	assert(IsActive);
    213 
    214 	ObjectClass::AI();
    215 
    216 	/*
    217 	**	If this is the kind of object that is "paralyzed with fear" while it is above
    218 	**	ground level (such as when be paradropped), it will perform no mission AI
    219 	**	processing.
    220 	*/
    221 	if ((What_Am_I() == RTTI_INFANTRY || What_Am_I() == RTTI_UNIT || What_Am_I() == RTTI_VESSEL) && Height > 0) {
    222 		return;
    223 	}
    224 
    225 	/*
    226 	**	This is the script AI equivalent processing.
    227 	*/
    228 	BStart(BENCH_MISSION);
    229 	if (Timer == 0 && Strength > 0) {
    230 		switch (Mission) {
    231 			default:
    232 				Timer = Mission_Sleep();
    233 				break;
    234 
    235 			case MISSION_HARMLESS:
    236 			case MISSION_SLEEP:
    237 				Timer = Mission_Sleep();
    238 				break;
    239 
    240 			case MISSION_STICKY:
    241 			case MISSION_GUARD:
    242 				Timer = Mission_Guard();
    243 				break;
    244 
    245 			case MISSION_ENTER:
    246 				Timer = Mission_Enter();
    247 				break;
    248 
    249 			case MISSION_CONSTRUCTION:
    250 				Timer = Mission_Construction();
    251 				break;
    252 
    253 			case MISSION_DECONSTRUCTION:
    254 				Timer = Mission_Deconstruction();
    255 				break;
    256 
    257 			case MISSION_CAPTURE:
    258 			case MISSION_SABOTAGE:
    259 				Timer = Mission_Capture();
    260 				break;
    261 
    262 			case MISSION_QMOVE:
    263 			case MISSION_MOVE:
    264 				Timer = Mission_Move();
    265 				break;
    266 
    267 			case MISSION_ATTACK:
    268 				Timer = Mission_Attack();
    269 				break;
    270 
    271 			case MISSION_RETREAT:
    272 				Timer = Mission_Retreat();
    273 				break;
    274 
    275 			case MISSION_HARVEST:
    276 				Timer = Mission_Harvest();
    277 				break;
    278 
    279 			case MISSION_GUARD_AREA:
    280 				Timer = Mission_Guard_Area();
    281 				break;
    282 
    283 			case MISSION_RETURN:
    284 				Timer = Mission_Return();
    285 				break;
    286 
    287 			case MISSION_STOP:
    288 				Timer = Mission_Stop();
    289 				break;
    290 
    291 			case MISSION_AMBUSH:
    292 				Timer = Mission_Ambush();
    293 				break;
    294 
    295 			case MISSION_HUNT:
    296 			case MISSION_RESCUE:
    297 				Timer = Mission_Hunt();
    298 				break;
    299 
    300 //			case MISSION_TIMED_HUNT:
    301 //				Timer = Mission_Timed_Hunt();
    302 //				break;
    303 
    304 			case MISSION_UNLOAD:
    305 				Timer = Mission_Unload();
    306 				break;
    307 
    308 			case MISSION_REPAIR:
    309 				Timer = Mission_Repair();
    310 				break;
    311 
    312 			case MISSION_MISSILE:
    313 				Timer = Mission_Missile();
    314 				break;
    315 		}
    316 	}
    317 	BEnd(BENCH_MISSION);
    318 }
    319 
    320 
    321 /***********************************************************************************************
    322  * MissionClass::Commence -- Start script with new order.                                      *
    323  *                                                                                             *
    324  *    This routine will start script processing according to any queued                        *
    325  *    order it may have. If there is no queued order, then this routine                        *
    326  *    does nothing. Call this routine whenever the unit is in a good                           *
    327  *    position to change its order (such as when it is stopped).                               *
    328  *                                                                                             *
    329  * INPUT:   none                                                                               *
    330  *                                                                                             *
    331  * OUTPUT:  Did the mission actually change?                                                   *
    332  *                                                                                             *
    333  * WARNINGS:   none                                                                            *
    334  *                                                                                             *
    335  * HISTORY:                                                                                    *
    336  *   04/23/1994 JLB : Created.                                                                 *
    337  *   07/14/1994 JLB : Simplified.                                                              *
    338  *   06/17/1995 JLB : Returns success flag.                                                    *
    339  *=============================================================================================*/
    340 bool MissionClass::Commence(void)
    341 {
    342 	assert(IsActive);
    343 
    344 	if (MissionQueue != MISSION_NONE) {
    345 		Mission = MissionQueue;
    346 		MissionQueue = MISSION_NONE;
    347 
    348 		/*
    349 		**	Force immediate state machine processing at the first state machine state value.
    350 		*/
    351 		Timer = 0;
    352 		Status = 0;
    353 		return(true);
    354 	}
    355 	return(false);
    356 }
    357 
    358 
    359 /***********************************************************************************************
    360  * MissionClass::Assign_Mission -- Give an order to a unit.                                    *
    361  *                                                                                             *
    362  *    This routine will assign the specified mission to the mission queue for this object.     *
    363  *    The actual mission logic will then be performed at the first available and legal         *
    364  *    opportunity.                                                                             *
    365  *                                                                                             *
    366  * INPUT:   order -- Mission to give the unit.                                                 *
    367  *                                                                                             *
    368  * OUTPUT:  none                                                                               *
    369  *                                                                                             *
    370  * WARNINGS:   none                                                                            *
    371  *                                                                                             *
    372  * HISTORY:                                                                                    *
    373  *   06/04/1991 JLB : Created.                                                                 *
    374  *   04/15/1994 JLB : Converted to member function.                                            *
    375  *=============================================================================================*/
    376 void MissionClass::Assign_Mission(MissionType order)
    377 {
    378 	assert(IsActive);
    379 
    380 	/*
    381 	**	Ensure that a MISSION_QMOVE is translated into a MISSION_MOVE.
    382 	*/
    383 	if (order == MISSION_QMOVE) order = MISSION_MOVE;
    384 
    385 	if (order != MISSION_NONE && Mission != order)  {
    386 		MissionQueue = order;
    387 	}
    388 }
    389 
    390 
    391 /***********************************************************************************************
    392  * MissionClass::Mission_From_Name -- Fetch order pointer from its name.                       *
    393  *                                                                                             *
    394  *    This routine is used to convert an ASCII order name into the actual                      *
    395  *    order number it represents. Typically, this is used when processing                      *
    396  *    a scenario INI file.                                                                     *
    397  *                                                                                             *
    398  * INPUT:   name  -- The ASCII order name to process.                                          *
    399  *                                                                                             *
    400  * OUTPUT:  Returns with the actual order number that the ASCII name                           *
    401  *          represents.                                                                        *
    402  *                                                                                             *
    403  * WARNINGS:   none                                                                            *
    404  *                                                                                             *
    405  * HISTORY:                                                                                    *
    406  *   10/07/1992 JLB : Created.                                                                 *
    407  *   04/22/1994 JLB : Converted to static member function.                                     *
    408  *=============================================================================================*/
    409 MissionType MissionClass::Mission_From_Name(char const * name)
    410 {
    411 	MissionType	order;
    412 
    413 	if (name) {
    414 		for (order = MISSION_FIRST; order < MISSION_COUNT; order++) {
    415 			if (stricmp(Missions[order], name) == 0) {
    416 				return(order);
    417 			}
    418 		}
    419 	}
    420 	return(MISSION_NONE);
    421 }
    422 
    423 
    424 /***********************************************************************************************
    425  * MissionClass::Mission_Name -- Converts a mission number into an ASCII string.               *
    426  *                                                                                             *
    427  *    Use this routine to convert a mission number into the ASCII string that represents       *
    428  *    it. Typical use of this is when generating an INI file.                                  *
    429  *                                                                                             *
    430  * INPUT:   mission  -- The mission number to convert.                                         *
    431  *                                                                                             *
    432  * OUTPUT:  Returns with a pointer to the ASCII string that represents the mission type.       *
    433  *                                                                                             *
    434  * WARNINGS:   none                                                                            *
    435  *                                                                                             *
    436  * HISTORY:                                                                                    *
    437  *   01/23/1995 JLB : Created.                                                                 *
    438  *=============================================================================================*/
    439 char const * MissionClass::Mission_Name(MissionType mission)
    440 {
    441 	if (mission != MISSION_NONE)  {
    442 		return(Missions[mission]);
    443 	}
    444 	return("None");
    445 }
    446 
    447 
    448 /***********************************************************************************************
    449  * MissionClass::Override_Mission -- temporarily overrides the units mission                   *
    450  *                                                                                             *
    451  *                                                                                             *
    452  *                                                                                             *
    453  * INPUT:      MissionType mission - the mission we want to override                           *
    454  *               TARGET      tarcom  - the new target we want to override                      *
    455  *               TARGET      navcom  - the new navigation point to override                    *
    456  *                                                                                             *
    457  * OUTPUT:      none                                                                           *
    458  *                                                                                             *
    459  * WARNINGS:   If a mission is already overridden, the current mission is                      *
    460  *               just re-assigned.                                                             *
    461  *                                                                                             *
    462  * HISTORY:                                                                                    *
    463  *   04/28/1995 PWG : Created.                                                                 *
    464  *=============================================================================================*/
    465 void MissionClass::Override_Mission(MissionType mission, TARGET, TARGET)
    466 {
    467 	assert(IsActive);
    468 
    469 	if (MissionQueue != MISSION_NONE) {
    470 		SuspendedMission = MissionQueue;
    471 	} else {
    472 		SuspendedMission = Mission;
    473 	}
    474 
    475 	Assign_Mission(mission);
    476 }
    477 
    478 
    479 /***********************************************************************************************
    480  * MissionClass::Restore_Mission -- Restores overridden mission                                *
    481  *                                                                                             *
    482  * INPUT:      none                                                                            *
    483  *                                                                                             *
    484  * OUTPUT:     none                                                                            *
    485  *                                                                                             *
    486  * WARNINGS:   none                                                                            *
    487  *                                                                                             *
    488  * HISTORY:                                                                                    *
    489  *   04/28/1995 PWG : Created.                                                                 *
    490  *=============================================================================================*/
    491 bool MissionClass::Restore_Mission(void)
    492 {
    493 	assert(IsActive);
    494 
    495 	if (SuspendedMission != MISSION_NONE) {
    496 		Assign_Mission(SuspendedMission);
    497 	 	SuspendedMission= MISSION_NONE;
    498 		return(true);
    499 	}
    500 	return(false);
    501 }
    502 
    503 
    504 /***********************************************************************************************
    505  * MissionClass::Is_Recruitable_Mission -- Determines if this mission is recruitable for a tea *
    506  *                                                                                             *
    507  *    Some missions preclude recruitment into a team. This routine will examine the mission    *
    508  *    specified and if not allowed for a team, it will return false.                           *
    509  *                                                                                             *
    510  * INPUT:   mission  -- The mission type to examine.                                           *
    511  *                                                                                             *
    512  * OUTPUT:  bool; Is an object following this mission allowed to be recruited into a team?     *
    513  *                                                                                             *
    514  * WARNINGS:   none                                                                            *
    515  *                                                                                             *
    516  * HISTORY:                                                                                    *
    517  *   09/14/1996 JLB : Created.                                                                 *
    518  *=============================================================================================*/
    519 bool MissionClass::Is_Recruitable_Mission(MissionType mission)
    520 {
    521 	if (mission == MISSION_NONE) {
    522 		return(true);
    523 	}
    524 	return(MissionControl[mission].IsRecruitable);
    525 }
    526 
    527 
    528 
    529 MissionControlClass::MissionControlClass(void) :
    530 	Mission(MISSION_NONE),
    531 	IsNoThreat(false),
    532 	IsZombie(false),
    533 	IsRecruitable(true),
    534 	IsParalyzed(false),
    535 	IsRetaliate(true),
    536 	IsScatter(true),
    537 	Rate(".016"),
    538 	AARate(".016")
    539 {
    540 }
    541 
    542 
    543 char const * MissionControlClass::Name(void) const
    544 {
    545 	if (Mission == MISSION_NONE) {
    546 		return("<none>");
    547 	}
    548 	return(Missions[Mission]);
    549 }
    550 
    551 
    552 
    553 bool MissionControlClass::Read_INI(CCINIClass & ini)
    554 {
    555 	if (ini.Is_Present(Name())) {
    556 		IsNoThreat = ini.Get_Bool(Name(), "NoThreat", IsNoThreat);
    557 		IsZombie = ini.Get_Bool(Name(), "Zombie", IsZombie);
    558 		IsRecruitable = ini.Get_Bool(Name(), "Recruitable", IsRecruitable);
    559 		IsParalyzed = ini.Get_Bool(Name(), "Paralyzed", IsParalyzed);
    560 		IsRetaliate = ini.Get_Bool(Name(), "Retaliate", IsRetaliate);
    561 		IsScatter = ini.Get_Bool(Name(), "Scatter", IsScatter);
    562 		Rate = ini.Get_Fixed(Name(), "Rate", Rate);
    563 		AARate = ini.Get_Fixed(Name(), "AARate", 0);
    564 		if (AARate == 0) {
    565 			AARate = Rate;
    566 		}
    567 		return(true);
    568 	}
    569 	return(false);
    570 }