CnC_Remastered_Collection

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

OVERLAY.CPP (21680B)


      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:   F:\projects\c&c\vcs\code\overlay.cpv   2.17   16 Oct 1995 16:50:44   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::Write_INI -- Writes the overlay data to an INI file.                        *
     35  *   OverlayClass::delete -- Returns a overlay object to the pool.                             *
     36  *   OverlayClass::Init -- Resets the overlay object system.                                   *
     37  *   OverlayClass::new -- Allocates a overlay object from pool                                 *
     38  *   OverlayClass::OverlayClass -- Overlay object constructor.                                 *
     39  *   OverlayClass::Mark -- Marks the overlay down on the map.                                  *
     40  *   OverlayClass::Validate -- validates overlay															  *
     41  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     42 
     43 #include	"function.h"
     44 #include	"overlay.h"
     45 
     46 /*
     47 ** This contains the value of the Virtual Function Table Pointer
     48 */
     49 void * OverlayClass::VTable;
     50 
     51 HousesType OverlayClass::ToOwn = HOUSE_NONE;
     52 
     53 OverlayClass::OverlayClass(void) : Class(0) {ToOwn = HOUSE_NONE;};
     54 
     55 
     56 /***********************************************************************************************
     57  * OverlayClass::Validate -- validates overlay																  *
     58  *                                                                                             *
     59  * INPUT:                                                                                      *
     60  *		none.																												  *
     61  *                                                                                             *
     62  * OUTPUT:                                                                                     *
     63  *		1 = ok, 0 = error																								  *
     64  *                                                                                             *
     65  * WARNINGS:                                                                                   *
     66  *		none.																												  *
     67  *                                                                                             *
     68  * HISTORY:                                                                                    *
     69  *   08/09/1995 BRR : Created.                                                                 *
     70  *=============================================================================================*/
     71 #ifdef CHEAT_KEYS
     72 int OverlayClass::Validate(void) const
     73 {
     74 	int num;
     75 
     76 	num = Overlays.ID(this);
     77 	if (num < 0 || num >= OVERLAY_MAX) {
     78 		Validate_Error("OVERLAY");
     79 		return (0);
     80 	}
     81 	else
     82 		return (1);
     83 }
     84 #else
     85 #define	Validate()
     86 #endif
     87 
     88 
     89 /***********************************************************************************************
     90  * OverlayClass::Init -- Resets the overlay object system.                                     *
     91  *                                                                                             *
     92  *    This routine resets the overlay object system. It is called                              *
     93  *    prior to loading a new scenario.                                                         *
     94  *                                                                                             *
     95  * INPUT:   none                                                                               *
     96  *                                                                                             *
     97  * OUTPUT:  none                                                                               *
     98  *                                                                                             *
     99  * WARNINGS:   none                                                                            *
    100  *                                                                                             *
    101  * HISTORY:                                                                                    *
    102  *   05/24/1994 JLB : Created.                                                                 *
    103  *=============================================================================================*/
    104 void OverlayClass::Init(void)
    105 {
    106 	OverlayClass *ptr;
    107 
    108 	Overlays.Free_All();
    109 
    110 	ptr = new OverlayClass();
    111 	VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0];
    112 	delete ptr;
    113 }
    114 
    115 
    116 /***********************************************************************************************
    117  * OverlayClass::new -- Allocates a overlay object from pool                                   *
    118  *                                                                                             *
    119  *    This routine is used to allocate a overlay object from the                               *
    120  *    overlay object pool.                                                                     *
    121  *                                                                                             *
    122  * INPUT:   size  -- The size of a overlay object (not used).                                  *
    123  *                                                                                             *
    124  * OUTPUT:  Returns with a pointer to an available overlay object.                             *
    125  *                                                                                             *
    126  * WARNINGS:   none                                                                            *
    127  *                                                                                             *
    128  * HISTORY:                                                                                    *
    129  *   05/17/1994 JLB : Created.                                                                 *
    130  *=============================================================================================*/
    131 void * OverlayClass::operator new(size_t )
    132 {
    133 	void * ptr = Overlays.Allocate();
    134 	if (ptr) {
    135 		((OverlayClass *)ptr)->Set_Active();
    136 	}
    137 	return(ptr);
    138 }
    139 
    140 
    141 /***********************************************************************************************
    142  * OverlayClass::delete -- Returns a overlay object to the pool.                               *
    143  *                                                                                             *
    144  *    This routine will return a overlay object to the overlay object                          *
    145  *    pool. A overlay so returned is available for allocation again.                           *
    146  *                                                                                             *
    147  * INPUT:   ptr   -- Pointer to the object to be returned.                                     *
    148  *                                                                                             *
    149  * OUTPUT:  none                                                                               *
    150  *                                                                                             *
    151  * WARNINGS:   none                                                                            *
    152  *                                                                                             *
    153  * HISTORY:                                                                                    *
    154  *   05/17/1994 JLB : Created.                                                                 *
    155  *=============================================================================================*/
    156 void OverlayClass::operator delete(void *ptr)
    157 {
    158 	if (ptr) {
    159 		((OverlayClass *)ptr)->IsActive = false;
    160 	}
    161 	Overlays.Free((OverlayClass *)ptr);
    162 
    163 	//Map.Validate();
    164 }
    165 
    166 
    167 /***********************************************************************************************
    168  * OverlayClass::OverlayClass -- Overlay object constructor.                                   *
    169  *                                                                                             *
    170  *    This is the constructor for a overlay object.                                            *
    171  *                                                                                             *
    172  * INPUT:   type  -- The overlay object this is to become.                                     *
    173  *                                                                                             *
    174  *          pos   -- The position on the map to place the object.                              *
    175  *                                                                                             *
    176  * OUTPUT:  none                                                                               *
    177  *                                                                                             *
    178  * WARNINGS:   none                                                                            *
    179  *                                                                                             *
    180  * HISTORY:                                                                                    *
    181  *   05/17/1994 JLB : Created.                                                                 *
    182  *=============================================================================================*/
    183 OverlayClass::OverlayClass(OverlayType type, CELL pos, HousesType house) :
    184 	Class(&OverlayTypeClass::As_Reference(type))
    185 {
    186 	if (pos != -1) {
    187 		ToOwn = house;
    188 		Unlimbo(Cell_Coord(pos));
    189 		ToOwn = HOUSE_NONE;
    190 	}
    191 }
    192 
    193 
    194 /***********************************************************************************************
    195  * OverlayClass::Mark -- Marks the overlay down on the map.                                    *
    196  *                                                                                             *
    197  *    This routine will place the overlay onto the map. The overlay object is deleted by this  *
    198  *    operation. The map is updated to reflect the presence of the overlay.                    *
    199  *                                                                                             *
    200  * INPUT:   mark  -- The type of marking to perform. Only MARK_DOWN is supported.              *
    201  *                                                                                             *
    202  * OUTPUT:  bool; Was the overlay successfully marked? Failure occurs if it is not being       *
    203  *                marked down.                                                                 *
    204  *                                                                                             *
    205  * WARNINGS:   none                                                                            *
    206  *                                                                                             *
    207  * HISTORY:                                                                                    *
    208  *   09/24/1994 JLB : Created.                                                                 *
    209  *   12/23/1994 JLB : Checks low level legality before proceeding.                             *
    210  *=============================================================================================*/
    211 bool OverlayClass::Mark(MarkType mark)
    212 {
    213 	Validate();
    214 	if (ObjectClass::Mark(mark)) {
    215 		if (mark == MARK_DOWN) {
    216 			CELL	cell = Coord_Cell(Coord);
    217 			CellClass * cellptr = &Map[cell];
    218 
    219 			/*
    220 			**	Road placement occurs in two steps. First the foundation is placed, but only
    221 			**	on buildable terrain. Second, the road is completed, but only if the foundation
    222 			**	was previously placed.
    223 			*/
    224 			if (*this == OVERLAY_ROAD) {
    225 				if ((cellptr->Overlay == OVERLAY_ROAD && cellptr->OverlayData == 0) ||
    226 					(cellptr->Overlay == OVERLAY_NONE && cellptr->Is_Generally_Clear())) {
    227 
    228 					if (cellptr->Overlay == OVERLAY_ROAD) {
    229 						cellptr->OverlayData = 1;
    230 					} else {
    231 						cellptr->OverlayData = 0;
    232 					}
    233 					cellptr->Overlay = Class->Type;
    234 					cellptr->Redraw_Objects();
    235 				}
    236 			} else {
    237 
    238 				/*
    239 				**	Walls have special logic when they are marked down.
    240 				*/
    241 				if (Class->IsWall) {
    242 					if (cellptr->Is_Generally_Clear() && cellptr->Overlay != OVERLAY_FLAG_SPOT) {
    243 						cellptr->Overlay = Class->Type;
    244 						cellptr->OverlayData = 0;
    245 						cellptr->Redraw_Objects();
    246 						cellptr->Wall_Update();
    247 
    248 						/*
    249 						**	Flag ownership of the cell if the 'global' ownership flag indicates that this
    250 						**	is necessary for the overlay.
    251 						*/
    252 						if (ToOwn != HOUSE_NONE) {
    253 							cellptr->Owner = ToOwn;
    254 						}
    255 
    256 					} else {
    257 						Delete_This();
    258 						return(false);
    259 					}
    260 				} else {
    261 					if ((cellptr->Overlay == OVERLAY_NONE || cellptr->Overlay == OVERLAY_SQUISH) && !cellptr->Cell_Terrain() && Ground[cellptr->Land_Type()].Build) {
    262 
    263 						/*
    264 						**	Increment the global crate counter. This is used to regulate
    265 						**	the crate generation.
    266 						*/
    267 						if (Class->IsCrate) CrateCount++;
    268 
    269 						/*
    270 						**	Don't show the squish unless the gross flag is active.
    271 						*/
    272 						if (!Special.IsGross && Class->Type != OVERLAY_SQUISH) {
    273 							cellptr->Overlay = Class->Type;
    274 							cellptr->OverlayData = 0;
    275 						}
    276 						cellptr->Redraw_Objects();
    277 						if (Class->Land == LAND_TIBERIUM) {
    278 							cellptr->OverlayData = 1;
    279 							cellptr->Tiberium_Adjust();
    280 						} else {
    281 							if (*this == OVERLAY_CONCRETE) {
    282 								CELL	newcell;
    283 
    284 								/*
    285 								**	Smudges go away when concrete is laid down.
    286 								*/
    287 								cellptr->Smudge = SMUDGE_NONE;
    288 								cellptr->SmudgeData = 0;
    289 								cellptr->Concrete_Calc();
    290 
    291 								/*
    292 								**	Possibly add concrete to adjacent cells depending on whether this
    293 								**	concrete is in an odd or even row.
    294 								*/
    295 								if (Cell_X(cell) & 0x01) {
    296 									newcell = Adjacent_Cell((CELL)(cellptr->Cell_Number()), FACING_W);
    297 								} else {
    298 									newcell = Adjacent_Cell((CELL)(cellptr->Cell_Number()), FACING_E);
    299 								}
    300 								if (Map[newcell].Overlay != OVERLAY_CONCRETE) {
    301 									Class->Create_And_Place(newcell);
    302 								}
    303 
    304 								/*
    305 								**	The display attributes must be recalculated for all adjacent
    306 								**	cells since their shape can be altered by the presence of
    307 								**	concrete at this location.
    308 								*/
    309 								static FacingType _face[4] = {FACING_N, FACING_E, FACING_S, FACING_W};
    310 
    311 								for (int index = 0; index < (sizeof(_face)/sizeof(_face[0])); index++) {
    312 									CellClass * adjcell = cellptr->Adjacent_Cell(_face[index]);
    313 									if (adjcell) adjcell->Concrete_Calc();
    314 								}
    315 							}
    316 						}
    317 					}
    318 				}
    319 
    320 				/*
    321 				**	*****  Is this really needed?
    322 				*/
    323 				cellptr->Recalc_Attributes();
    324 			}
    325 			Delete_This();
    326 			return(true);
    327 		}
    328 	}
    329 	return(false);
    330 }
    331 
    332 
    333 /***********************************************************************************************
    334  * OverlayClass::Read_INI -- Reads the overlay data from an INI file.                          *
    335  *                                                                                             *
    336  *    This routine is used to load a scenario's overlay data. The overlay objects are read     *
    337  *    from the INI file and then created on the map.                                           *
    338  *                                                                                             *
    339  * INPUT:   buffer   -- Pointer to the INI file staging buffer.                                *
    340  *                                                                                             *
    341  * OUTPUT:  none                                                                               *
    342  *                                                                                             *
    343  * WARNINGS:   none                                                                            *
    344  *                                                                                             *
    345  * HISTORY:                                                                                    *
    346  *   09/01/1994 JLB : Created.                                                                 *
    347  *   07/24/1995 JLB : Specifically forbid manual crates in multiplayer scenarios.              *
    348  *=============================================================================================*/
    349 void OverlayClass::Read_INI(char *buffer)
    350 {
    351 	char	*tbuffer;
    352 	int	len;				// Length of data in buffer.
    353 	char	buf[128];
    354 
    355 	len = strlen(buffer) + 2;
    356 	tbuffer = buffer + len;
    357 
    358 	WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer);
    359 	while (*tbuffer != '\0') {
    360 		CELL			cell;
    361 		OverlayType	classid;
    362 
    363 		cell = atoi(tbuffer);
    364 		WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer);
    365 		classid = OverlayTypeClass::From_Name(strtok(buf, ",\n\r"));
    366 
    367 		/*
    368 		**	Don't allow placement of crates in the multiplayer scenarios.
    369 		*/
    370 		if (classid != OVERLAY_NONE && (GameToPlay == GAME_NORMAL || !OverlayTypeClass::As_Reference(classid).IsCrate)) {
    371 
    372 			/*
    373 			**	Don't allow placement of overlays on the top or bottom rows of
    374 			**	the map.
    375 			*/
    376 			if (cell >= MAP_CELL_W && cell <= MAP_CELL_TOTAL - MAP_CELL_W) {
    377 				new OverlayClass(classid, cell);
    378 			}
    379 		}
    380 		tbuffer += strlen(tbuffer)+1;
    381 	}
    382 }
    383 
    384 
    385 /***********************************************************************************************
    386  * OverlayClass::Write_INI -- Writes the overlay data to an INI file.                          *
    387  *                                                                                             *
    388  *    This is used to output the overlay data to a scenario INI file. Typically, this is       *
    389  *    only used by the scenario editor.                                                        *
    390  *                                                                                             *
    391  * INPUT:   buffer   -- Pointer to the INI file staging buffer.                                *
    392  *                                                                                             *
    393  * OUTPUT:  none                                                                               *
    394  *                                                                                             *
    395  * WARNINGS:   none                                                                            *
    396  *                                                                                             *
    397  * HISTORY:                                                                                    *
    398  *   09/01/1994 JLB : Created.                                                                 *
    399  *=============================================================================================*/
    400 void OverlayClass::Write_INI(char *buffer)
    401 {
    402 	int	index;
    403 	char	uname[10];
    404 	char	buf[128];
    405 	char	*tbuffer;		// Accumulation buffer of unit IDs.
    406 
    407 	/*
    408 	**	First, clear out all existing unit data from the ini file.
    409 	*/
    410 	tbuffer = buffer + strlen(buffer) + 2;
    411 	WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer);
    412 	while (*tbuffer != '\0') {
    413 		WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer);
    414 		tbuffer += strlen(tbuffer)+1;
    415 	}
    416 
    417 	/*
    418 	**	Write the unit data out.
    419 	*/
    420 	for (index = 0; index < MAP_CELL_TOTAL; index++) {
    421 		CellClass	* cellptr = &Map[index];
    422 
    423 		if (cellptr->Overlay != OVERLAY_NONE) {
    424 			sprintf(uname, "%03d", index);
    425 			sprintf(buf, "%s", OverlayTypeClass::As_Reference(cellptr->Overlay).IniName);
    426 			WWWritePrivateProfileString(INI_Name(), uname, buf, buffer);
    427 		}
    428 	}
    429 }