TARGET.CPP 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  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: F:\projects\c&c\vcs\code\target.cpv 2.17 16 Oct 1995 16:51:06 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 : TARGET.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : September 10, 1993 *
  26. * *
  27. * Last Update : August 27, 1995 [JLB] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * As_Aircraft -- Converts the target value into an aircraft pointer. *
  32. * As_Animation -- Converts target value into animation pointer. *
  33. * As_Building -- Converts a target value into a building object pointer. *
  34. * As_Bullet -- Converts the target into a bullet pointer. *
  35. * As_Cell -- Converts a target value into a cell number. *
  36. * As_Coord -- Converts a target value into a coordinate value. *
  37. * As_Infantry -- If the target is infantry, return a pointer to it. *
  38. * As_Movement_Coord -- Fetches coordinate if trying to move to this target. *
  39. * As_Object -- Converts a target value into an object pointer. *
  40. * As_Team -- Converts a target number into a team pointer. *
  41. * As_TeamType -- Converts a target into a team type pointer. *
  42. * As_Techno -- Converts a target value into a TechnoClass pointer. *
  43. * As_Trigger -- Converts specified target into a trigger pointer. *
  44. * As_Unit -- Converts a target value into a unit pointer. *
  45. * Target_Legal -- Determines if the specified target is legal. *
  46. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  47. #include "function.h"
  48. #include "target.h"
  49. /***********************************************************************************************
  50. * As_Trigger -- Converts specified target into a trigger pointer. *
  51. * *
  52. * This routine will convert the specified target number into a trigger pointer. *
  53. * *
  54. * INPUT: target -- The target number to convert. *
  55. * *
  56. * OUTPUT: Returns with the trigger pointer that the specified target number represents. If *
  57. * it doesn't represent a legal trigger object, then NULL is returned. *
  58. * *
  59. * WARNINGS: none *
  60. * *
  61. * HISTORY: *
  62. * 07/08/1995 JLB : Created. *
  63. *=============================================================================================*/
  64. TriggerClass * As_Trigger(TARGET target, bool check_active)
  65. {
  66. TriggerClass* trigger = Is_Target_Trigger(target) ? Triggers.Raw_Ptr(Target_Value(target)) : NULL;
  67. if (check_active && trigger != NULL && !trigger->IsActive) {
  68. trigger = NULL;
  69. }
  70. return(trigger);
  71. }
  72. /***********************************************************************************************
  73. * As_Team -- Converts a target number into a team pointer. *
  74. * *
  75. * This routine will convert the specified target number into a team pointer. *
  76. * *
  77. * INPUT: target -- The target number to convert. *
  78. * *
  79. * OUTPUT: Returns with the team object that the specified target number represents. If it *
  80. * doesn't represent a legal team then NULL is returned. *
  81. * *
  82. * WARNINGS: none *
  83. * *
  84. * HISTORY: *
  85. * 07/08/1995 JLB : Created. *
  86. *=============================================================================================*/
  87. TeamClass * As_Team(TARGET target, bool check_active)
  88. {
  89. TeamClass* team = Is_Target_Team(target) ? Teams.Raw_Ptr(Target_Value(target)) : NULL;
  90. if (check_active && team != NULL && !team->IsActive) {
  91. team = NULL;
  92. }
  93. return(team);
  94. }
  95. /***********************************************************************************************
  96. * As_TeamType -- Converts a target into a team type pointer. *
  97. * *
  98. * This routine will convert the specified target number into a team type pointer. *
  99. * *
  100. * INPUT: target -- The target number to convert. *
  101. * *
  102. * OUTPUT: Returns with a pointer to the team type represented by the target number. If the *
  103. * target number doesn't represent a legal team type, then NULL is returned. *
  104. * *
  105. * WARNINGS: none *
  106. * *
  107. * HISTORY: *
  108. * 07/08/1995 JLB : Created. *
  109. *=============================================================================================*/
  110. TeamTypeClass * As_TeamType(TARGET target)
  111. {
  112. return(Is_Target_TeamType(target) ? TeamTypes.Raw_Ptr(Target_Value(target)) : NULL);
  113. }
  114. /***********************************************************************************************
  115. * As_Animation -- Converts target value into animation pointer. *
  116. * *
  117. * This routine will convert the specified target number into an animation pointer. *
  118. * *
  119. * INPUT: target -- The target number to convert into an animation pointer. *
  120. * *
  121. * OUTPUT: Returns with a pointer to the legal animation that this target represents. If it *
  122. * doesn't represent a legal animation, then NULL is returned. *
  123. * *
  124. * WARNINGS: none *
  125. * *
  126. * HISTORY: *
  127. * 07/08/1995 JLB : Created. *
  128. *=============================================================================================*/
  129. AnimClass * As_Animation(TARGET target, bool check_active)
  130. {
  131. AnimClass* anim = Is_Target_Animation(target) ? Anims.Raw_Ptr(Target_Value(target)) : NULL;
  132. if (check_active && anim != NULL && !anim->IsActive) {
  133. anim = NULL;
  134. }
  135. return(anim);
  136. }
  137. /***********************************************************************************************
  138. * As_Bullet -- Converts the target into a bullet pointer. *
  139. * *
  140. * This routine will convert the specified target number into a bullet pointer. *
  141. * *
  142. * INPUT: target -- The target number to convert. *
  143. * *
  144. * OUTPUT: Returns with a pointer to the bullet it specifies. If the target doesn't refer to *
  145. * a legal bullet, then NULL is returned. *
  146. * *
  147. * WARNINGS: none *
  148. * *
  149. * HISTORY: *
  150. * 07/08/1995 JLB : Created. *
  151. *=============================================================================================*/
  152. BulletClass * As_Bullet(TARGET target, bool check_active)
  153. {
  154. BulletClass* bullet = Is_Target_Bullet(target) ? Bullets.Raw_Ptr(Target_Value(target)) : NULL;
  155. if (check_active && bullet != NULL && !bullet->IsActive) {
  156. bullet = NULL;
  157. }
  158. return(bullet);
  159. }
  160. /***********************************************************************************************
  161. * As_Aircraft -- Converts the target value into an aircraft pointer. *
  162. * *
  163. * This routine will convert the specified target value into an aircraft object pointer. *
  164. * *
  165. * INPUT: target -- The target value to convert. *
  166. * *
  167. * OUTPUT: Returns with a pointer to the aircraft that this target value represents. If the *
  168. * specified target value doesn't represent an aircraft, then NULL is returned. *
  169. * *
  170. * WARNINGS: none *
  171. * *
  172. * HISTORY: *
  173. * 08/27/1995 JLB : Created. *
  174. *=============================================================================================*/
  175. AircraftClass * As_Aircraft(TARGET target, bool check_active)
  176. {
  177. AircraftClass* aircraft = Is_Target_Aircraft(target) ? Aircraft.Raw_Ptr(Target_Value(target)) : NULL;
  178. if (check_active && aircraft != NULL && !aircraft->IsActive) {
  179. aircraft = NULL;
  180. }
  181. return(aircraft);
  182. }
  183. /***********************************************************************************************
  184. * As_Techno -- Converts a target value into a TechnoClass pointer. *
  185. * *
  186. * This routine will take the target value specified and convert it into a TechnoClass *
  187. * pointer if the target represents an object that has a TechnoClass. *
  188. * *
  189. * INPUT: target -- The target value to convert into a TechnoClass pointer. *
  190. * *
  191. * OUTPUT: Returns with a pointer to the associated object's TechnoClass. If the target *
  192. * cannot be converted into a TechnoClass pointer, then NULL is returned. *
  193. * *
  194. * WARNINGS: none *
  195. * *
  196. * HISTORY: *
  197. * 06/02/1994 JLB : Created. *
  198. *=============================================================================================*/
  199. TechnoClass * As_Techno(TARGET target, bool check_active)
  200. {
  201. ObjectClass * obj = As_Object(target, check_active);
  202. if (obj && obj->Is_Techno()) {
  203. return(TechnoClass *)obj;
  204. }
  205. return(NULL);
  206. }
  207. /***********************************************************************************************
  208. * As_Object -- Converts a target value into an object pointer. *
  209. * *
  210. * This routine is used to convert the target value specified into an object pointer. If *
  211. * the target doesn't represent an object or the target value is illegal, then NULL is *
  212. * returned. *
  213. * *
  214. * INPUT: target -- The target value to convert from. *
  215. * check_active -- Check if the target is active, return NULL if not. *
  216. * *
  217. * OUTPUT: Returns with a pointer to the object it represent, or NULL if not an object. *
  218. * *
  219. * WARNINGS: none *
  220. * *
  221. * HISTORY: *
  222. * 05/27/1994 JLB : Created. *
  223. *=============================================================================================*/
  224. ObjectClass * As_Object(TARGET target, bool check_active)
  225. {
  226. int val = Target_Value(target);
  227. ObjectClass * object = NULL;
  228. switch (Target_Kind(target)) {
  229. case KIND_INFANTRY:
  230. object = Infantry.Raw_Ptr(val);
  231. break;
  232. case KIND_UNIT:
  233. object = Units.Raw_Ptr(val);
  234. break;
  235. case KIND_BUILDING:
  236. object = Buildings.Raw_Ptr(val);
  237. break;
  238. case KIND_AIRCRAFT:
  239. object = Aircraft.Raw_Ptr(val);
  240. break;
  241. case KIND_TERRAIN:
  242. object = Terrains.Raw_Ptr(val);
  243. break;
  244. case KIND_BULLET:
  245. object = Bullets.Raw_Ptr(val);
  246. break;
  247. case KIND_ANIMATION:
  248. object = Anims.Raw_Ptr(val);
  249. break;
  250. default:
  251. break;
  252. }
  253. /*
  254. ** Special check to ensure that a target value that references an
  255. ** invalid object will not be converted back into an object pointer.
  256. ** This condition is rare, but could occur in a network game if the
  257. ** object it refers to is destroyed between the time an event message
  258. ** is sent and when it is received.
  259. */
  260. if (check_active && object != NULL && !object->IsActive) {
  261. object = NULL;
  262. }
  263. return(object);
  264. }
  265. /***********************************************************************************************
  266. * As_Unit -- Converts a target value into a unit pointer. *
  267. * *
  268. * This routine is used to convert the target value specified into a pointer to a unit *
  269. * object. *
  270. * *
  271. * INPUT: target -- The target value to convert into a unit pointer. *
  272. * *
  273. * OUTPUT: Returns with a pointer to the unit the target value represents or NULL if not *
  274. * a unit. *
  275. * *
  276. * WARNINGS: none *
  277. * *
  278. * HISTORY: *
  279. * 05/27/1994 JLB : Created. *
  280. *=============================================================================================*/
  281. UnitClass * As_Unit(TARGET target, bool check_active)
  282. {
  283. UnitClass* unit = Is_Target_Unit(target) ? Units.Raw_Ptr(Target_Value(target)) : NULL;
  284. if (check_active && unit != NULL && !unit->IsActive) {
  285. unit = NULL;
  286. }
  287. return(unit);
  288. }
  289. /***********************************************************************************************
  290. * As_Infantry -- If the target is infantry, return a pointer to it. *
  291. * *
  292. * This routine will translate the specified target value into an infantry pointer if the *
  293. * target actually represents an infantry object. *
  294. * *
  295. * INPUT: target -- The target to convert to a pointer. *
  296. * *
  297. * OUTPUT: Returns a pointer to the infantry object that this target value represents. If *
  298. * the target doesn't represent an infantry object, then return NULL. *
  299. * *
  300. * WARNINGS: none *
  301. * *
  302. * HISTORY: *
  303. * 10/17/1994 JLB : Created. *
  304. *=============================================================================================*/
  305. InfantryClass * As_Infantry(TARGET target, bool check_active)
  306. {
  307. InfantryClass* infantry = Is_Target_Infantry(target) ? Infantry.Raw_Ptr(Target_Value(target)) : NULL;
  308. if (check_active && infantry != NULL && !infantry->IsActive) {
  309. infantry = NULL;
  310. }
  311. return(infantry);
  312. }
  313. #ifdef NEVER
  314. TerrainClass * As_Terrain(TARGET target)
  315. {
  316. return(Is_Target_Terrain(target) ? &Terrains[Target_Value(target)] : NULL);
  317. }
  318. #endif
  319. /***********************************************************************************************
  320. * As_Building -- Converts a target value into a building object pointer. *
  321. * *
  322. * This routine is used to convert the target value specified into a building pointer. *
  323. * *
  324. * INPUT: target -- The target value to convert from. *
  325. * *
  326. * OUTPUT: Returns with a pointer to the building object that the target value represents. *
  327. * If it doesn't represent a building, then return NULL. *
  328. * *
  329. * WARNINGS: none *
  330. * *
  331. * HISTORY: *
  332. * 05/27/1994 JLB : Created. *
  333. *=============================================================================================*/
  334. BuildingClass * As_Building(TARGET target, bool check_active)
  335. {
  336. BuildingClass* building = Is_Target_Building(target) ? Buildings.Raw_Ptr(Target_Value(target)) : NULL;
  337. if (check_active && building != NULL && !building->IsActive) {
  338. building = NULL;
  339. }
  340. return(building);
  341. }
  342. /***********************************************************************************************
  343. * Target_Legal -- Determines if the specified target is legal. *
  344. * *
  345. * This routine is used to check for the legality of the target value specified. It is *
  346. * necessary to call this routine if there is doubt about the the legality of the target. *
  347. * It is possible for the unit that a target value represents to be eliminated and thus *
  348. * rendering the target value invalid. *
  349. * *
  350. * INPUT: target -- The target value to check. *
  351. * *
  352. * OUTPUT: bool; Is the target value legal? *
  353. * *
  354. * WARNINGS: none *
  355. * *
  356. * HISTORY: *
  357. * 05/27/1994 JLB : Created. *
  358. *=============================================================================================*/
  359. bool Target_Legal(TARGET target)
  360. {
  361. if (target == TARGET_NONE) return(false);
  362. ObjectClass * obj = As_Object(target, false);
  363. if (obj) {
  364. return(obj->IsActive);
  365. }
  366. return(true);
  367. }
  368. /***********************************************************************************************
  369. * As_Cell -- Converts a target value into a cell number. *
  370. * *
  371. * This routine is used to convert the target value specified, into a cell value. This is *
  372. * necessary for find path and other procedures that need a cell value. *
  373. * *
  374. * INPUT: target -- The target value to convert to a cell value. *
  375. * *
  376. * OUTPUT: Returns with the target value expressed as a cell location. *
  377. * *
  378. * WARNINGS: none *
  379. * *
  380. * HISTORY: *
  381. * 05/27/1994 JLB : Created. *
  382. *=============================================================================================*/
  383. CELL As_Cell(TARGET target)
  384. {
  385. return(Coord_Cell(As_Coord(target)));
  386. }
  387. /***********************************************************************************************
  388. * As_Coord -- Converts a target value into a coordinate value. *
  389. * *
  390. * This routine is used to convert the target value specified into a coordinate value. It *
  391. * is necessary for those procedures that require a coordinate value. *
  392. * *
  393. * INPUT: target -- The target value to convert. *
  394. * *
  395. * OUTPUT: Returns with the target expressed as a COORD value. *
  396. * *
  397. * WARNINGS: none *
  398. * *
  399. * HISTORY: *
  400. * 05/27/1994 JLB : Created. *
  401. * 11/16/1994 JLB : Simplified. *
  402. *=============================================================================================*/
  403. COORDINATE As_Coord(TARGET target)
  404. {
  405. if (Target_Legal(target)) {
  406. /*
  407. ** Cell target values are handled as a special case. The value of the target number is
  408. ** actually the cell index number.
  409. */
  410. if (Is_Target_Cell(target)) {
  411. return(Cell_Coord((CELL)Target_Value(target)));
  412. }
  413. /*
  414. ** Normal targets correspond to game objects. Fetch the object pointer and then ask it
  415. ** for the center coordinate. Return the center coordinate as the target's coordinate.
  416. */
  417. ObjectClass * obj = As_Object(target);
  418. if (obj) {
  419. /*
  420. ** If this is invalid memory or the object is dead then return 0
  421. ** This is a kludge to fix the problem of team target objects being assigned after
  422. ** the object is already destroyed - 1/15/97 3:13PM
  423. */
  424. if (IsBadReadPtr ((void*)obj, sizeof (ObjectClass) ) || !obj->IsActive){
  425. //OutputDebugString ("C&C95 - As_Coord called for invalid target object\m");
  426. return(0x00000000L);
  427. }
  428. return(obj->Target_Coord());
  429. }
  430. }
  431. /*
  432. ** An unrecognized target value results in a null coordinate value.
  433. */
  434. return(0x00000000L);
  435. }
  436. /***********************************************************************************************
  437. * As_Movement_Coord -- Fetches coordinate if trying to move to this target. *
  438. * *
  439. * This routine will convert the specified target into a coordinate location. This location *
  440. * is used when moving to the target specified. For cells, this is the center of the cell. *
  441. * For special buildings that allow docking, it is the center location of the docking *
  442. * bay. *
  443. * *
  444. * INPUT: target -- The target to convert into a coordinate value. *
  445. * *
  446. * OUTPUT: Returns with the docking coordinate of the target value specified. *
  447. * *
  448. * WARNINGS: none *
  449. * *
  450. * HISTORY: *
  451. * 08/27/1995 JLB : Created. *
  452. *=============================================================================================*/
  453. COORDINATE As_Movement_Coord(TARGET target)
  454. {
  455. if (Target_Legal(target)) {
  456. /*
  457. ** Cell target values are handled as a special case. The value of the target number is
  458. ** actually the cell index number.
  459. */
  460. if (Is_Target_Cell(target)) {
  461. return(Cell_Coord((CELL)Target_Value(target)));
  462. }
  463. /*
  464. ** Normal targets correspond to game objects. Fetch the object pointer and then ask it
  465. ** for the center coordinate. Return the center coordinate as the target's coordinate.
  466. */
  467. ObjectClass * obj = As_Object(target);
  468. if (obj) {
  469. return(obj->Docking_Coord());
  470. }
  471. }
  472. /*
  473. ** An unrecognized target value results in a null coordinate value.
  474. */
  475. return(0x00000000L);
  476. }