CnC_Remastered_Collection

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

OVERLAY.CPP (18403B)


      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/OVERLAY.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 : OVERLAY.CPP                                                  *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : May 17, 1994                                                 *
     28  *                                                                                             *
     29  *                  Last Update : July 24, 1995 [JLB]                                          *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   OverlayClass::Read_INI -- Reads the overlay data from an INI file.                        *
     34  *   OverlayClass::Init -- Resets the overlay object system.                                   *
     35  *   OverlayClass::Mark -- Marks the overlay down on the map.                                  *
     36  *   OverlayClass::OverlayClass -- Overlay object constructor.                                 *
     37  *   OverlayClass::delete -- Returns a overlay object to the pool.                             *
     38  *   OverlayClass::new -- Allocates a overlay object from pool                                 *
     39  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     40 
     41 #include	"function.h"
     42 #include	"overlay.h"
     43 
     44 
     45 HousesType OverlayClass::ToOwn = HOUSE_NONE;
     46 
     47 
     48 
     49 /***********************************************************************************************
     50  * OverlayClass::Init -- Resets the overlay object system.                                     *
     51  *                                                                                             *
     52  *    This routine resets the overlay object system. It is called                              *
     53  *    prior to loading a new scenario.                                                         *
     54  *                                                                                             *
     55  * INPUT:   none                                                                               *
     56  *                                                                                             *
     57  * OUTPUT:  none                                                                               *
     58  *                                                                                             *
     59  * WARNINGS:   none                                                                            *
     60  *                                                                                             *
     61  * HISTORY:                                                                                    *
     62  *   05/24/1994 JLB : Created.                                                                 *
     63  *=============================================================================================*/
     64 void OverlayClass::Init(void)
     65 {
     66 	Overlays.Free_All();
     67 }
     68 
     69 
     70 /***********************************************************************************************
     71  * OverlayClass::new -- Allocates a overlay object from pool                                   *
     72  *                                                                                             *
     73  *    This routine is used to allocate a overlay object from the                               *
     74  *    overlay object pool.                                                                     *
     75  *                                                                                             *
     76  * INPUT:   size  -- The size of a overlay object (not used).                                  *
     77  *                                                                                             *
     78  * OUTPUT:  Returns with a pointer to an available overlay object.                             *
     79  *                                                                                             *
     80  * WARNINGS:   none                                                                            *
     81  *                                                                                             *
     82  * HISTORY:                                                                                    *
     83  *   05/17/1994 JLB : Created.                                                                 *
     84  *=============================================================================================*/
     85 void * OverlayClass::operator new(size_t )
     86 {
     87 	void * ptr = Overlays.Allocate();
     88 	if (ptr) {
     89 		((OverlayClass *)ptr)->Set_Active();
     90 	}
     91 	return(ptr);
     92 }
     93 
     94 
     95 /***********************************************************************************************
     96  * OverlayClass::delete -- Returns a overlay object to the pool.                               *
     97  *                                                                                             *
     98  *    This routine will return a overlay object to the overlay object                          *
     99  *    pool. A overlay so returned is available for allocation again.                           *
    100  *                                                                                             *
    101  * INPUT:   ptr   -- Pointer to the object to be returned.                                     *
    102  *                                                                                             *
    103  * OUTPUT:  none                                                                               *
    104  *                                                                                             *
    105  * WARNINGS:   none                                                                            *
    106  *                                                                                             *
    107  * HISTORY:                                                                                    *
    108  *   05/17/1994 JLB : Created.                                                                 *
    109  *=============================================================================================*/
    110 void OverlayClass::operator delete(void * ptr)
    111 {
    112 	if (ptr) {
    113 		((OverlayClass *)ptr)->IsActive = false;
    114 	}
    115 	Overlays.Free((OverlayClass *)ptr);
    116 }
    117 
    118 
    119 /***********************************************************************************************
    120  * OverlayClass::OverlayClass -- Overlay object constructor.                                   *
    121  *                                                                                             *
    122  *    This is the constructor for a overlay object.                                            *
    123  *                                                                                             *
    124  * INPUT:   type  -- The overlay object this is to become.                                     *
    125  *                                                                                             *
    126  *          pos   -- The position on the map to place the object.                              *
    127  *                                                                                             *
    128  * OUTPUT:  none                                                                               *
    129  *                                                                                             *
    130  * WARNINGS:   none                                                                            *
    131  *                                                                                             *
    132  * HISTORY:                                                                                    *
    133  *   05/17/1994 JLB : Created.                                                                 *
    134  *=============================================================================================*/
    135 OverlayClass::OverlayClass(OverlayType type, CELL pos, HousesType house) :
    136 	ObjectClass(RTTI_OVERLAY, Overlays.ID(this)),
    137 	Class(OverlayTypes.Ptr((int)type))
    138 {
    139 	if (pos != -1) {
    140 		ToOwn = house;
    141 		Unlimbo(Cell_Coord(pos));
    142 		ToOwn = HOUSE_NONE;
    143 	}
    144 }
    145 
    146 
    147 /***********************************************************************************************
    148  * OverlayClass::Mark -- Marks the overlay down on the map.                                    *
    149  *                                                                                             *
    150  *    This routine will place the overlay onto the map. The overlay object is deleted by this  *
    151  *    operation. The map is updated to reflect the presence of the overlay.                    *
    152  *                                                                                             *
    153  * INPUT:   mark  -- The type of marking to perform. Only MARK_DOWN is supported.              *
    154  *                                                                                             *
    155  * OUTPUT:  bool; Was the overlay successfully marked? Failure occurs if it is not being       *
    156  *                marked down.                                                                 *
    157  *                                                                                             *
    158  * WARNINGS:   none                                                                            *
    159  *                                                                                             *
    160  * HISTORY:                                                                                    *
    161  *   09/24/1994 JLB : Created.                                                                 *
    162  *   12/23/1994 JLB : Checks low level legality before proceeding.                             *
    163  *=============================================================================================*/
    164 bool OverlayClass::Mark(MarkType mark)
    165 {
    166 	assert(Overlays.ID(this) == ID);
    167 	assert(IsActive);
    168 
    169 	if (ObjectClass::Mark(mark)) {
    170 		if (mark == MARK_DOWN) {
    171 			CELL	cell = Coord_Cell(Coord);
    172 			CellClass * cellptr = &Map[cell];
    173 
    174 			/*
    175 			**	Walls have special logic when they are marked down.
    176 			*/
    177 			if (Class->IsWall) {
    178 				if (cellptr->Is_Clear_To_Build()) {
    179 					cellptr->Overlay = Class->Type;
    180 					cellptr->OverlayData = 0;
    181 					cellptr->Redraw_Objects();
    182 					cellptr->Wall_Update();
    183 					Map.Zone_Reset(Class->IsCrushable ? MZONE_NORMAL : MZONE_NORMAL|MZONE_CRUSHER);
    184 
    185 					/*
    186 					**	Flag ownership of the cell if the 'global' ownership flag indicates that this
    187 					**	is necessary for the overlay.
    188 					*/
    189 					if (ToOwn != HOUSE_NONE) {
    190 						cellptr->Owner = ToOwn;
    191 					}
    192 
    193 				} else {
    194 					delete this;
    195 					return(false);
    196 				}
    197 			} else {
    198 
    199 				bool clear = false;
    200 				if (!ScenarioInit) {
    201 					if (Class->Type == OVERLAY_WATER_CRATE) {
    202 						clear = cellptr->Is_Clear_To_Move(SPEED_FLOAT, false, false);
    203 					} else {
    204 						if (Class->Type == OVERLAY_STEEL_CRATE || Class->Type == OVERLAY_WOOD_CRATE) {
    205 							clear = cellptr->Is_Clear_To_Move(SPEED_TRACK, false, false);
    206 						} else {
    207 							clear = cellptr->Is_Clear_To_Move(SPEED_TRACK, true, true);
    208 						}
    209 					}
    210 				} else {
    211 					clear = true;
    212 				}
    213 
    214 				if ((ScenarioInit || cellptr->Overlay == OVERLAY_NONE) && clear) {
    215 
    216 					cellptr->Overlay = Class->Type;
    217 					cellptr->OverlayData = 0;
    218 
    219 					cellptr->Redraw_Objects();
    220 					if (Class->Land == LAND_TIBERIUM) {
    221 						cellptr->OverlayData = 1;
    222 						cellptr->Tiberium_Adjust();
    223 					}
    224 				}
    225 			}
    226 
    227 			/*
    228 			**	*****  Is this really needed?
    229 			*/
    230 			cellptr->Recalc_Attributes();
    231 
    232 			/*
    233 			**	Remove the overlay and make sure the system thinks it was never placed down!
    234 			*/
    235 			Map.Overlap_Up(Coord_Cell(Coord), this);
    236 			IsDown = false;
    237 			IsInLimbo = true;
    238 
    239 			delete this;
    240 			return(true);
    241 		}
    242 	}
    243 	return(false);
    244 }
    245 
    246 
    247 /***********************************************************************************************
    248  * OverlayClass::Read_INI -- Reads the overlay data from an INI file.                          *
    249  *                                                                                             *
    250  *    This routine is used to load a scenario's overlay data. The overlay objects are read     *
    251  *    from the INI file and then created on the map.                                           *
    252  *                                                                                             *
    253  * INPUT:   buffer   -- Pointer to the INI file staging buffer.                                *
    254  *                                                                                             *
    255  * OUTPUT:  none                                                                               *
    256  *                                                                                             *
    257  * WARNINGS:   Requires that all the buildings be placed first, so the scan for assigning wall *
    258  *             ownership to the nearest building will work.                                    *
    259  * HISTORY:                                                                                    *
    260  *   09/01/1994 JLB : Created.                                                                 *
    261  *   07/24/1995 JLB : Specifically forbid manual crates in multiplayer scenarios.              *
    262  *=============================================================================================*/
    263 void OverlayClass::Read_INI(CCINIClass & ini)
    264 {
    265 	if (NewINIFormat > 1) {
    266 		int len = ini.Get_UUBlock("OverlayPack", _staging_buffer, sizeof(_staging_buffer));
    267 
    268 		if (len > 0) {
    269 			BufferStraw bpipe(_staging_buffer, len);
    270 			LCWStraw uncomp(LCWStraw::DECOMPRESS);
    271 			uncomp.Get_From(&bpipe);
    272 
    273 			for (CELL cell = 0; cell < MAP_CELL_TOTAL; cell++) {
    274 				OverlayType classid;
    275 
    276 				uncomp.Get(&classid, sizeof(classid));
    277 
    278 				if (classid != OVERLAY_NONE) {
    279 
    280 					if (Session.Type == GAME_NORMAL || !OverlayTypeClass::As_Reference(classid).IsCrate) {
    281 
    282 						/*
    283 						**	Don't allow placement of overlays on the top or bottom rows of
    284 						**	the map.
    285 						*/
    286 						if (cell >= MAP_CELL_W && cell <= MAP_CELL_TOTAL - MAP_CELL_W) {
    287 							new OverlayClass(classid, cell);
    288 
    289 							// Assign house ownership to cells with walls in 'em.
    290 							if (OverlayTypeClass::As_Reference(classid).IsWall) {
    291 								HousesType owner = HOUSE_NONE;
    292 								int distance = 0x7FFFFFFF;
    293 								for (int index = 0; index < Buildings.Count(); index++) {
    294 									BuildingClass * building = Buildings.Ptr(index);
    295 									int newdist = ::Distance(building->Center_Coord(), Cell_Coord(cell));
    296 									if (newdist < distance) {
    297 										distance = newdist;
    298 										owner = building->Owner();
    299 									}
    300 								}
    301 								Map[cell].Owner = owner;
    302 							}
    303 						}
    304 					}
    305 				}
    306 			}
    307 		}
    308 	}
    309 
    310 	if (NewINIFormat < 2 || ini.Is_Present("Overlay")) {
    311 		int len = ini.Entry_Count(INI_Name());
    312 		for (int index = 0; index < len; index++) {
    313 			char const * entry = ini.Get_Entry(INI_Name(), index);
    314 			CELL cell = atoi(entry);
    315 			OverlayType classid = ini.Get_OverlayType(INI_Name(), entry, OVERLAY_NONE);
    316 
    317 			/*
    318 			**	Don't allow placement of crates in the multiplayer scenarios.
    319 			*/
    320 			if (classid != OVERLAY_NONE && (Session.Type == GAME_NORMAL || !OverlayTypeClass::As_Reference(classid).IsCrate)) {
    321 
    322 				/*
    323 				**	Don't allow placement of overlays on the top or bottom rows of
    324 				**	the map.
    325 				*/
    326 				if (cell >= MAP_CELL_W && cell <= MAP_CELL_TOTAL - MAP_CELL_W) {
    327 					new OverlayClass(classid, cell);
    328 
    329 					// Assign house ownership to cells with walls in 'em.
    330 					if (OverlayTypeClass::As_Reference(classid).IsWall) {
    331 						HousesType owner = HOUSE_NONE;
    332 						int distance = 0x7FFFFFFF;
    333 						for (int index = 0; index < Buildings.Count(); index++) {
    334 							BuildingClass * building = Buildings.Ptr(index);
    335 							int newdist = ::Distance(building->Center_Coord(), Cell_Coord(cell));
    336 							if (newdist < distance) {
    337 								distance = newdist;
    338 								owner = building->Owner();
    339 							}
    340 						}
    341 						Map[cell].Owner = owner;
    342 					}
    343 				}
    344 			}
    345 		}
    346 	}
    347 }
    348 
    349 
    350 void OverlayClass::Write_INI(CCINIClass & ini)
    351 {
    352 	/*
    353 	**	First, clear out all existing unit data from the ini file.
    354 	*/
    355 	ini.Clear(INI_Name());
    356 	ini.Clear("OverlayPack");
    357 
    358 	BufferPipe bpipe(_staging_buffer, sizeof(_staging_buffer));
    359 	LCWPipe comppipe(LCWPipe::COMPRESS);
    360 
    361 	comppipe.Put_To(&bpipe);
    362 
    363 	int total = 0;
    364 	CellClass * cellptr = &Map[(CELL)0];
    365 	for (CELL index = 0; index < MAP_CELL_TOTAL; index++) {
    366 		total += comppipe.Put(&cellptr->Overlay, sizeof(cellptr->Overlay));
    367 		cellptr++;
    368 	}
    369 	if (total) {
    370 		ini.Put_UUBlock("OverlayPack", _staging_buffer, total);
    371 	}
    372 
    373 //	for (CELL index = 0; index < MAP_CELL_TOTAL; index++) {
    374 //		CellClass * cellptr = &Map[index];
    375 //		if (cellptr->Overlay != OVERLAY_NONE) {
    376 //			char	uname[10];
    377 //			sprintf(uname, "%d", index);
    378 //			ini.Put_Overlay(INI_Name(), uname, cellptr->Overlay);
    379 //		}
    380 //	}
    381 }