CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

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 }