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 }