TERRAIN.CPP 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: /CounterStrike/TERRAIN.CPP 1 3/03/97 10:25a Joe_bostic $ */
  15. /***********************************************************************************************
  16. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  17. ***********************************************************************************************
  18. * *
  19. * Project Name : Command & Conquer *
  20. * *
  21. * File Name : TERRAIN.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : April 29, 1994 *
  26. * *
  27. * Last Update : October 4, 1996 [JLB] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * TerrainClass::AI -- Process the terrain object AI. *
  32. * TerrainClass::Can_Enter_Cell -- Determines if the terrain object can exist in the cell. *
  33. * TerrainClass::Catch_Fire -- Catches the terrain object on fire. *
  34. * TerrainClass::Center_Coord -- Fetches the center point coordinate for terrain object. *
  35. * TerrainClass::Debug_Dump -- Displays the status of the terrain object. *
  36. * TerrainClass::Draw_It -- Renders the terrain object at the location specified. *
  37. * TerrainClass::Fire_Out -- Handles when fire has gone out. *
  38. * TerrainClass::Heath_Ratio -- Determines the health ratio for the terrain object. *
  39. * TerrainClass::Init -- Initialize the terrain object tracking system. *
  40. * TerrainClass::Limbo -- Handles terrain specific limbo action. *
  41. * TerrainClass::Mark -- Marks the terrain object on the map. *
  42. * TerrainClass::Radar_Icon -- Fetches pointer to radar icon to use. *
  43. * TerrainClass::Read_INI -- Reads terrain objects from INI file. *
  44. * TerrainClass::Start_To_Crumble -- Initiates crumbling of terrain (tree) object. *
  45. * TerrainClass::Take_Damage -- Damages the terrain object as specified. *
  46. * TerrainClass::Target_Coord -- Returns with the target coordinate. *
  47. * TerrainClass::TerrainClass -- This is the constructor for a terrain object. *
  48. * TerrainClass::Unlimbo -- Unlimbo terrain object onto the map. *
  49. * TerrainClass::Write_INI -- Write all terrain objects to the INI database specified. *
  50. * TerrainClass::delete -- Deletes a terrain object. *
  51. * TerrainClass::new -- Creates a new terrain object. *
  52. * TerrainClass::~TerrainClass -- Default destructor for terrain class objects. *
  53. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  54. #include "function.h"
  55. #include "terrain.h"
  56. /***********************************************************************************************
  57. * TerrainClass::~TerrainClass -- Default destructor for terrain class objects. *
  58. * *
  59. * This is the default destructor for terrain objects. It will remove the object from the *
  60. * map and tracking systems, but only if the game is running. Otherwise, it does nothing. *
  61. * *
  62. * INPUT: none *
  63. * *
  64. * OUTPUT: none *
  65. * *
  66. * WARNINGS: none *
  67. * *
  68. * HISTORY: *
  69. * 01/23/1995 JLB : Created. *
  70. *=============================================================================================*/
  71. TerrainClass::~TerrainClass(void)
  72. {
  73. if (GameActive && Class) {
  74. TerrainClass::Limbo();
  75. }
  76. }
  77. /***********************************************************************************************
  78. * TerrainClass::Take_Damage -- Damages the terrain object as specified. *
  79. * *
  80. * This routine is called when damage is to be inflicted upon the terrain object. It is *
  81. * through this routine that terrain objects are attacked and thereby destroyed. Not all *
  82. * terrain objects can be damaged by this routine however. *
  83. * *
  84. * INPUT: damage -- The damage points to inflict (raw). *
  85. * *
  86. * warhead -- The warhead type the indicates the kind of damage. This is used to *
  87. * determine if the terrain object is damaged and if so, by how much. *
  88. * *
  89. * OUTPUT: bool; Was the terrain object destroyed by this damage? *
  90. * *
  91. * WARNINGS: none *
  92. * *
  93. * HISTORY: *
  94. * 09/24/1994 JLB : Created. *
  95. * 11/22/1994 JLB : Shares base damage handler for techno objects. *
  96. * 12/11/1994 JLB : Shortens attached burning animations. *
  97. *=============================================================================================*/
  98. ResultType TerrainClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source, bool forced)
  99. {
  100. assert(Terrains.ID(this) == ID);
  101. assert(IsActive);
  102. ResultType res = RESULT_NONE;
  103. /*
  104. ** Small arms can never destroy a terrain element.
  105. */
  106. if ((!IsOnFire || warhead == WARHEAD_FIRE) && warhead != WARHEAD_SA && !Class->IsImmune) {
  107. res = ObjectClass::Take_Damage(damage, distance, warhead, source, forced);
  108. if (damage && warhead == WARHEAD_FIRE) {
  109. Catch_Fire();
  110. }
  111. /*
  112. ** If the terrain object is destroyed by this damage, then only remove it if it
  113. ** currently isn't on fire and isn't in the process of crumbling.
  114. */
  115. if (res == RESULT_DESTROYED) {
  116. /*
  117. ** Remove this terrain object from the targeting computers of all other
  118. ** game objects. No use beating a dead horse.
  119. */
  120. Detach_All();
  121. if (IsOnFire) {
  122. /*
  123. ** Attached flame animation should be shortened as much as possible so that
  124. ** crumbling can begin soon.
  125. */
  126. Shorten_Attached_Anims(this);
  127. } else {
  128. Start_To_Crumble();
  129. }
  130. }
  131. }
  132. return(res);
  133. }
  134. /***********************************************************************************************
  135. * TerrainClass::new -- Creates a new terrain object. *
  136. * *
  137. * This routine creates a new terrain object by grabbing a free slot *
  138. * out of the terrain object pool. *
  139. * *
  140. * INPUT: none *
  141. * *
  142. * OUTPUT: Returns with a pointer to the terrain object allocated. *
  143. * *
  144. * WARNINGS: none *
  145. * *
  146. * HISTORY: *
  147. * 05/14/1994 JLB : Created. *
  148. *=============================================================================================*/
  149. void * TerrainClass::operator new(size_t)
  150. {
  151. void * ptr = Terrains.Allocate();
  152. if (ptr) {
  153. ((TerrainClass *)ptr)->Set_Active();
  154. }
  155. return(ptr);
  156. }
  157. /***********************************************************************************************
  158. * TerrainClass::delete -- Deletes a terrain object. *
  159. * *
  160. * This routine deletes a terrain object by returning it to the *
  161. * terrain object pool. *
  162. * *
  163. * INPUT: ptr -- Pointer to the terrain object to delete. *
  164. * *
  165. * OUTPUT: none *
  166. * *
  167. * WARNINGS: none *
  168. * *
  169. * HISTORY: *
  170. * 05/14/1994 JLB : Created. *
  171. *=============================================================================================*/
  172. void TerrainClass::operator delete(void * ptr)
  173. {
  174. if (ptr) {
  175. ((TerrainClass *)ptr)->IsActive = false;
  176. }
  177. Terrains.Free((TerrainClass *)ptr);
  178. }
  179. /***********************************************************************************************
  180. * TerrainClass::TerrainClass -- This is the constructor for a terrain object *
  181. * *
  182. * This constructor for a terrain object will initialize the terrain *
  183. * object with it's proper type and insert it into the access *
  184. * tracking system. *
  185. * *
  186. * INPUT: type -- The terrain object type. *
  187. * *
  188. * cell -- The location of the terrain object. *
  189. * *
  190. * OUTPUT: none *
  191. * *
  192. * WARNINGS: none *
  193. * *
  194. * HISTORY: *
  195. * 05/02/1994 JLB : Created. *
  196. *=============================================================================================*/
  197. TerrainClass::TerrainClass(TerrainType type, CELL cell) :
  198. ObjectClass(RTTI_TERRAIN, Terrains.ID(this)),
  199. Class(TerrainTypes.Ptr((int)type)),
  200. IsOnFire(false),
  201. IsCrumbling(false)
  202. {
  203. Strength = Class->MaxStrength;
  204. if (cell != -1) {
  205. if (!Unlimbo(Cell_Coord(cell))) {
  206. delete this;
  207. }
  208. }
  209. Set_Rate(0); // turn off animation
  210. }
  211. /***********************************************************************************************
  212. * TerrainClass::Mark -- Marks the terrain object on the map. *
  213. * *
  214. * This routine will mark or remove the terrain object from the map *
  215. * tracking system. This is typically called when the terrain object *
  216. * is first created, when it is destroyed, and whenever it needs to be *
  217. * redrawn. *
  218. * *
  219. * INPUT: mark -- The marking operation to perform. *
  220. * *
  221. * OUTPUT: bool; Was the terrain object successfully marked? *
  222. * *
  223. * WARNINGS: none *
  224. * *
  225. * HISTORY: *
  226. * 05/02/1994 JLB : Created. *
  227. * 12/23/1994 JLB : Performs low level legality check before proceeding. *
  228. *=============================================================================================*/
  229. bool TerrainClass::Mark(MarkType mark)
  230. {
  231. assert(Terrains.ID(this) == ID);
  232. assert(IsActive);
  233. if (ObjectClass::Mark(mark)) {
  234. CELL cell = Coord_Cell(Coord);
  235. switch (mark) {
  236. case MARK_UP:
  237. Map.Pick_Up(cell, this);
  238. break;
  239. case MARK_DOWN:
  240. Map.Place_Down(cell, this);
  241. break;
  242. default:
  243. Map.Refresh_Cells(cell, Overlap_List(true));
  244. Map.Refresh_Cells(cell, Occupy_List());
  245. break;
  246. }
  247. return(true);
  248. }
  249. return(false);
  250. }
  251. /***********************************************************************************************
  252. * TerrainClass::Draw_It -- Renders the terrain object at the location specified. *
  253. * *
  254. * This routine is used to render the terrain object at the location specified and *
  255. * clipped to the window specified. This is the gruntwork drawing routine for the *
  256. * terrain objects as they are displayed on the map. *
  257. * *
  258. * INPUT: x,y -- The coordinate to draw the terrain object at (centered). *
  259. * *
  260. * window -- The clipping window to draw to. *
  261. * *
  262. * OUTPUT: none *
  263. * *
  264. * WARNINGS: none *
  265. * *
  266. * HISTORY: *
  267. * 06/27/1994 JLB : Created. *
  268. * 11/09/1994 JLB : Changed selected terrain highlight method. *
  269. *=============================================================================================*/
  270. void TerrainClass::Draw_It(int x, int y, WindowNumberType window) const
  271. {
  272. assert(Terrains.ID(this) == ID);
  273. assert(IsActive);
  274. void const * shapedata;
  275. shapedata = Get_Image_Data();
  276. if (shapedata) {
  277. int shapenum = 0;
  278. /*
  279. ** Determine the animation stage to render the terrain object. If it is crumbling, then
  280. ** it will display the crumbling animation.
  281. */
  282. if (IsCrumbling) {
  283. shapenum = Fetch_Stage()+IsCrumbling;
  284. } else {
  285. if (Strength < 2) {
  286. shapenum++;
  287. }
  288. }
  289. ShapeFlags_Type flags = SHAPE_NORMAL;
  290. if (Is_Selected_By_Player() && Debug_Map) flags = flags | SHAPE_FADING;
  291. /*
  292. **Terrain is always theater specific so flag it as such for Build_Frame
  293. */
  294. IsTheaterShape = true;
  295. // Add 'this' parameter to call new shape draw intercept. ST - 5/22/2019
  296. CC_Draw_Shape(this, shapedata, shapenum, x, y, window, flags|SHAPE_WIN_REL|SHAPE_GHOST, Map.FadingLight, Map.UnitShadow);
  297. IsTheaterShape = false;
  298. }
  299. }
  300. /***********************************************************************************************
  301. * TerrainClass::Init -- Initialize the terrain object tracking system. *
  302. * *
  303. * This routine will clear out the terrain object system so that no terrain objects will *
  304. * exists. It is called prior to loading or starting a scenario. *
  305. * *
  306. * INPUT: none *
  307. * *
  308. * OUTPUT: none *
  309. * *
  310. * WARNINGS: none *
  311. * *
  312. * HISTORY: *
  313. * 09/24/1994 JLB : Created. *
  314. *=============================================================================================*/
  315. void TerrainClass::Init(void)
  316. {
  317. Terrains.Free_All();
  318. }
  319. /***********************************************************************************************
  320. * TerrainClass::Can_Enter_Cell -- Determines if the terrain object can exist in the cell. *
  321. * *
  322. * This routine will examine the cell specified and determine if the the terrain object *
  323. * can legally exist there. *
  324. * *
  325. * INPUT: cell -- The cell to examine. *
  326. * *
  327. * OUTPUT: If the terrain object can be placed in the cell specified, then a value less than *
  328. * 256 will be returned. *
  329. * *
  330. * WARNINGS: none *
  331. * *
  332. * HISTORY: *
  333. * 09/24/1994 JLB : Created. *
  334. * 01/01/1995 JLB : Actually works now. *
  335. *=============================================================================================*/
  336. MoveType TerrainClass::Can_Enter_Cell(CELL cell, FacingType) const
  337. {
  338. assert(Terrains.ID(this) == ID);
  339. assert(IsActive);
  340. short const * offset; // Pointer to cell offset list.
  341. if ((unsigned)cell >= MAP_CELL_TOTAL) return(MOVE_NO);
  342. offset = Occupy_List();
  343. while (*offset != REFRESH_EOL) {
  344. if (Class->IsWaterBased) {
  345. if (!Map[(CELL)(cell + *offset++)].Is_Clear_To_Build(SPEED_FLOAT)) {
  346. return(MOVE_NO);
  347. }
  348. } else {
  349. if (!Map[(CELL)(cell + *offset++)].Is_Clear_To_Build()) {
  350. return(MOVE_NO);
  351. }
  352. }
  353. }
  354. return(MOVE_OK);
  355. }
  356. /***********************************************************************************************
  357. * TerrainClass::Catch_Fire -- Catches the terrain object on fire. *
  358. * *
  359. * This routine is called if the terrain object is supposed to catch on fire. The routine *
  360. * performs checking to make sure that only flammable terrain objects that aren't already *
  361. * on fire get caught on fire. *
  362. * *
  363. * INPUT: none *
  364. * *
  365. * OUTPUT: bool; Was the terrain object caught on fire by this routine? *
  366. * *
  367. * WARNINGS: none *
  368. * *
  369. * HISTORY: *
  370. * 09/27/1994 JLB : Created. *
  371. * 12/11/1994 JLB : Don't catch fire if already on fire or crumbling. *
  372. *=============================================================================================*/
  373. bool TerrainClass::Catch_Fire(void)
  374. {
  375. assert(Terrains.ID(this) == ID);
  376. assert(IsActive);
  377. if (!IsCrumbling && !IsOnFire && Class->Armor == ARMOR_WOOD) {
  378. AnimClass * anim = new AnimClass(ANIM_BURN_BIG, Coord_Add(Sort_Y(), 0xFFB00000L));
  379. if (anim) {
  380. anim->Attach_To(this);
  381. }
  382. anim = new AnimClass(ANIM_BURN_MED, Coord_Add(Sort_Y(), 0xFF200000L), 15);
  383. if (anim) {
  384. anim->Attach_To(this);
  385. }
  386. IsOnFire = true;
  387. return(true);
  388. }
  389. return(false);
  390. }
  391. /***********************************************************************************************
  392. * TerrainClass::Fire_Out -- Handles when fire has gone out. *
  393. * *
  394. * When the fire has gone out on a burning terrain object, this routine is called. The *
  395. * animation has already been terminated prior to calling this routine. All this routine *
  396. * needs to perform is any necessary local flag updating. *
  397. * *
  398. * INPUT: none *
  399. * *
  400. * OUTPUT: none *
  401. * *
  402. * WARNINGS: none *
  403. * *
  404. * HISTORY: *
  405. * 09/27/1994 JLB : Created. *
  406. *=============================================================================================*/
  407. void TerrainClass::Fire_Out(void)
  408. {
  409. assert(Terrains.ID(this) == ID);
  410. assert(IsActive);
  411. if (IsOnFire) {
  412. IsOnFire = false;
  413. if (!IsCrumbling && !Strength) {
  414. Detach_All();
  415. Mark();
  416. Start_To_Crumble();
  417. new AnimClass(ANIM_SMOKE_M, Coord_Add(Coord, Class->CenterBase));
  418. }
  419. }
  420. }
  421. /***********************************************************************************************
  422. * TerrainClass::AI -- Process the terrain object AI. *
  423. * *
  424. * This is used to handle any AI processing necessary for terrain objects. This might *
  425. * include animation effects. *
  426. * *
  427. * INPUT: none *
  428. * *
  429. * OUTPUT: none *
  430. * *
  431. * WARNINGS: none *
  432. * *
  433. * HISTORY: *
  434. * 09/27/1994 JLB : Created. *
  435. * 09/28/1994 JLB : Crumbling animation. *
  436. * 08/12/1996 JLB : Reset map zone when terrain object destroyed. *
  437. * 10/04/1996 JLB : Growth speed regulated by rules. *
  438. *=============================================================================================*/
  439. void TerrainClass::AI(void)
  440. {
  441. assert(Terrains.ID(this) == ID);
  442. assert(IsActive);
  443. ObjectClass::AI();
  444. if ((*this == TERRAIN_MINE) && (Frame % (Rule.GrowthRate * TICKS_PER_MINUTE)) == 0) {
  445. Map[::As_Cell(As_Target())].Spread_Tiberium(true);
  446. }
  447. if (StageClass::Graphic_Logic()) {
  448. Mark();
  449. /*
  450. ** If the terrain object is in the process of crumbling, then when at the
  451. ** last stage of the crumbling animation, delete the terrain object.
  452. */
  453. if (IsCrumbling && Fetch_Stage() == Get_Build_Frame_Count(Class->Get_Image_Data())-1) {
  454. delete this;
  455. Map.Zone_Reset(MZONEF_NORMAL|MZONEF_CRUSHER|MZONEF_DESTROYER);
  456. }
  457. }
  458. }
  459. #ifdef CHEAT_KEYS
  460. /***********************************************************************************************
  461. * TerrainClass::Debug_Dump -- Displays the status of the terrain object. *
  462. * *
  463. * This debugging support routine is used to display the status of the terrain object to *
  464. * the debug screen. *
  465. * *
  466. * INPUT: mono -- The mono screen to display the status to. *
  467. * *
  468. * OUTPUT: none *
  469. * *
  470. * WARNINGS: none *
  471. * *
  472. * HISTORY: *
  473. * 09/27/1994 JLB : Created. *
  474. *=============================================================================================*/
  475. void TerrainClass::Debug_Dump(MonoClass * mono) const
  476. {
  477. assert(Terrains.ID(this) == ID);
  478. assert(IsActive);
  479. ObjectClass::Debug_Dump(mono);
  480. }
  481. #endif
  482. /***********************************************************************************************
  483. * TerrainClass::Unlimbo -- Unlimbo terrain object onto the map. *
  484. * *
  485. * This routine is used to unlimbo the terrain object onto a location on the map. Normal *
  486. * unlimbo procedures are sufficient except that the coordinate location of a terrain *
  487. * object is based on the upper left corner of a cell rather than the center. Mask the *
  488. * coordinate value so that it snaps to the upper left corner and then proceed with a *
  489. * normal unlimbo process. *
  490. * *
  491. * INPUT: coord -- The coordinate to mark as the terrain's location. *
  492. * *
  493. * dir -- unused *
  494. * *
  495. * OUTPUT: bool; Was the terrain object successful in the unlimbo process? Failure could be *
  496. * the result of illegal positioning. *
  497. * *
  498. * WARNINGS: none *
  499. * *
  500. * HISTORY: *
  501. * 11/02/1994 JLB : Created. *
  502. * 11/16/1994 JLB : Checks for theater legality. *
  503. *=============================================================================================*/
  504. bool TerrainClass::Unlimbo(COORDINATE coord, DirType dir)
  505. {
  506. assert(Terrains.ID(this) == ID);
  507. assert(IsActive);
  508. if (Class->Theater & (1 << Scen.Theater)) {
  509. return(ObjectClass::Unlimbo(coord, dir));
  510. }
  511. return(false);
  512. }
  513. /***********************************************************************************************
  514. * TerrainClass::Start_To_Crumble -- Initiates crumbling of terrain (tree) object. *
  515. * *
  516. * This routine is used to start the crumbling process for terrain object. This only *
  517. * applies to trees. *
  518. * *
  519. * INPUT: none *
  520. * *
  521. * OUTPUT: none *
  522. * *
  523. * WARNINGS: none *
  524. * *
  525. * HISTORY: *
  526. * 12/22/1994 JLB : Created. *
  527. *=============================================================================================*/
  528. void TerrainClass::Start_To_Crumble(void)
  529. {
  530. assert(Terrains.ID(this) == ID);
  531. assert(IsActive);
  532. if (!IsCrumbling) {
  533. IsCrumbling = true;
  534. Set_Rate(2);
  535. Set_Stage(0);
  536. }
  537. }
  538. /***********************************************************************************************
  539. * TerrainClass::Limbo -- Handles terrain specific limbo action. *
  540. * *
  541. * This routine (called as a part of the limbo process) will remove the terrain occupation *
  542. * flag in the cell it occupies. *
  543. * *
  544. * INPUT: none *
  545. * *
  546. * OUTPUT: bool; Was the terrain object unlimboed? *
  547. * *
  548. * WARNINGS: none *
  549. * *
  550. * HISTORY: *
  551. * 12/22/1994 JLB : Created. *
  552. *=============================================================================================*/
  553. bool TerrainClass::Limbo(void)
  554. {
  555. assert(Terrains.ID(this) == ID);
  556. assert(IsActive);
  557. if (!IsInLimbo) {
  558. CELL cell = Coord_Cell(Coord);
  559. Map[cell].Flag.Occupy.Monolith = false;
  560. }
  561. return(ObjectClass::Limbo());
  562. }
  563. /***********************************************************************************************
  564. * TerrainClass::Center_Coord -- Fetches the center point coordinate for terrain object. *
  565. * *
  566. * Use this routine to fetch the center point terrain *
  567. * *
  568. * INPUT: *
  569. * *
  570. * OUTPUT: *
  571. * *
  572. * WARNINGS: *
  573. * *
  574. * HISTORY: *
  575. * 01/23/1995 JLB : Created. *
  576. *=============================================================================================*/
  577. COORDINATE TerrainClass::Center_Coord(void) const
  578. {
  579. assert(Terrains.ID(this) == ID);
  580. assert(IsActive);
  581. return(Coord_Add(Coord, Class->CenterBase));
  582. }
  583. /***********************************************************************************************
  584. * TerrainClass::Radar_Icon -- Fetches pointer to radar icon to use. *
  585. * *
  586. * This routine will return with a pointer to the radar icon to use for the cell number *
  587. * specified. *
  588. * *
  589. * INPUT: cell -- The cell number to use when determine what icon pointer to return. *
  590. * *
  591. * OUTPUT: Returns with a pointer to the 9 pixel values that make up the icon of this *
  592. * terrain object located at the cell specified. *
  593. * *
  594. * WARNINGS: none *
  595. * *
  596. * HISTORY: *
  597. * 05/08/1995 JLB : Created. *
  598. *=============================================================================================*/
  599. unsigned char * TerrainClass::Radar_Icon(CELL cell)
  600. {
  601. assert(Terrains.ID(this) == ID);
  602. assert(IsActive);
  603. unsigned char * icon = (unsigned char *)Class->Get_Radar_Data(); // get a pointer to radar icons
  604. int width = *icon++; // extract the width from data
  605. int height = *icon++; // extract the width from data
  606. /*
  607. ** Icon number that we need can be found by converting the cell and base
  608. ** cell to and x and y offset from the upper left of the cell, and then
  609. ** multiplying it by the width of the terrain in icons, which we
  610. ** conveniently stored out as the first byte of every icon we made.
  611. */
  612. int basecell = Coord_Cell(Coord); // find the base cell of terrain
  613. int ydiff = Cell_Y(cell) - Cell_Y(basecell);
  614. int xdiff = Cell_X(cell) - Cell_X(basecell);
  615. if (xdiff < width && ydiff < height) {
  616. int iconnum = (ydiff * width) + xdiff;
  617. return(icon + (iconnum * 9));
  618. }
  619. return(NULL);
  620. }
  621. /***********************************************************************************************
  622. * TerrainClass::Target_Coord -- Returns with the target coordinate. *
  623. * *
  624. * This routine will return with the coordinate to use if this terrain object were to be *
  625. * fired upon and the coordinate where the bullets should hit is needed. Usually, this *
  626. * location is the base of the object (e.g., the trunk of a tree). *
  627. * *
  628. * INPUT: none *
  629. * *
  630. * OUTPUT: Returns with the coordinate to use when firing at this object. *
  631. * *
  632. * WARNINGS: none *
  633. * *
  634. * HISTORY: *
  635. * 02/07/1996 JLB : Created. *
  636. *=============================================================================================*/
  637. COORDINATE TerrainClass::Target_Coord(void) const
  638. {
  639. return(Coord_Add(XY_Coord(0, -Height), Sort_Y()));
  640. }
  641. /***********************************************************************************************
  642. * TerrainClass::Read_INI -- Reads terrain objects from INI file. *
  643. * *
  644. * This routine reads a scenario control INI file and creates all *
  645. * terrain objects specified therein. Objects so created are placed *
  646. * upon the map. *
  647. * *
  648. * INI entry format: *
  649. * cellnum = TypeName, Triggername *
  650. * *
  651. * INPUT: buffer -- Pointer to the loaded scenario INI file data. *
  652. * *
  653. * OUTPUT: none *
  654. * *
  655. * WARNINGS: none *
  656. * *
  657. * HISTORY: *
  658. * 05/24/1994 JLB : Created. *
  659. *=============================================================================================*/
  660. void TerrainClass::Read_INI(CCINIClass & ini)
  661. {
  662. TerrainClass * tptr;
  663. int len = ini.Entry_Count(INI_Name());
  664. for (int index = 0; index < len; index++) {
  665. char const * entry = ini.Get_Entry(INI_Name(), index);
  666. TerrainType terrain = ini.Get_TerrainType(INI_Name(), entry, TERRAIN_NONE);
  667. CELL cell = atoi(entry);
  668. if (terrain != TERRAIN_NONE) {
  669. tptr = new TerrainClass(terrain, cell);
  670. }
  671. }
  672. }
  673. /***********************************************************************************************
  674. * TerrainClass::Write_INI -- Write all terrain objects to the INI database specified. *
  675. * *
  676. * This routine will clear out any old terrain data from the INI database and then *
  677. * fill it in with all the data from the terrain objects that currently exists. *
  678. * *
  679. * INPUT: ini -- Reference to the INI database to store the terrain objects in. *
  680. * *
  681. * OUTPUT: none *
  682. * *
  683. * WARNINGS: none *
  684. * *
  685. * HISTORY: *
  686. * 07/30/1996 JLB : Created. *
  687. *=============================================================================================*/
  688. void TerrainClass::Write_INI(CCINIClass & ini)
  689. {
  690. /*
  691. ** First, clear out all existing terrain data from the ini file.
  692. */
  693. ini.Clear(INI_Name());
  694. /*
  695. ** Write the terrain data out.
  696. */
  697. for (int index = 0; index < Terrains.Count(); index++) {
  698. TerrainClass * terrain;
  699. terrain = Terrains.Ptr(index);
  700. if (terrain != NULL && !terrain->IsInLimbo && terrain->IsActive) {
  701. char uname[10];
  702. sprintf(uname, "%d", Coord_Cell(terrain->Coord));
  703. ini.Put_TerrainType(INI_Name(), uname, *terrain);
  704. }
  705. }
  706. }