TERRAIN.CPP 46 KB

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