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