MISSION.CPP 30 KB

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