OBJECT.CPP 98 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713
  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\object.cpv 2.17 16 Oct 1995 16:49:22 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 : OBJECT.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : April 29, 1994 *
  26. * *
  27. * Last Update : August 13, 1995 [JLB] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * ObjectClass::Debug_Dump -- Displays status of the object class to the mono monitor. *
  32. * ObjectClass::Detach_All -- Removes the object from all tracking systems. *
  33. * ObjectClass::Detach_This_From_All -- Detatches this object from all others. *
  34. * ObjectClass::Fire_Out -- Informs object that attached animation has finished. *
  35. * ObjectClass::Get_Mission -- Fetches the current mission of this object. *
  36. * ObjectClass::Init -- Initializes the basic object system. *
  37. * ObjectClass::Limbo -- Brings the object into a state of limbo. *
  38. * ObjectClass::Mark -- Handles basic marking logic. *
  39. * ObjectClass::Mark_For_Redraw -- Marks object and system for redraw. *
  40. * ObjectClass::Move -- Moves (by force) the object in the desired direction. *
  41. * ObjectClass::ObjectClass -- Default constructor for objects. *
  42. * ObjectClass::Passive_Click_With -- Right mouse button click process. *
  43. * ObjectClass::Receive_Message -- Processes an incoming radio message. *
  44. * ObjectClass::Render -- Displays the object onto the map. *
  45. * ObjectClass::Repair -- Handles object repair control. *
  46. * ObjectClass::Revealed -- Reveals this object to the house specified. *
  47. * ObjectClass::Select -- Try to make this object the "selected" object. *
  48. * ObjectClass::Sell_Back -- Sells the object -- if possible. *
  49. * ObjectClass::Take_Damage -- Applies damage to the object. *
  50. * ObjectClass::Unlimbo -- Brings the object into the game system. *
  51. * ObjectClass::Unselect -- This will un-select the object if it was selected. *
  52. * ObjectClass::Value -- Fetches the target value of this object. *
  53. * ObjectClass::What_Action -- Deteremines what action to perform on specified object. *
  54. * ObjectClass::What_Am_I -- RTTI query of this object type. *
  55. * ObjectTypeClass::Cost_Of -- Returns the cost to buy this unit. *
  56. * ObjectTypeClass::Dimensions -- Gets the dimensions of the object in pixels. *
  57. * ObjectTypeClass::Get_Cameo_Data -- Fetches pointer to cameo data for this object type. *
  58. * ObjectTypeClass::Max_Pips -- Fetches the maximum pips allowed for this object. *
  59. * ObjectTypeClass::ObjectTypeClass -- Normal constructor for object type class objects. *
  60. * ObjectTypeClass::Occupy_List -- Returns with simple occupation list for object. *
  61. * ObjectTypeClass::One_Time -- Handles one time processing for object types. *
  62. * ObjectTypeClass::Overlap_List -- Returns a pointer to a simple overlap list. *
  63. * ObjectTypeClass::Time_To_Build -- Fetches the time to construct this object. *
  64. * ObjectTypeClass::Who_Can_Build_Me -- Finds the factory building that can build this object*
  65. * ObjectClass::What_Action -- Returns with the action to perform for this object. *
  66. * ObjectClass::In_Which_Layer -- Fetches what layer this object is located in. *
  67. * ObjectClass::Is_Techno -- Checks to see if this object is a techno type. *
  68. * ObjectClass::Get_Ownable -- Fetches the house owner legality options for this object. *
  69. * ObjectClass::Can_Repair -- Queries whether this object can be repaired. *
  70. * ObjectClass::Can_Demolish -- Queries whether this object can be sold back. *
  71. * ObjectClass::Can_Player_Fire -- Can the player give this object an attack mission? *
  72. * ObjectClass::Can_Player_Move -- Can the player give this object a movement mission? *
  73. * ObjectClass::Target_Coord -- Fetches the coordinate if this object is a target. *
  74. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  75. #include "function.h"
  76. /*
  77. ** Selected objects have a special marking box around them. This is the shapes that are
  78. ** used for this purpose.
  79. */
  80. void const * ObjectTypeClass::SelectShapes = 0;
  81. void const * ObjectTypeClass::PipShapes = 0;
  82. bool ObjectClass::Is_Infantry(void) const
  83. {
  84. return(false);
  85. }
  86. /***********************************************************************************************
  87. * ObjectTypeClass::ObjectTypeClass -- Normal constructor for object type class objects. *
  88. * *
  89. * This is the base constructor that is used when constructing the object type classes. *
  90. * Every tangible game piece type calls this constructor for the ObjectTypeClass. This *
  91. * class holds static information that is common to objects in general. *
  92. * *
  93. * INPUT: see below... *
  94. * *
  95. * OUTPUT: none *
  96. * *
  97. * WARNINGS: none *
  98. * *
  99. * HISTORY: *
  100. * 03/23/1995 JLB : Created. *
  101. *=============================================================================================*/
  102. ObjectTypeClass::ObjectTypeClass(
  103. bool is_sentient,
  104. bool is_flammable,
  105. bool is_crushable,
  106. bool is_stealthy,
  107. bool is_selectable,
  108. bool is_legal_target,
  109. bool is_insignificant,
  110. bool is_immune,
  111. int name,
  112. char const *ini,
  113. ArmorType armor,
  114. unsigned short strength) :
  115. AbstractTypeClass(name, ini)
  116. {
  117. IsSentient = is_sentient;
  118. IsFlammable = is_flammable;
  119. IsCrushable = is_crushable;
  120. IsStealthy = is_stealthy;
  121. IsSelectable = is_selectable;
  122. IsLegalTarget = is_legal_target;
  123. IsInsignificant = is_insignificant;
  124. IsImmune = is_immune;
  125. Armor = armor;
  126. MaxStrength = strength;
  127. ImageData = NULL;
  128. //RadarIcon = NULL;
  129. }
  130. /***********************************************************************************************
  131. * ObjectTypeClass::Max_Pips -- Fetches the maximum pips allowed for this object. *
  132. * *
  133. * This routine will return the maximum number of pips that can be displayed for this *
  134. * object. When dealing with generic objects, this value is always zero. *
  135. * *
  136. * INPUT: none *
  137. * *
  138. * OUTPUT: Returns with the number of pip boxes (empty or otherwise) to display. *
  139. * *
  140. * WARNINGS: none *
  141. * *
  142. * HISTORY: *
  143. * 07/19/1995 JLB : Created. *
  144. *=============================================================================================*/
  145. int ObjectTypeClass::Max_Pips(void) const
  146. {
  147. return(0);
  148. }
  149. /***********************************************************************************************
  150. * ObjectTypeClass::Dimensions -- Gets the dimensions of the object in pixels. *
  151. * *
  152. * This routine will fetch the dimensions of this object expressed as pixels width and *
  153. * pixels height. This information can be used to intelligently update the clipping *
  154. * rectangles. *
  155. * *
  156. * INPUT: width -- Reference to the width variable that will be filled in. *
  157. * *
  158. * height -- Reference to the height variable that will be filled in. *
  159. * *
  160. * OUTPUT: none *
  161. * *
  162. * WARNINGS: none *
  163. * *
  164. * HISTORY: *
  165. * 07/19/1995 JLB : Created. *
  166. *=============================================================================================*/
  167. void ObjectTypeClass::Dimensions(int &width, int &height) const
  168. {
  169. width = 10;
  170. height = 10;
  171. }
  172. /***********************************************************************************************
  173. * ObjectTypeClass::Cost_Of -- Returns the cost to buy this unit. *
  174. * *
  175. * This routine will return the cost to purchase this unit. This routine is expected to be *
  176. * overridden by the objects that can actually be purchased. All other object types can *
  177. * simply return zero since this value won't be used. *
  178. * *
  179. * INPUT: none *
  180. * *
  181. * OUTPUT: Returns the cost of the object. *
  182. * *
  183. * WARNINGS: none *
  184. * *
  185. * HISTORY: *
  186. * 07/19/1995 JLB : Created. *
  187. *=============================================================================================*/
  188. int ObjectTypeClass::Cost_Of(void) const
  189. {
  190. return(0);
  191. }
  192. /***********************************************************************************************
  193. * ObjectTypeClass::Time_To_Build -- Fetches the time to construct this object. *
  194. * *
  195. * This routine will fetch the time in takes to construct this object. Objects that can *
  196. * be constructed will override this routine in order to return a useful value. *
  197. * *
  198. * INPUT: none *
  199. * *
  200. * OUTPUT: Returns with the time units (arbitrary) that it takes to construct this object. *
  201. * *
  202. * WARNINGS: none *
  203. * *
  204. * HISTORY: *
  205. * 07/19/1995 JLB : Created. *
  206. *=============================================================================================*/
  207. int ObjectTypeClass::Time_To_Build(HousesType ) const
  208. {
  209. return(0);
  210. }
  211. /***********************************************************************************************
  212. * ObjectTypeClass::Who_Can_Build_Me -- Finds the factory building that can build this object. *
  213. * *
  214. * This routine will search for a factory building that can build this object type. *
  215. * *
  216. * INPUT: <NA> this routine is just here to be overridden by other classes. *
  217. * *
  218. * OUTPUT: Returns with a pointer to the building that can construct the object specified. *
  219. * *
  220. * WARNINGS: none *
  221. * *
  222. * HISTORY: *
  223. * 07/19/1995 JLB : Created. *
  224. *=============================================================================================*/
  225. BuildingClass * ObjectTypeClass::Who_Can_Build_Me(bool, bool, HousesType) const
  226. {
  227. return(NULL);
  228. }
  229. /***********************************************************************************************
  230. * ObjectTypeClass::Get_Cameo_Data -- Fetches pointer to cameo data for this object type. *
  231. * *
  232. * This routine will return with the cameo data pointer for this object type. It is *
  233. * expected that objects that can appear on the sidebar will override this routine in order *
  234. * to provide proper cameo data pointer. *
  235. * *
  236. * INPUT: none *
  237. * *
  238. * OUTPUT: Returns with a pointer to the cameo shape data. *
  239. * *
  240. * WARNINGS: none *
  241. * *
  242. * HISTORY: *
  243. * 07/19/1995 JLB : Created. *
  244. *=============================================================================================*/
  245. void const * ObjectTypeClass::Get_Cameo_Data(void) const
  246. {
  247. return(NULL);
  248. }
  249. /***********************************************************************************************
  250. * ObjectClass::ObjectClass -- Default constructor for objects. *
  251. * *
  252. * This is the default constructor for objects. It is called as an inherent part of the *
  253. * construction process for all the normal game objects instantiated. It serves merely to *
  254. * initialize the object values to a common (default) state. *
  255. * *
  256. * INPUT: none *
  257. * *
  258. * OUTPUT: none *
  259. * *
  260. * WARNINGS: Objects always start in a state of limbo. They must be Unlimbo()ed before they *
  261. * can be used. *
  262. * *
  263. * HISTORY: *
  264. * 09/24/1994 JLB : Created. *
  265. *=============================================================================================*/
  266. ObjectClass::ObjectClass(void)
  267. {
  268. Coord = 0xFFFFFFFFL; // Some bogus illegal value.
  269. Next = 0; // Not part of any object list.
  270. Trigger = 0; // No associated trigger.
  271. IsToDamage = false;
  272. IsToDisplay = false; // Redraw is presumed unnecessary.
  273. IsInLimbo = true; // Always presumed to start in limbo state.
  274. IsSelected = false; // Limboed units cannot be selected.
  275. IsDown = false; // Limboed units cannot be on the map.
  276. IsAnimAttached = false; // Anim is not attached.
  277. Strength = 255; // nominal strength value
  278. IsSelectedMask = 0; // Mask showing who has selected this object
  279. }
  280. /***********************************************************************************************
  281. * ObjectClass::What_Am_I -- RTTI query of this object type. *
  282. * *
  283. * This routine will never be called, but is here for completeness. Every object that *
  284. * is derived from object class must overload this function and return their own proper *
  285. * object RTTI value. *
  286. * *
  287. * INPUT: none *
  288. * *
  289. * OUTPUT: Returns with the RTTI value that coresponds to the object's type. *
  290. * *
  291. * WARNINGS: none *
  292. * *
  293. * HISTORY: *
  294. * 07/19/1995 JLB : Created. *
  295. *=============================================================================================*/
  296. RTTIType ObjectClass::What_Am_I(void) const
  297. {
  298. return(RTTI_OBJECT);
  299. }
  300. /***********************************************************************************************
  301. * ObjectClass::What_Action -- Deteremines what action to perform on specified object. *
  302. * *
  303. * This routine will return that action that this object could perform if the mouse were *
  304. * clicked over the object specified. *
  305. * *
  306. * INPUT: object -- Pointer to the object to check this object against when determining *
  307. * the action to perform. *
  308. * *
  309. * OUTPUT: It returns that action that will be performed if the mouse were clicked over the *
  310. * object. Since non-derived objects cannot do anything, and cannot even be *
  311. * instantiated, this routine will always return ACTION_NONE. *
  312. * *
  313. * WARNINGS: none *
  314. * *
  315. * HISTORY: *
  316. * 07/19/1995 JLB : Created. *
  317. *=============================================================================================*/
  318. ActionType ObjectClass::What_Action(ObjectClass *) const
  319. {
  320. return(ACTION_NONE);
  321. }
  322. /***********************************************************************************************
  323. * ObjectClass::What_Action -- Returns with the action to perform for this object. *
  324. * *
  325. * This routine is called when information on a potential action if the mouse were clicked *
  326. * on the cell specified. This routine merely serves as a virtual placeholder so that *
  327. * object types that can actually perform some action will override this routine to provide *
  328. * true functionality. *
  329. * *
  330. * INPUT: cell -- The cell that the mouse is over and might be clicked on. *
  331. * *
  332. * OUTPUT: Returns with the action that this object would try to perform if the mouse were *
  333. * clicked. Since objects at this level have no ability to do anything, this routine *
  334. * will always returns ACTION_NONE unless it is overridden. *
  335. * *
  336. * WARNINGS: none *
  337. * *
  338. * HISTORY: *
  339. * 08/13/1995 JLB : Created. *
  340. *=============================================================================================*/
  341. ActionType ObjectClass::What_Action(CELL) const
  342. {
  343. return(ACTION_NONE);
  344. }
  345. /***********************************************************************************************
  346. * ObjectClass::In_Which_Layer -- Fetches what layer this object is located in. *
  347. * *
  348. * The default layer for object location is the LAYER_GROUND. Aircraft will override this *
  349. * routine and make adjustments as necessary according to the aircraft's altitude. *
  350. * *
  351. * INPUT: none *
  352. * *
  353. * OUTPUT: Returns with the layer that this object is located in. *
  354. * *
  355. * WARNINGS: none *
  356. * *
  357. * HISTORY: *
  358. * 08/13/1995 JLB : Created. *
  359. *=============================================================================================*/
  360. LayerType ObjectClass::In_Which_Layer(void) const
  361. {
  362. return(LAYER_GROUND);
  363. }
  364. /***********************************************************************************************
  365. * ObjectClass::Is_Techno -- Checks to see if this object is a techno type. *
  366. * *
  367. * Most active objects in the game are of the techno type. This routine will return true *
  368. * if called on an object that is derived from TechnoClass. The RTTI interface is *
  369. * insufficient for this purpose -- hence the existence of this routine. *
  370. * *
  371. * INPUT: none *
  372. * *
  373. * OUTPUT: Is this object derived from the TechnoClass object? This is true for units, *
  374. * infantry, aircraft, and buildings. *
  375. * *
  376. * WARNINGS: none *
  377. * *
  378. * HISTORY: *
  379. * 08/13/1995 JLB : Created. *
  380. *=============================================================================================*/
  381. bool ObjectClass::Is_Techno(void) const
  382. {
  383. return(false);
  384. }
  385. /***********************************************************************************************
  386. * ObjectClass::Get_Ownable -- Fetches the house owner legality options for this object. *
  387. * *
  388. * This routine will return the ownable bits for this object. Objects at this level can't *
  389. * really be owned by anyone, but return the full spectrum of legality just to be safe. *
  390. * *
  391. * INPUT: none *
  392. * *
  393. * OUTPUT: Returns with the ownable flags (as a combined bitfield) for this object. *
  394. * *
  395. * WARNINGS: none *
  396. * *
  397. * HISTORY: *
  398. * 08/13/1995 JLB : Created. *
  399. *=============================================================================================*/
  400. unsigned char ObjectClass::Get_Ownable(void) const
  401. {
  402. return(0xff);
  403. }
  404. /***********************************************************************************************
  405. * ObjectClass::Can_Repair -- Queries whether this object can be repaired. *
  406. * *
  407. * Most objects cannot be repaired. This routine defaults to returning "false", but is *
  408. * overridden by derived functions defined by object types that can support repair. *
  409. * *
  410. * INPUT: none *
  411. * *
  412. * OUTPUT: Can this object be repaired? *
  413. * *
  414. * WARNINGS: none *
  415. * *
  416. * HISTORY: *
  417. * 08/13/1995 JLB : Created. *
  418. *=============================================================================================*/
  419. bool ObjectClass::Can_Repair(void) const
  420. {
  421. return(false);
  422. }
  423. /***********************************************************************************************
  424. * ObjectClass::Can_Demolish -- Queries whether this object can be sold back. *
  425. * *
  426. * This routine is used to determine if this object can be sold. Most objects cannot be *
  427. * but for those objects that can, this routine will be overridden as necessary. *
  428. * *
  429. * INPUT: none *
  430. * *
  431. * OUTPUT: Can this object be sold back? Typically, the answer is no. *
  432. * *
  433. * WARNINGS: none *
  434. * *
  435. * HISTORY: *
  436. * 08/13/1995 JLB : Created. *
  437. *=============================================================================================*/
  438. bool ObjectClass::Can_Demolish(void) const
  439. {
  440. return(false);
  441. }
  442. bool ObjectClass::Can_Demolish_Unit(void) const
  443. {
  444. return(false);
  445. }
  446. bool ObjectClass::Can_Capture(void) const
  447. {
  448. return(false);
  449. }
  450. /***********************************************************************************************
  451. * ObjectClass::Can_Player_Fire -- Can the player give this object an attack mission? *
  452. * *
  453. * This routine is used to determine if attacking is an option under player control with *
  454. * respect to this unit. This routine will be overridden as necessary for those objects *
  455. * that have the ability to attack. *
  456. * *
  457. * INPUT: none *
  458. * *
  459. * OUTPUT: Can this object be given an attack order by the player? *
  460. * *
  461. * WARNINGS: none *
  462. * *
  463. * HISTORY: *
  464. * 08/13/1995 JLB : Created. *
  465. *=============================================================================================*/
  466. bool ObjectClass::Can_Player_Fire(void) const
  467. {
  468. return(false);
  469. }
  470. /***********************************************************************************************
  471. * ObjectClass::Can_Player_Move -- Can the player give this object a movement mission? *
  472. * *
  473. * This routine is used to determine if the player has the ability to command this object *
  474. * with a movement mission. This routine will be overridden as necessary to support this *
  475. * ability. *
  476. * *
  477. * INPUT: none *
  478. * *
  479. * OUTPUT: Can this object be given a movement mission by the player? *
  480. * *
  481. * WARNINGS: none *
  482. * *
  483. * HISTORY: *
  484. * 08/13/1995 JLB : Created. *
  485. *=============================================================================================*/
  486. bool ObjectClass::Can_Player_Move(void) const
  487. {
  488. return(false);
  489. }
  490. /***********************************************************************************************
  491. * ObjectClass::Target_Coord -- Fetches the coordinate if this object is a target. *
  492. * *
  493. * When the coordinate to use when firing at this object is needed, this routine will *
  494. * provide it. Normal objects just use the center of the object for this, but there are *
  495. * some more sophisticated objects that are not fired upon the center. *
  496. * *
  497. * INPUT: none *
  498. * *
  499. * OUTPUT: Returns with the coordinate to fire at if this object is a target. *
  500. * *
  501. * WARNINGS: none *
  502. * *
  503. * HISTORY: *
  504. * 08/13/1995 JLB : Created. *
  505. *=============================================================================================*/
  506. COORDINATE ObjectClass::Target_Coord(void) const
  507. {
  508. return(Center_Coord());
  509. }
  510. COORDINATE ObjectClass::Center_Coord(void) const {return Coord;};
  511. COORDINATE ObjectClass::Render_Coord(void) const {return(Center_Coord());}
  512. COORDINATE ObjectClass::Docking_Coord(void) const {return(Center_Coord());}
  513. COORDINATE ObjectClass::Sort_Y(void) const {return Coord;};
  514. FireDataType ObjectClass::Fire_Data(int which) const {return{Fire_Coord(which),0};}
  515. COORDINATE ObjectClass::Fire_Coord(int ) const {return Coord;};
  516. void ObjectClass::Record_The_Kill(TechnoClass * ) {};
  517. void ObjectClass::Do_Shimmer(void) {};
  518. int ObjectClass::Exit_Object(TechnoClass *) {return 0;};
  519. void ObjectClass::Hidden(void) {};
  520. void ObjectClass::Look(bool ) {};
  521. void ObjectClass::Active_Click_With(ActionType , ObjectClass *) {};
  522. void ObjectClass::Active_Click_With(ActionType , CELL ) {};
  523. void ObjectClass::Clicked_As_Target(HousesType house, int) {}; // 2019/09/20 JAS - Added record of who clicked on the object
  524. bool ObjectClass::In_Range(COORDINATE , int) const {return false;};
  525. int ObjectClass::Weapon_Range(int) const {return 0x0000;};
  526. TARGET ObjectClass::As_Target(void) const {return TARGET_NONE;};
  527. void ObjectClass::Scatter(COORDINATE , bool, bool) {};
  528. bool ObjectClass::Catch_Fire(void) {return false;};
  529. /***********************************************************************************************
  530. * ObjectClass::Fire_Out -- Informs object that attached animation has finished. *
  531. * *
  532. * This routine is called if there is an attached animation on this object and that *
  533. * animation has finished. Typically, this is necessary for when trees are on fire. *
  534. * *
  535. * INPUT: none *
  536. * *
  537. * OUTPUT: none *
  538. * *
  539. * WARNINGS: none *
  540. * *
  541. * HISTORY: *
  542. * 07/24/1995 JLB : Created. *
  543. *=============================================================================================*/
  544. void ObjectClass::Fire_Out(void)
  545. {
  546. }
  547. /***********************************************************************************************
  548. * ObjectClass::Value -- Fetches the target value of this object. *
  549. * *
  550. * This routine will return the target value of this object. The higher the number, the *
  551. * better the object will be as a target. This routine is called when searching for *
  552. * targets. Generic objects have no target potential, and this routine returns zero to *
  553. * reflect that. Other object types will override this routine to return the appropriate *
  554. * target value. *
  555. * *
  556. * INPUT: none *
  557. * *
  558. * OUTPUT: Returns with the value of this object as a target. Higher values mean better *
  559. * target. *
  560. * *
  561. * WARNINGS: none *
  562. * *
  563. * HISTORY: *
  564. * 07/24/1995 JLB : Created. *
  565. *=============================================================================================*/
  566. int ObjectClass::Value(void) const
  567. {
  568. return(0);
  569. }
  570. /***********************************************************************************************
  571. * ObjectClass::Get_Mission -- Fetches the current mission of this object. *
  572. * *
  573. * Generic objects don't have a mission, so this routine will just return MISSION_NONE. *
  574. * However, techno objects do have a mission and this routine is overloaded to handle *
  575. * those objects in order to return the correct mission value. *
  576. * *
  577. * INPUT: none *
  578. * *
  579. * OUTPUT: Returns with the current mission being followed by this object. *
  580. * *
  581. * WARNINGS: none *
  582. * *
  583. * HISTORY: *
  584. * 07/24/1995 JLB : Created. *
  585. *=============================================================================================*/
  586. MissionType ObjectClass::Get_Mission(void) const
  587. {
  588. return(MISSION_NONE);
  589. }
  590. /***********************************************************************************************
  591. * ObjectClass::Repair -- Handles object repair control. *
  592. * *
  593. * This routine will control object repair mode. At the object level, no repair is *
  594. * possible, so it is expected that any object that can repair will override this function *
  595. * as necessary. *
  596. * *
  597. * INPUT: control -- The repair control parameter. *
  598. * 0 = turn repair off *
  599. * 1 = turn repair on *
  600. * -1 = toggle repair state *
  601. * *
  602. * OUTPUT: none *
  603. * *
  604. * WARNINGS: none *
  605. * *
  606. * HISTORY: *
  607. * 07/24/1995 JLB : Created. *
  608. *=============================================================================================*/
  609. void ObjectClass::Repair(int )
  610. {
  611. }
  612. /***********************************************************************************************
  613. * ObjectClass::Sell_Back -- Sells the object -- if possible. *
  614. * *
  615. * This routine is called to sell back the object. Override this routine for the more *
  616. * sophisticated objects that can actually be sold back. Normal objects can't be sold and *
  617. * this routine does nothing as a consequence. *
  618. * *
  619. * INPUT: control -- How to control the sell state of this object. *
  620. * 0 = stop selling. *
  621. * 1 = start selling. *
  622. * -1 = toggle selling state. *
  623. * *
  624. * OUTPUT: none *
  625. * *
  626. * WARNINGS: none *
  627. * *
  628. * HISTORY: *
  629. * 07/19/1995 JLB : Created. *
  630. *=============================================================================================*/
  631. void ObjectClass::Sell_Back(int )
  632. {
  633. }
  634. /***********************************************************************************************
  635. * ObjectClass::Move -- Moves (by force) the object in the desired direction. *
  636. * *
  637. * This routine will instantly move the object one cell in the specified direction. It *
  638. * moves the object by force. This is typically ONLY used by the scenario editor *
  639. * process. *
  640. * *
  641. * INPUT: facing -- The direction to move the object. *
  642. * *
  643. * OUTPUT: none *
  644. * *
  645. * WARNINGS: Naturally, this can cause illegal placement situations -- use with caution. *
  646. * *
  647. * HISTORY: *
  648. * 06/19/1994 JLB : Created. *
  649. *=============================================================================================*/
  650. void ObjectClass::Move(FacingType facing)
  651. {
  652. COORDINATE coord;
  653. Mark(MARK_UP);
  654. coord = Adjacent_Cell(Coord, facing);
  655. if (Can_Enter_Cell(Coord_Cell(coord)) == MOVE_OK) {
  656. Coord = coord;
  657. }
  658. Mark(MARK_DOWN);
  659. }
  660. // Object selection list is switched with player context for GlyphX. ST - 4/17/2019 9:42AM
  661. extern void Logic_Switch_Player_Context(ObjectClass *object);
  662. /***********************************************************************************************
  663. * ObjectClass::Unselect -- This will un-select the object if it was selected. *
  664. * *
  665. * This routine brings a currently selected object into an unselected state. This is *
  666. * needed when another object becomes selected as well as if the object is destroyed. *
  667. * *
  668. * INPUT: none *
  669. * *
  670. * OUTPUT: none *
  671. * *
  672. * WARNINGS: none *
  673. * *
  674. * HISTORY: *
  675. * 06/19/1994 JLB : Created. *
  676. *=============================================================================================*/
  677. void ObjectClass::Unselect(void)
  678. {
  679. //if (IsSelected) {
  680. // Updated to function for multiplayer - 6/26/2019 JAS
  681. if (Is_Selected_By_Player()) {
  682. if (In_Which_Layer()==LAYER_GROUND){
  683. Mark(MARK_OVERLAP_UP);
  684. }
  685. //IsSelected = false;
  686. // Updated to function for multiplayer - 6/26/2019 JAS
  687. Set_Unselected_By_Player();
  688. if (In_Which_Layer()==LAYER_GROUND){
  689. Mark(MARK_OVERLAP_DOWN);
  690. }
  691. }
  692. }
  693. /***********************************************************************************************
  694. * ObjectClass::Unselect_All_Players -- This will un-select the object if it was selected *
  695. * from all players *
  696. * *
  697. * This routine brings a currently selected object into an unselected state for all players.*
  698. * This is needed when the object is destroyed. *
  699. * *
  700. * INPUT: none *
  701. * *
  702. * OUTPUT: none *
  703. * *
  704. * WARNINGS: none *
  705. * *
  706. * HISTORY: *
  707. * 06/25/2019 JAS : Created. *
  708. *=============================================================================================*/
  709. void ObjectClass::Unselect_All_Players(void)
  710. {
  711. CurrentObject.Delete_All(this);
  712. if (In_Which_Layer() == LAYER_GROUND) {
  713. Mark(MARK_OVERLAP_UP);
  714. }
  715. IsSelected = false;
  716. IsSelectedMask = 0;
  717. if (In_Which_Layer() == LAYER_GROUND) {
  718. Mark(MARK_OVERLAP_DOWN);
  719. }
  720. }
  721. /***********************************************************************************************
  722. * ObjectClass::Unselect_All_Players_Except_Owner -- This will un-select the object if it was *
  723. * selected for all players except for the object's owner *
  724. * *
  725. * This routine brings a currently selected object into an unselected state for all players.*
  726. * This is needed when the object cloaks. *
  727. * *
  728. * INPUT: none *
  729. * *
  730. * OUTPUT: none *
  731. * *
  732. * WARNINGS: none *
  733. * *
  734. * HISTORY: *
  735. * 06/28/2019 JAS : Created. *
  736. *=============================================================================================*/
  737. void ObjectClass::Unselect_All_Players_Except_Owner(void)
  738. {
  739. CurrentObject.Delete_All_Except(this, Owner());
  740. if (In_Which_Layer() == LAYER_GROUND) {
  741. Mark(MARK_OVERLAP_UP);
  742. }
  743. int owner_mask = 1 << Owner();
  744. if (IsSelectedMask & owner_mask)
  745. {
  746. IsSelected = true;
  747. IsSelectedMask = owner_mask;
  748. }
  749. else
  750. {
  751. IsSelected = false;
  752. IsSelectedMask = 0;
  753. }
  754. if (In_Which_Layer() == LAYER_GROUND) {
  755. Mark(MARK_OVERLAP_DOWN);
  756. }
  757. }
  758. /***********************************************************************************************
  759. * ObjectClass::Select -- Try to make this object the "selected" object. *
  760. * *
  761. * This routine is used to make this object into the one that is "selected". A selected *
  762. * object usually displays a floating bar graph and is available to be given orders from *
  763. * the player's I/O. *
  764. * *
  765. * INPUT: allow_mixed -- Allow a mix of player and non-player controlled units? *
  766. * *
  767. * OUTPUT: none *
  768. * *
  769. * WARNINGS: none *
  770. * *
  771. * HISTORY: *
  772. * 06/19/1994 JLB : Created. *
  773. * 06/12/1995 JLB : Cannot select a loaner object. *
  774. * 07/23/1995 JLB : Adds to head or tail depending on leader type flag. *
  775. *=============================================================================================*/
  776. bool ObjectClass::Select(bool allow_mixed)
  777. {
  778. // if (!Debug_Map && (IsSelected || !Class_Of().IsSelectable)) return(false);
  779. // Updated to function for multiplayer - 6/26/2019 JAS
  780. if (!Debug_Map && (Is_Selected_By_Player() || !Class_Of().IsSelectable)) return(false);
  781. if (Can_Player_Move() && Is_Techno() && ((TechnoClass *)this)->IsALoaner) return(false);
  782. /*
  783. ** Don't allow selection of object when in building placement mode.
  784. */
  785. if (Map.PendingObject) return(false);
  786. if (!allow_mixed) {
  787. /*
  788. ** If selecting an object of a different house than the player's, make sure that
  789. ** the entire selection list is cleared.
  790. */
  791. for (int i = 0; i < CurrentObject.Count(); i++) {
  792. if (Owner() != CurrentObject[i]->Owner()) {
  793. Unselect_All();
  794. break;
  795. }
  796. }
  797. }
  798. if (In_Which_Layer()==LAYER_GROUND){
  799. Mark(MARK_OVERLAP_UP);
  800. }
  801. //IsSelected = true;
  802. // Updated to function for multiplayer - 6/26/2019 JAS
  803. Set_Selected_By_Player();
  804. if (In_Which_Layer()==LAYER_GROUND){
  805. Mark(MARK_OVERLAP_DOWN);
  806. }
  807. return(true);
  808. }
  809. /***********************************************************************************************
  810. * ObjectClass::Render -- Displays the object onto the map. *
  811. * *
  812. * This routine will determine the location of the object and if it is roughly on the *
  813. * visible screen, it will display it. Not displaying objects that are not on the screen *
  814. * will save valuable time. *
  815. * *
  816. * INPUT: bool; Should the render be forced regardless of whether the object is flagged to *
  817. * be redrawn? *
  818. * *
  819. * OUTPUT: bool; Was the draw code called for this object? *
  820. * *
  821. * WARNINGS: none *
  822. * *
  823. * HISTORY: *
  824. * 06/19/1994 JLB : Created. *
  825. *=============================================================================================*/
  826. bool ObjectClass::Render(bool forced)
  827. {
  828. int x,y;
  829. COORDINATE coord = Render_Coord();
  830. CELL cell = Coord_Cell(coord);
  831. if (Debug_Map || Debug_Unshroud || ((forced || IsToDisplay) && IsDown && !IsInLimbo)) {
  832. IsToDisplay = false;
  833. /*
  834. ** Draw the path as lines on the map if so directed and the object is one that
  835. ** contains a path.
  836. */
  837. //if (Special.IsShowPath && IsSelected) {
  838. // Updated to function for multiplayer - 6/26/2019 JAS
  839. if (Special.IsShowPath && Is_Selected_By_Player()) {
  840. switch (What_Am_I()) {
  841. case RTTI_INFANTRY:
  842. case RTTI_UNIT:
  843. FootClass * foot = (FootClass *)this;
  844. CELL cell;
  845. int oldx, oldy;
  846. if (foot->Head_To_Coord() && foot->Path[0] != FACING_NONE) {
  847. cell = Adjacent_Cell(Coord_Cell(foot->Head_To_Coord()), (FacingType)((foot->Path[0] + FACING_S) & FACING_NW));
  848. Map.Coord_To_Pixel(Cell_Coord(cell), oldx, oldy);
  849. for (int index = 0; index < MAX_PATH; index++) {
  850. if (foot->Path[index] == FACING_NONE) break;
  851. cell = Adjacent_Cell(cell, foot->Path[index]);
  852. if (Map.Coord_To_Pixel(Cell_Coord(cell), x, y)) {
  853. LogicPage->Draw_Line(oldx, 8+oldy, x, 8+y, BLACK);
  854. }
  855. oldx = x;
  856. oldy = y;
  857. }
  858. }
  859. break;
  860. }
  861. }
  862. if (Map.Coord_To_Pixel(coord, x, y)) {
  863. /*
  864. ** Draw the object itself
  865. */
  866. Draw_It(x, y, WINDOW_TACTICAL);
  867. #ifdef SCENARIO_EDITOR
  868. /*
  869. ** Draw the trigger attached to the object. Draw_It is window-
  870. ** relative, so add the window's x-coord to 'x'.
  871. */
  872. if (Debug_Map && Trigger) {
  873. Fancy_Text_Print(Trigger->Get_Name(), x + (WinX<<3), y, PINK, TBLACK, TPF_CENTER | TPF_NOSHADOW | TPF_6POINT);
  874. }
  875. #endif
  876. return(true);
  877. }
  878. }
  879. return(false);
  880. }
  881. #ifdef CHEAT_KEYS
  882. /***********************************************************************************************
  883. * ObjectClass::Debug_Dump -- Displays status of the object class to the mono monitor. *
  884. * *
  885. * This routine is used to display the current status of the object class to the mono *
  886. * monitor. *
  887. * *
  888. * INPUT: none *
  889. * *
  890. * OUTPUT: none *
  891. * *
  892. * WARNINGS: none *
  893. * *
  894. * HISTORY: *
  895. * 06/02/1994 JLB : Created. *
  896. *=============================================================================================*/
  897. void ObjectClass::Debug_Dump(MonoClass *mono) const
  898. {
  899. mono->Text_Print("X", 16 + (IsToDisplay?2:0), 18);
  900. mono->Text_Print("X", 16 + (IsActive?2:0), 3);
  901. mono->Text_Print("X", 16 + (IsInLimbo?2:0), 4);
  902. //mono->Text_Print("X", 16 + (IsSelected?2:0), 7);
  903. // Updated to function for multiplayer - 6/26/2019 JAS
  904. mono->Text_Print("X", 16 + (Is_Selected_By_Player() ?2:0), 7);
  905. mono->Set_Cursor(56, 1);
  906. mono->Printf("%08lX", Coord);
  907. mono->Set_Cursor(14, 1);mono->Printf("[%04X]", As_Target());
  908. mono->Set_Cursor(20, 3);mono->Printf("%2d[%d]", Strength, Class_Of().MaxStrength);
  909. }
  910. #endif
  911. /***********************************************************************************************
  912. * ObjectTypeClass::Occupy_List -- Returns with simple occupation list for object. *
  913. * *
  914. * This routine returns a pointer to a simple occupation list for this object. Since at *
  915. * this tier of the object class chain, the exact shape of the object is indeterminate, *
  916. * this function merely returns a single cell occupation list. This actually works for *
  917. * most vehicles. *
  918. * *
  919. * INPUT: none *
  920. * *
  921. * OUTPUT: Returns a pointer to a simple occupation list. *
  922. * *
  923. * WARNINGS: none *
  924. * *
  925. * HISTORY: *
  926. * 05/28/1994 JLB : Created. *
  927. *=============================================================================================*/
  928. short const * ObjectTypeClass::Occupy_List(bool) const
  929. {
  930. static short const _list[] = {0, REFRESH_EOL};
  931. return(_list);
  932. }
  933. /***********************************************************************************************
  934. * ObjectTypeClass::Overlap_List -- Returns a pointer to a simple overlap list. *
  935. * *
  936. * This function returns a pointer to an overlap list for the object. An overlap list is *
  937. * the offsets from the object's cell to get the cells the imagery overlaps, but is object *
  938. * is not considered to occupy. Since at this stage, the overlap information is not *
  939. * available, this function merely returns a pointer to an empty list. *
  940. * *
  941. * INPUT: none *
  942. * *
  943. * OUTPUT: Returns a pointer to the generic overlap list. *
  944. * *
  945. * WARNINGS: none *
  946. * *
  947. * HISTORY: *
  948. * 05/28/1994 JLB : Created. *
  949. *=============================================================================================*/
  950. short const * ObjectTypeClass::Overlap_List(void) const
  951. {
  952. static short const _list[] = {REFRESH_EOL};
  953. return(_list);
  954. }
  955. /***********************************************************************************************
  956. * ObjectTypeClass::One_Time -- Handles one time processing for object types. *
  957. * *
  958. * This routine is used to handle the once per game processing required for object types. *
  959. * This consists of loading any data and initializing any data tables the game requires. *
  960. * *
  961. * INPUT: none *
  962. * *
  963. * OUTPUT: none *
  964. * *
  965. * WARNINGS: This routine goes to disk. *
  966. * *
  967. * HISTORY: *
  968. * 11/01/1994 JLB : Created. *
  969. *=============================================================================================*/
  970. void ObjectTypeClass::One_Time(void)
  971. {
  972. SelectShapes = MixFileClass::Retrieve("SELECT.SHP");
  973. #if (FRENCH)
  974. PipShapes = Hires_Retrieve("PIPS_F.SHP");
  975. #else
  976. #if (GERMAN)
  977. PipShapes = Hires_Retrieve("PIPS_G.SHP");
  978. #else
  979. PipShapes = Hires_Retrieve("PIPS.SHP");
  980. #endif
  981. #endif
  982. }
  983. /***********************************************************************************************
  984. * ObjectClass::Mark_For_Redraw -- Marks object and system for redraw. *
  985. * *
  986. * This routine will mark the object and inform the display system *
  987. * that appropriate rendering is needed. Whenever it is determined *
  988. * that an object needs to be redrawn, call this routine. *
  989. * *
  990. * INPUT: none *
  991. * *
  992. * OUTPUT: none *
  993. * *
  994. * WARNINGS: This is a subordinate function to the function Mark(). If an object needs to *
  995. * be redrawn it is probably better to call the function Mark(MARK_CHANGE) rather *
  996. * than this function. This function does not inform the map system that *
  997. * overlapping objects are to be redrawn and thus unless you are really sure that *
  998. * this routine should be called, don't. *
  999. * *
  1000. * HISTORY: *
  1001. * 05/08/1994 JLB : Created. *
  1002. * 12/23/1994 JLB : Flags map and flags unit only. *
  1003. *=============================================================================================*/
  1004. void ObjectClass::Mark_For_Redraw(void)
  1005. {
  1006. if (!IsToDisplay) {
  1007. IsToDisplay = true;
  1008. /*
  1009. ** This tells the map rendering logic to "go through the motions" and call the
  1010. ** rendering function. In the rendering function, it will sort out what gets
  1011. ** rendered and what doesn't.
  1012. */
  1013. Map.Flag_To_Redraw(false);
  1014. }
  1015. }
  1016. /***********************************************************************************************
  1017. * ObjectClass::Limbo -- Brings the object into a state of limbo. *
  1018. * *
  1019. * An object brought into a state of limbo by this routine can be safely deleted. This *
  1020. * routine will remove the object from all game lists and tracking systems. It is called *
  1021. * prior to deleting the object or placing the object "on ice". *
  1022. * *
  1023. * INPUT: none *
  1024. * *
  1025. * OUTPUT: bool; Was the object successfully placed in limbo? *
  1026. * *
  1027. * WARNINGS: none *
  1028. * *
  1029. * HISTORY: *
  1030. * 09/24/1994 JLB : Created. *
  1031. *=============================================================================================*/
  1032. bool ObjectClass::Limbo(void)
  1033. {
  1034. if (GameActive && !IsInLimbo) {
  1035. //Unselect();
  1036. // Updated to function for multiplayer - 6/26/2019 JAS
  1037. Unselect_All_Players();
  1038. Detach_All();
  1039. Mark(MARK_UP);
  1040. /*
  1041. ** Remove the object from the appropriate display list.
  1042. */
  1043. Map.Remove(this, In_Which_Layer());
  1044. /*
  1045. ** Remove the object from the logic processing list.
  1046. */
  1047. if (Class_Of().IsSentient) {
  1048. Logic.Delete(this);
  1049. }
  1050. Hidden();
  1051. IsInLimbo = true;
  1052. IsToDisplay = false;
  1053. return(true);
  1054. }
  1055. return(false);
  1056. }
  1057. /***********************************************************************************************
  1058. * ObjectClass::Unlimbo -- Brings the object into the game system. *
  1059. * *
  1060. * This routine will place the object into the game tracking and display systems. It is *
  1061. * called as a consequence of creating the object. Every game object must be unlimboed at *
  1062. * some point. *
  1063. * *
  1064. * INPUT: coord -- The coordinate to place the object into the game system. *
  1065. * *
  1066. * dir (optional) -- initial facing direction for this object *
  1067. * *
  1068. * OUTPUT: bool; Was the game object successfully unlimboed? *
  1069. * *
  1070. * WARNINGS: none *
  1071. * *
  1072. * HISTORY: *
  1073. * 09/24/1994 JLB : Created. *
  1074. * 12/23/1994 JLB : Sets object strength. *
  1075. *=============================================================================================*/
  1076. bool ObjectClass::Unlimbo(COORDINATE coord, DirType )
  1077. {
  1078. if (GameActive && IsInLimbo && !IsDown) {
  1079. if (ScenarioInit || Can_Enter_Cell(Coord_Cell(coord), FACING_NONE) == MOVE_OK) {
  1080. IsInLimbo = false;
  1081. IsToDisplay = false;
  1082. Coord = Class_Of().Coord_Fixup(coord);
  1083. if (Mark(MARK_DOWN)) {
  1084. if (IsActive) {
  1085. /*
  1086. ** Add the object to the appropriate map layer. This layer is used
  1087. ** for rendering purposes.
  1088. */
  1089. if (In_Which_Layer() != LAYER_NONE) {
  1090. Map.Submit(this, In_Which_Layer());
  1091. }
  1092. if (Class_Of().IsSentient) {
  1093. Logic.Submit(this);
  1094. }
  1095. }
  1096. return(true);
  1097. }
  1098. }
  1099. }
  1100. return(false);
  1101. }
  1102. /***********************************************************************************************
  1103. * ObjectClass::Detach_All -- Removes the object from all tracking systems. *
  1104. * *
  1105. * This routine will take the object and see that it is removed from all miscellaneous *
  1106. * tracking systems in the game. This operation is vital when deleting an object. It is *
  1107. * necessary so that when the object is removed from the game, existing game objects won't *
  1108. * be referencing a now invalid game object. This typically affects the targeting *
  1109. * and navigation computers of other game objects. *
  1110. * *
  1111. * INPUT: none *
  1112. * *
  1113. * OUTPUT: none *
  1114. * *
  1115. * WARNINGS: none *
  1116. * *
  1117. * HISTORY: *
  1118. * 09/24/1994 JLB : Created. *
  1119. *=============================================================================================*/
  1120. void ObjectClass::Detach_All(bool all)
  1121. {
  1122. /*
  1123. ** Unselect this object if it was selected.
  1124. */
  1125. //if (all || Owner() != PlayerPtr->Class->House) {
  1126. // Unselect();
  1127. //}
  1128. //Added some error handling incase there was an issue removing the object - JAS 6/28/2019
  1129. if (all) {
  1130. //Unselect();
  1131. // Updated to function for multiplayer - 6/28/2019 JAS
  1132. Unselect_All_Players();
  1133. }
  1134. else
  1135. {
  1136. Unselect_All_Players_Except_Owner();
  1137. }
  1138. //End of change - JAS 6/28/2019
  1139. Map.Detach(this);
  1140. /*
  1141. ** Remove from targeting computers.
  1142. */
  1143. Detach_This_From_All(As_Target(), all);
  1144. }
  1145. /***********************************************************************************************
  1146. * ObjectClass::Detach_This_From_All -- Detatches this object from all others. *
  1147. * *
  1148. * This routine sweeps through all game objects and makes sure that it is no longer *
  1149. * referenced by them. Typically, this is called in preparation for the object's death *
  1150. * or limbo state. *
  1151. * *
  1152. * INPUT: target -- This object expressed as a target number. *
  1153. * *
  1154. * OUTPUT: none *
  1155. * *
  1156. * WARNINGS: none *
  1157. * *
  1158. * HISTORY: *
  1159. * 05/08/1995 JLB : Created. *
  1160. *=============================================================================================*/
  1161. void ObjectClass::Detach_This_From_All(TARGET target, bool all)
  1162. {
  1163. int index;
  1164. if (Target_Legal(target)) {
  1165. for (index = 0; index < Houses.Count(); index++) {
  1166. Houses.Ptr(index)->Detach(target, all);
  1167. }
  1168. for (index = 0; index < Teams.Count(); index++) {
  1169. Teams.Ptr(index)->Detach(target, all);
  1170. }
  1171. for (index = 0; index < Units.Count(); index++) {
  1172. Units.Ptr(index)->Detach(target, all);
  1173. }
  1174. for (index = 0; index < Infantry.Count(); index++) {
  1175. Infantry.Ptr(index)->Detach(target, all);
  1176. }
  1177. for (index = 0; index < Aircraft.Count(); index++) {
  1178. Aircraft.Ptr(index)->Detach(target, all);
  1179. }
  1180. for (index = 0; index < Buildings.Count(); index++) {
  1181. Buildings.Ptr(index)->Detach(target, all);
  1182. }
  1183. for (index = 0; index < Bullets.Count(); index++) {
  1184. Bullets.Ptr(index)->Detach(target, all);
  1185. }
  1186. for (index = 0; index < Anims.Count(); index++) {
  1187. Anims.Ptr(index)->Detach(target, all);
  1188. }
  1189. }
  1190. }
  1191. /***********************************************************************************************
  1192. * ObjectClass::Receive_Message -- Processes an incoming radio message. *
  1193. * *
  1194. * Any radio message received that applies to objects in general are handled by this *
  1195. * routine. Typically, this is the "redraw" message, which occurs when another object is *
  1196. * loading or unloading and thus overlapping. *
  1197. * *
  1198. * INPUT: message -- The message received. *
  1199. * *
  1200. * OUTPUT: Returns with the appropriate radio response. If the message was recognized, then *
  1201. * RADIO_ROGER is returned, otherwise, just RADIO_STATIC is returned. *
  1202. * *
  1203. * WARNINGS: none *
  1204. * *
  1205. * HISTORY: *
  1206. * 09/24/1994 JLB : Created. *
  1207. *=============================================================================================*/
  1208. RadioMessageType ObjectClass::Receive_Message(RadioClass *, RadioMessageType message, long & )
  1209. {
  1210. switch (message) {
  1211. /*
  1212. ** This message serves as a rendering convenience. It lets the system
  1213. ** know that there might be a visual conflict and the unit in radio
  1214. ** contact should be redrawn. This typically occurs when a vehicle
  1215. ** is being unloaded from a hover lander.
  1216. */
  1217. case RADIO_REDRAW:
  1218. Mark(MARK_CHANGE);
  1219. return(RADIO_ROGER);
  1220. default:
  1221. break;
  1222. }
  1223. return(RADIO_STATIC);
  1224. }
  1225. /***********************************************************************************************
  1226. * ObjectClass::Take_Damage -- Applies damage to the object. *
  1227. * *
  1228. * This routine applies damage to the object according to the damage parameters. It handles *
  1229. * reducing the strength of the object and also returns the result of that damage. The *
  1230. * result value can be examined to determine if the object was destroyed, greatly damaged, *
  1231. * or other results. *
  1232. * *
  1233. * INPUT: damage -- Reference to the damage number to apply. This number will be adjusted *
  1234. * according to defensive armor and distance. Examine this value after *
  1235. * the call to determine the actual amount of damage applied. *
  1236. * *
  1237. * distance -- The distance (in leptons) from the center of the damage causing *
  1238. * explosion to the object itself. *
  1239. * *
  1240. * warhead -- The warhead type that is causing the damage. *
  1241. * *
  1242. * OUTPUT: Returns the ResultType that indicates what the affect of the damage was. *
  1243. * *
  1244. * WARNINGS: none *
  1245. * *
  1246. * HISTORY: *
  1247. * 11/29/1994 JLB : Created. *
  1248. * 12/27/1994 JLB : Trigger event processing for attacked or destroyed. *
  1249. * 01/01/1995 JLB : Reduces damage greatly depending on range. *
  1250. *=============================================================================================*/
  1251. ResultType ObjectClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source)
  1252. {
  1253. ResultType result = RESULT_NONE;
  1254. int oldstrength = Strength;
  1255. if (oldstrength && damage && !Class_Of().IsImmune) {
  1256. int maxstrength = Class_Of().MaxStrength;
  1257. /*
  1258. ** Modify damage based on the warhead type and the armor of the object. This results
  1259. ** in a reduced damage value, but never below 1 damage point.
  1260. */
  1261. damage = Modify_Damage(damage, warhead, Class_Of().Armor, distance);
  1262. if (!damage) return(RESULT_NONE);
  1263. /*
  1264. ** At this point, we KNOW that at least light damage has occurred.
  1265. */
  1266. result = RESULT_LIGHT;
  1267. /*
  1268. ** A non-fatal blow has occurred. Check to see if the object transitioned to below
  1269. ** half strength or if it is now down to one hit point.
  1270. */
  1271. if (oldstrength > damage) {
  1272. if (oldstrength >= (maxstrength >> 1) && (oldstrength-damage) < (maxstrength >> 1)) {
  1273. result = RESULT_HALF;
  1274. }
  1275. } else {
  1276. /*
  1277. ** When an object is damaged to destruction, it will instead stop at one
  1278. ** damage point. This will prolong the damage state as well as
  1279. ** give greater satisfaction when it is finally destroyed.
  1280. */
  1281. damage = oldstrength;
  1282. }
  1283. /*
  1284. ** Apply the damage to the object.
  1285. */
  1286. Strength = oldstrength - damage;
  1287. /*
  1288. ** Check to see if the object is majorly damaged or destroyed.
  1289. */
  1290. switch (Strength) {
  1291. case 0:
  1292. Record_The_Kill(source);
  1293. result = RESULT_DESTROYED;
  1294. Detach_All();
  1295. break;
  1296. case 1:
  1297. result = RESULT_MAJOR;
  1298. break;
  1299. default:
  1300. break;
  1301. }
  1302. /*
  1303. ** Handle any trigger event associated with this object.
  1304. */
  1305. if (source && Trigger && result != RESULT_DESTROYED) {
  1306. Trigger->Spring(EVENT_ATTACKED, this);
  1307. }
  1308. /*
  1309. ** If any damage was assessed and this object is selected, then flag
  1310. ** the object to be redrawn so that the health bar will be updated.
  1311. */
  1312. //if (result != RESULT_NONE && IsSelected) {
  1313. // Updated to function for multiplayer - 6/26/2019 JAS
  1314. if (result != RESULT_NONE && Is_Selected_By_Player()) {
  1315. Mark(MARK_CHANGE);
  1316. }
  1317. }
  1318. /*
  1319. ** Return with the result of the damage taken.
  1320. */
  1321. return(result);
  1322. }
  1323. /***********************************************************************************************
  1324. * ObjectClass::Mark -- Handles basic marking logic. *
  1325. * *
  1326. * This routine handles the base logic for marking an object up or down on the map. It *
  1327. * manages the IsDown flag as well as flagging the object to be redrawn if necessary. *
  1328. * Whenever an object is to be marked, it should call this base class function first. If *
  1329. * this function returns true, then the higher level function should proceed with its own *
  1330. * logic. *
  1331. * *
  1332. * INPUT: mark -- The marking method to use for this object. It can be either MARK_DOWN, *
  1333. * MARK_UP, or MARK_CHANGE. *
  1334. * *
  1335. * OUTPUT: bool; Was the object marked successfully? *
  1336. * *
  1337. * WARNINGS: none *
  1338. * *
  1339. * HISTORY: *
  1340. * 01/23/1995 JLB : Created. *
  1341. *=============================================================================================*/
  1342. bool ObjectClass::Mark(MarkType mark)
  1343. {
  1344. TechnoClass *tech;
  1345. CELL cell;
  1346. int threat;
  1347. HousesType house;
  1348. if (!IsInLimbo && IsActive) {
  1349. /*
  1350. ** A mark for change is always successful UNLESS the object
  1351. ** is not placed down or has already been flagged as changed
  1352. ** this game frame.
  1353. */
  1354. if (mark == MARK_CHANGE) {
  1355. if (IsToDisplay) return(false);
  1356. if (IsDown == true) {
  1357. Mark_For_Redraw();
  1358. return(true);
  1359. }
  1360. return(false);
  1361. }
  1362. /*
  1363. ** Handle adding or removing the object in the cells' overlap lists
  1364. */
  1365. if (mark == MARK_OVERLAP_UP) {
  1366. if (IsDown == true) {
  1367. Map.Overlap_Up(Coord_Cell(Coord),this);
  1368. Mark_For_Redraw();
  1369. return(true);
  1370. }
  1371. }
  1372. if (mark == MARK_OVERLAP_DOWN) {
  1373. if (IsDown == true) {
  1374. Map.Overlap_Down(Coord_Cell(Coord),this);
  1375. Mark_For_Redraw();
  1376. return(true);
  1377. }
  1378. }
  1379. /*
  1380. ** It is important to know whether the object is a techno class
  1381. ** or not to see if we have to adjust the regional threat ratings
  1382. */
  1383. if (Is_Techno()) {
  1384. tech = (TechnoClass *)this;
  1385. threat = tech->Risk();
  1386. house = tech->Owner();
  1387. cell = Coord_Cell(Coord);
  1388. } else
  1389. tech = NULL;
  1390. /*
  1391. ** Marking down is only successful if the object isn't already
  1392. ** placed down.
  1393. */
  1394. if (mark == MARK_DOWN && !IsDown) {
  1395. if (tech && GameToPlay == GAME_NORMAL) {
  1396. Map[cell].Adjust_Threat(house, threat);
  1397. }
  1398. IsDown = true;
  1399. Mark_For_Redraw();
  1400. return(true);
  1401. }
  1402. /*
  1403. ** Lifting up is only successful if the object isn't already
  1404. ** lifted up from the map.
  1405. */
  1406. if (mark == MARK_UP && IsDown) {
  1407. if (tech && GameToPlay == GAME_NORMAL) {
  1408. Map[cell].Adjust_Threat(house, -threat);
  1409. }
  1410. Map.Overlap_Up(Coord_Cell(Coord), this);
  1411. IsDown = false;
  1412. return(true);
  1413. }
  1414. }
  1415. return(false);
  1416. }
  1417. /***********************************************************************************************
  1418. * ObjectClass::Init -- Initializes the basic object system. *
  1419. * *
  1420. * This routine should be called when the basic object system needs to be initialized. This *
  1421. * occurs when the scenario is about to be loaded. *
  1422. * *
  1423. * INPUT: none *
  1424. * *
  1425. * OUTPUT: none *
  1426. * *
  1427. * WARNINGS: none *
  1428. * *
  1429. * HISTORY: *
  1430. * 01/23/1995 JLB : Created. *
  1431. *=============================================================================================*/
  1432. void ObjectClass::Init(void)
  1433. {
  1434. CurrentObject.Clear_All();
  1435. }
  1436. /***********************************************************************************************
  1437. * ObjectClass::Revealed -- Reveals this object to the house specified. *
  1438. * *
  1439. * This routine is called when this object gets revealed to the house specified. *
  1440. * *
  1441. * INPUT: house -- Pointer to the house that this object is being revealed to. *
  1442. * *
  1443. * OUTPUT: Was this object revealed for the first time to this house? Generic objects always *
  1444. * return true unless an invalid house pointer was specified. *
  1445. * *
  1446. * WARNINGS: none *
  1447. * *
  1448. * HISTORY: *
  1449. * 07/19/1995 JLB : Created. *
  1450. *=============================================================================================*/
  1451. bool ObjectClass::Revealed(HouseClass * house)
  1452. {
  1453. return(house != NULL);
  1454. }
  1455. /***********************************************************************************************
  1456. * ObjectClass::Set_Selected_By_Player -- Set this object as selected by the given player or *
  1457. * the default player. *
  1458. * *
  1459. * INPUT: Player pointer *
  1460. * *
  1461. * OUTPUT: *
  1462. * *
  1463. * WARNINGS: none *
  1464. * *
  1465. * HISTORY: *
  1466. * 6/25/2019 - JAS *
  1467. *=============================================================================================*/
  1468. void ObjectClass::Set_Selected_By_Player(HouseClass *player)
  1469. {
  1470. if (!player || !player->Class) {
  1471. player = PlayerPtr;
  1472. }
  1473. HousesType house = player->Class->House;
  1474. if (((TechnoTypeClass const &)Class_Of()).IsLeader) {
  1475. CurrentObject.Add_Head(house, this);
  1476. }
  1477. else {
  1478. CurrentObject.Add(house, this);
  1479. }
  1480. int shift = (int)house;
  1481. IsSelectedMask |= (1 << shift);
  1482. if (GameToPlay == GAME_NORMAL && player == PlayerPtr) {
  1483. IsSelected = true;
  1484. }
  1485. }
  1486. /***********************************************************************************************
  1487. * ObjectClass::Set_Unselected_By_Player -- Set this object as unselected by the given player *
  1488. * orthe default player. *
  1489. * *
  1490. * INPUT: Player pointer *
  1491. * *
  1492. * OUTPUT: *
  1493. * *
  1494. * WARNINGS: none *
  1495. * *
  1496. * HISTORY: *
  1497. * 6/25/2019 - JAS *
  1498. *=============================================================================================*/
  1499. void ObjectClass::Set_Unselected_By_Player(HouseClass *player)
  1500. {
  1501. if (!player || !player->Class) {
  1502. player = PlayerPtr;
  1503. }
  1504. HousesType house = player->Class->House;
  1505. CurrentObject.Delete(house, this);
  1506. int shift = (int)house;
  1507. IsSelectedMask &= ~(1 << shift);
  1508. if (GameToPlay == GAME_NORMAL && player == PlayerPtr) {
  1509. IsSelected = false;
  1510. }
  1511. }
  1512. /***********************************************************************************************
  1513. * ObjectClass::Is_Selected_By_Player -- Has this object been selected by the given player *
  1514. * *
  1515. * INPUT: Player pointer *
  1516. * *
  1517. * OUTPUT: True if selected by that player *
  1518. * *
  1519. * WARNINGS: none *
  1520. * *
  1521. * HISTORY: *
  1522. * 6/25/2019 - JAS *
  1523. *=============================================================================================*/
  1524. bool ObjectClass::Is_Selected_By_Player(HouseClass *player) const
  1525. {
  1526. if (player && player->Class) {
  1527. int shift = (int)player->Class->House;
  1528. return (IsSelectedMask & (1 << shift)) ? true : false;
  1529. }
  1530. else {
  1531. int shift = (int)PlayerPtr->Class->House;
  1532. return (IsSelectedMask & (1 << shift)) ? true : false;
  1533. }
  1534. return false;
  1535. }
  1536. // These can't be made inline (for various reasons).
  1537. short const * ObjectClass::Occupy_List(bool placement) const {return(Class_Of().Occupy_List(placement));};
  1538. short const * ObjectClass::Overlap_List(void) const {return(Class_Of().Overlap_List());};
  1539. BuildingClass * ObjectClass::Who_Can_Build_Me(bool intheory, bool legal) const {return(Class_Of().Who_Can_Build_Me(intheory, legal, Owner()));};
  1540. unsigned ObjectClass::Health_Ratio(void) const {return(Cardinal_To_Fixed(Class_Of().MaxStrength, Strength));};
  1541. int ObjectClass::Full_Name(void) const {return Class_Of().Full_Name();};