MISSION.CPP (26549B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: F:\projects\c&c\vcs\code\mission.cpv 2.18 16 Oct 1995 16:49:12 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 : June 25, 1995 [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_From_Name -- Fetch order pointer from its name. * 40 * MissionClass::Mission_Name -- Converts a mission number into an ASCII string. * 41 * MissionClass::Overide_Mission -- temporarily overides the units mission * 42 * MissionClass::Restore_Mission -- Restores overidden mission * 43 * MissionClass::Set_Mission -- Sets the mission to the specified value. * 44 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 45 46 #include "function.h" 47 48 49 /*********************************************************************************************** 50 * MissionClass::MissionClass -- Default constructor for the mission object type. * 51 * * 52 * This is the default constructor for the mission class object. It sets the mission * 53 * handler into a default -- do nothing -- state. * 54 * * 55 * INPUT: none * 56 * * 57 * OUTPUT: none * 58 * * 59 * WARNINGS: none * 60 * * 61 * HISTORY: * 62 * 01/23/1995 JLB : Created. * 63 *=============================================================================================*/ 64 MissionClass::MissionClass(void) 65 { 66 Status = 0; 67 Timer = 0; 68 Mission = MISSION_NONE; 69 SuspendedMission = MISSION_NONE; 70 MissionQueue = MISSION_NONE; 71 } 72 73 74 int MissionClass::Mission_Sleep(void) {return TICKS_PER_SECOND*30;}; 75 int MissionClass::Mission_Ambush(void) {return TICKS_PER_SECOND*30;}; 76 int MissionClass::Mission_Attack(void) {return TICKS_PER_SECOND*30;}; 77 int MissionClass::Mission_Capture(void) {return TICKS_PER_SECOND*30;}; 78 int MissionClass::Mission_Guard(void) {return TICKS_PER_SECOND*30;}; 79 int MissionClass::Mission_Guard_Area(void) {return TICKS_PER_SECOND*30;}; 80 int MissionClass::Mission_Harvest(void) {return TICKS_PER_SECOND*30;}; 81 int MissionClass::Mission_Hunt(void) {return TICKS_PER_SECOND*30;}; 82 int MissionClass::Mission_Timed_Hunt(void) {return TICKS_PER_SECOND*30;}; 83 int MissionClass::Mission_Move(void) {return TICKS_PER_SECOND*30;}; 84 int MissionClass::Mission_Retreat(void) {return TICKS_PER_SECOND*30;}; 85 int MissionClass::Mission_Return(void) {return TICKS_PER_SECOND*30;}; 86 int MissionClass::Mission_Stop(void) {return TICKS_PER_SECOND*30;}; 87 int MissionClass::Mission_Unload(void) {return TICKS_PER_SECOND*30;}; 88 int MissionClass::Mission_Enter(void) {return TICKS_PER_SECOND*30;}; 89 int MissionClass::Mission_Construction(void) {return TICKS_PER_SECOND*30;}; 90 int MissionClass::Mission_Deconstruction(void) {return TICKS_PER_SECOND*30;}; 91 int MissionClass::Mission_Repair(void) {return TICKS_PER_SECOND*30;}; 92 int MissionClass::Mission_Missile(void) {return TICKS_PER_SECOND*30;}; 93 94 95 /*********************************************************************************************** 96 * MissionClass::Set_Mission -- Sets the mission to the specified value. * 97 * * 98 * Use this routine to set the current mission for this object. This routine will blast * 99 * over the current mission, bypassing the queue method. Call it when the mission needs * 100 * to be changed immediately. * 101 * * 102 * INPUT: mission -- The mission to set to. * 103 * * 104 * OUTPUT: none * 105 * * 106 * WARNINGS: none * 107 * * 108 * HISTORY: * 109 * 01/23/1995 JLB : Created. * 110 *=============================================================================================*/ 111 void MissionClass::Set_Mission(MissionType mission) 112 { 113 Mission = mission; 114 MissionQueue = MISSION_NONE; 115 } 116 117 118 /*********************************************************************************************** 119 * MissionClass::Get_Mission -- Fetches the mission that this object is acting under. * 120 * * 121 * Use this routine to fetch the mission that this object is CURRENTLY acting under. The * 122 * mission queue may be filled with a immanent mission change, but this routine does not * 123 * consider that. It only returns the CURRENT mission. * 124 * * 125 * INPUT: none * 126 * * 127 * OUTPUT: Returns with the mission that this unit is currently following. * 128 * * 129 * WARNINGS: none * 130 * * 131 * HISTORY: * 132 * 01/23/1995 JLB : Created. * 133 *=============================================================================================*/ 134 MissionType MissionClass::Get_Mission(void) const 135 { 136 return(Mission == MISSION_NONE ? MissionQueue : Mission); 137 } 138 139 140 #ifdef CHEAT_KEYS 141 /*********************************************************************************************** 142 * MissionClass::Debug_Dump -- Dumps status values to mono screen. * 143 * * 144 * This is a debugging function that dumps this class' status to the monochrome screen * 145 * for review. * 146 * * 147 * INPUT: none * 148 * * 149 * OUTPUT: none * 150 * * 151 * WARNINGS: none * 152 * * 153 * HISTORY: * 154 * 05/28/1994 JLB : Created. * 155 *=============================================================================================*/ 156 void MissionClass::Debug_Dump(MonoClass *mono) const 157 { 158 mono->Set_Cursor(21, 1);mono->Printf("%5.5s[%4.4s]", MissionClass::Mission_Name(Mission), MissionClass::Mission_Name(MissionQueue)); 159 // mono->Text_Print(MissionClass::Mission_Name(Mission), 21, 1); 160 mono->Set_Cursor(20, 7);mono->Printf("%2d", (long)Timer); 161 mono->Set_Cursor(74, 1);mono->Printf("%2d", Status); 162 163 ObjectClass::Debug_Dump(mono); 164 } 165 #endif 166 167 168 /*********************************************************************************************** 169 * MissionClass::AI -- Processes order script. * 170 * * 171 * This routine will process the order script for as much time as * 172 * possible or until a script delay is detected. This routine should * 173 * be called for every unit once per game loop (if possible). * 174 * * 175 * INPUT: none * 176 * * 177 * OUTPUT: none * 178 * * 179 * WARNINGS: none * 180 * * 181 * HISTORY: * 182 * 04/23/1994 JLB : Created. * 183 * 06/25/1995 JLB : Added new missions. * 184 *=============================================================================================*/ 185 void MissionClass::AI(void) 186 { 187 ObjectClass::AI(); 188 189 /* 190 ** This is the script AI equivalent processing. 191 */ 192 if (Timer.Expired() && Strength > 0) { 193 switch (Mission) { 194 default: 195 case MISSION_STICKY: 196 case MISSION_SLEEP: 197 Timer = Mission_Sleep(); 198 break; 199 200 case MISSION_GUARD: 201 Timer = Mission_Guard(); 202 break; 203 204 case MISSION_ENTER: 205 Timer = Mission_Enter(); 206 break; 207 208 case MISSION_CONSTRUCTION: 209 Timer = Mission_Construction(); 210 break; 211 212 case MISSION_DECONSTRUCTION: 213 Timer = Mission_Deconstruction(); 214 break; 215 216 case MISSION_CAPTURE: 217 case MISSION_SABOTAGE: 218 Timer = Mission_Capture(); 219 break; 220 221 case MISSION_MOVE: 222 Timer = Mission_Move(); 223 break; 224 225 case MISSION_ATTACK: 226 Timer = Mission_Attack(); 227 break; 228 229 case MISSION_RETREAT: 230 Timer = Mission_Retreat(); 231 break; 232 233 case MISSION_HARVEST: 234 Timer = Mission_Harvest(); 235 break; 236 237 case MISSION_GUARD_AREA: 238 Timer = Mission_Guard_Area(); 239 break; 240 241 case MISSION_RETURN: 242 Timer = Mission_Return(); 243 break; 244 245 case MISSION_STOP: 246 Timer = Mission_Stop(); 247 break; 248 249 case MISSION_AMBUSH: 250 Timer = Mission_Ambush(); 251 break; 252 253 case MISSION_HUNT: 254 case MISSION_RESCUE: 255 Timer = Mission_Hunt(); 256 break; 257 258 case MISSION_TIMED_HUNT: 259 Timer = Mission_Timed_Hunt(); 260 break; 261 262 case MISSION_UNLOAD: 263 Timer = Mission_Unload(); 264 break; 265 266 case MISSION_REPAIR: 267 Timer = Mission_Repair(); 268 break; 269 270 case MISSION_MISSILE: 271 Timer = Mission_Missile(); 272 break; 273 } 274 } 275 } 276 277 278 /*********************************************************************************************** 279 * MissionClass::Commence -- Start script with new order. * 280 * * 281 * This routine will start script processing according to any queued * 282 * order it may have. If there is no queued order, then this routine * 283 * does nothing. Call this routine whenever the unit is in a good * 284 * position to change its order (such as when it is stopped). * 285 * * 286 * INPUT: none * 287 * * 288 * OUTPUT: Did the mission actually change? * 289 * * 290 * WARNINGS: none * 291 * * 292 * HISTORY: * 293 * 04/23/1994 JLB : Created. * 294 * 07/14/1994 JLB : Simplified. * 295 * 06/17/1995 JLB : Returns success flag. * 296 *=============================================================================================*/ 297 bool MissionClass::Commence(void) 298 { 299 if (MissionQueue != MISSION_NONE) { 300 Mission = MissionQueue; 301 MissionQueue = MISSION_NONE; 302 303 /* 304 ** Force immediate state machine processing at the first state machine state value. 305 */ 306 Timer = 0; 307 Status = 0; 308 return(true); 309 } 310 return(false); 311 } 312 313 314 /*********************************************************************************************** 315 * MissionClass::Assign_Mission -- Give an order to a unit. * 316 * * 317 * This assigns an order to a unit. It does NOT do the AI, but merely * 318 * flags the unit for normal AI processing. At that time the computer * 319 * will determine the unit's course of action. * 320 * * 321 * INPUT: order -- Mission to give the unit. * 322 * * 323 * OUTPUT: none * 324 * * 325 * WARNINGS: none * 326 * * 327 * HISTORY: * 328 * 06/04/1991 JLB : Created. * 329 * 04/15/1994 JLB : Converted to member function. * 330 *=============================================================================================*/ 331 void MissionClass::Assign_Mission(MissionType order) 332 { 333 if (order == MISSION_NONE || Mission == order) return; 334 335 // Status = 0; 336 MissionQueue = order; 337 } 338 339 340 /*********************************************************************************************** 341 * MissionClass::Mission_From_Name -- Fetch order pointer from its name. * 342 * * 343 * This routine is used to convert an ASCII order name into the actual * 344 * order number it represents. Typically, this is used when processing * 345 * a scenario INI file. * 346 * * 347 * INPUT: name -- The ASCII order name to process. * 348 * * 349 * OUTPUT: Returns with the actual order number that the ASCII name * 350 * represents. * 351 * * 352 * WARNINGS: none * 353 * * 354 * HISTORY: * 355 * 10/07/1992 JLB : Created. * 356 * 04/22/1994 JLB : Converted to static member function. * 357 *=============================================================================================*/ 358 MissionType MissionClass::Mission_From_Name(char const *name) 359 { 360 MissionType order; 361 362 if (name) { 363 for (order = MISSION_FIRST; order < MISSION_COUNT; order++) { 364 if (stricmp(Missions[order], name) == 0) { 365 return(order); 366 } 367 } 368 } 369 return(MISSION_NONE); 370 } 371 372 373 /*********************************************************************************************** 374 * MissionClass::Mission_Name -- Converts a mission number into an ASCII string. * 375 * * 376 * Use this routine to convert a mission number into the ASCII string that represents * 377 * it. Typical use of this is when generating an INI file. * 378 * * 379 * INPUT: mission -- The mission number to convert. * 380 * * 381 * OUTPUT: Returns with a pointer to the ASCII string that represents the mission type. * 382 * * 383 * WARNINGS: none * 384 * * 385 * HISTORY: * 386 * 01/23/1995 JLB : Created. * 387 *=============================================================================================*/ 388 char const * MissionClass::Mission_Name(MissionType mission) 389 { 390 return(mission == MISSION_NONE ? "None" : Missions[mission]); 391 } 392 393 394 /*********************************************************************************************** 395 * MissionClass::Override_Mission -- temporarily overides the units mission * 396 * * 397 * * 398 * * 399 * INPUT: MissionType mission - the mission we want to overide * 400 * TARGET tarcom - the new target we want to overide * 401 * TARGET navcom - the new navigation point to overide * 402 * * 403 * OUTPUT: none * 404 * * 405 * WARNINGS: If a mission is already overidden, the current mission is * 406 * just re-assigned. * 407 * * 408 * HISTORY: * 409 * 04/28/1995 PWG : Created. * 410 *=============================================================================================*/ 411 void MissionClass::Override_Mission(MissionType mission, TARGET, TARGET) 412 { 413 if (MissionQueue != MISSION_NONE) { 414 SuspendedMission = MissionQueue; 415 } else { 416 SuspendedMission = Mission; 417 } 418 419 Assign_Mission(mission); 420 } 421 422 423 /*********************************************************************************************** 424 * MissionClass::Restore_Mission -- Restores overidden mission * 425 * * 426 * INPUT: none * 427 * * 428 * OUTPUT: none * 429 * * 430 * WARNINGS: none * 431 * * 432 * HISTORY: * 433 * 04/28/1995 PWG : Created. * 434 *=============================================================================================*/ 435 bool MissionClass::Restore_Mission(void) 436 { 437 if (SuspendedMission != MISSION_NONE) { 438 Assign_Mission(SuspendedMission); 439 SuspendedMission= MISSION_NONE; 440 return(true); 441 } 442 return(false); 443 } 444 445 446 /*********************************************************************************************** 447 ** Unit order names. These names correspond to the player selectable orders 448 ** a unit can have. The system initiated orders have no use for the ASCII name 449 ** associated, but they are listed here for completeness sake. 450 */ 451 char const * MissionClass::Missions[MISSION_COUNT] = { 452 "Sleep", 453 "Attack", 454 "Move", 455 "Retreat", 456 "Guard", 457 "Sticky", 458 "Enter", 459 "Capture", 460 "Harvest", 461 "Area Guard", 462 "Return", 463 "Stop", 464 "Ambush", 465 "Hunt", 466 "Timed Hunt", 467 "Unload", 468 "Sabotage", 469 "Construction", 470 "Selling", 471 "Repair", 472 "Rescue", 473 "Missile", 474 };