SMUDGE.CPP (22031B)
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\smudge.cpv 2.18 16 Oct 1995 16:52:06 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 : SMUDGE.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : August 9, 1994 * 28 * * 29 * Last Update : July 24, 1995 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * SmudgeClass::Init -- Initialize the smudge tracking system. * 34 * SmudgeClass::SmudgeClass -- Constructor for smudge objects. * 35 * SmudgeClass::operator delete -- Deletes the smudge from the tracking system. * 36 * SmudgeClass::operator new -- Creator of smudge objects. * 37 * SmudgeClass::Mark -- Marks a smudge down on the map. * 38 * SmudgeClass::Read_INI -- Reads smudge data from an INI file. * 39 * SmudgeClass::Write_INI -- Writes the smudge data to an INI file. * 40 * SmudgeClass::Disown -- Disowns (removes) a building bib piece. * 41 * SmudgeClass::Validate -- validates smudge pointer * 42 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 43 44 #include "function.h" 45 #include "smudge.h" 46 47 48 /* 49 ** This contains the value of the Virtual Function Table Pointer 50 */ 51 void * SmudgeClass::VTable; 52 53 HousesType SmudgeClass::ToOwn = HOUSE_NONE; 54 55 56 /*********************************************************************************************** 57 * SmudgeClass::Validate -- validates smudge pointer * 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 SmudgeClass::Validate(void) const 73 { 74 int num; 75 76 num = Smudges.ID(this); 77 if (num < 0 || num >= SMUDGE_MAX) { 78 Validate_Error("SMUDGE"); 79 return (0); 80 } 81 else 82 return (1); 83 } 84 #else 85 #define Validate() 86 #endif 87 88 89 /*********************************************************************************************** 90 * SmudgeClass::operator new -- Creator of smudge objects. * 91 * * 92 * This routine will allocate a smudge object from the smudge tracking pool. * 93 * * 94 * INPUT: none * 95 * * 96 * OUTPUT: Returns with a pointer to a newly allocated smudge object. If one couldn't be * 97 * found, then NULL is returned. * 98 * * 99 * WARNINGS: none * 100 * * 101 * HISTORY: * 102 * 09/01/1994 JLB : Created. * 103 *=============================================================================================*/ 104 void * SmudgeClass::operator new(size_t ) 105 { 106 void * ptr = Smudges.Allocate(); 107 if (ptr) { 108 ((SmudgeClass *)ptr)->Set_Active(); 109 } 110 return(ptr); 111 } 112 113 114 /*********************************************************************************************** 115 * SmudgeClass::operator delete -- Deletes the smudge from the tracking system. * 116 * * 117 * This routine is used to remove the smudge from the tracking system. * 118 * * 119 * INPUT: ptr -- Pointer to the smudge to delete. * 120 * * 121 * OUTPUT: none * 122 * * 123 * WARNINGS: none * 124 * * 125 * HISTORY: * 126 * 09/01/1994 JLB : Created. * 127 *=============================================================================================*/ 128 void SmudgeClass::operator delete(void *ptr) 129 { 130 if (ptr) { 131 ((SmudgeClass *)ptr)->IsActive = false; 132 } 133 Smudges.Free((SmudgeClass *)ptr); 134 135 //Map.Validate(); 136 } 137 138 139 /*********************************************************************************************** 140 * SmudgeClass::SmudgeClass -- Constructor for smudge objects. * 141 * * 142 * This is the typical constructor for smudge objects. If the position to place the * 143 * smudge is not given, then the smudge will be initialized in a limbo state. If the * 144 * smudge is placed on the map, then this operation causes the smudge object itself to be * 145 * deleted and special map values updated to reflect the presence of a smudge. * 146 * * 147 * INPUT: type -- The type of smudge to construct. * 148 * * 149 * pos -- The position to place the smudge. If -1, then the smudge is initialized * 150 * into a limbo state. * 151 * * 152 * OUTPUT: none * 153 * * 154 * WARNINGS: none * 155 * * 156 * HISTORY: * 157 * 09/01/1994 JLB : Created. * 158 *=============================================================================================*/ 159 SmudgeClass::SmudgeClass(SmudgeType type, COORDINATE pos, HousesType house) : 160 Class(&SmudgeTypeClass::As_Reference(type)) 161 { 162 if (pos != -1) { 163 ToOwn = house; 164 if (!Unlimbo(pos)) { 165 Delete_This(); 166 } 167 ToOwn = HOUSE_NONE; 168 } 169 } 170 171 172 /*********************************************************************************************** 173 * SmudgeClass::Init -- Initialize the smudge tracking system. * 174 * * 175 * This routine is used during the scenario clearing process to initialize the smudge * 176 * object tracking system to a null state. * 177 * * 178 * INPUT: none * 179 * * 180 * OUTPUT: none * 181 * * 182 * WARNINGS: none * 183 * * 184 * HISTORY: * 185 * 09/01/1994 JLB : Created. * 186 *=============================================================================================*/ 187 void SmudgeClass::Init(void) 188 { 189 SmudgeClass *ptr; 190 191 Smudges.Free_All(); 192 193 ptr = new SmudgeClass(); 194 VTable = ((void **)(((char *)ptr) + sizeof(AbstractClass) - 4))[0]; 195 delete ptr; 196 } 197 198 199 /*********************************************************************************************** 200 * SmudgeClass::Mark -- Marks a smudge down on the map. * 201 * * 202 * This routine will place the smudge on the map. If the map cell allows. * 203 * * 204 * INPUT: mark -- The type of marking to perform. Only MARK_DOWN is supported. * 205 * * 206 * OUTPUT: bool; Was the smudge marked successfully? Failure occurs if the smudge isn't * 207 * marked DOWN. * 208 * * 209 * WARNINGS: The smudge object is DELETED by this routine. * 210 * * 211 * HISTORY: * 212 * 09/22/1994 JLB : Created. * 213 * 12/23/1994 JLB : Checks low level legality before proceeding. * 214 *=============================================================================================*/ 215 bool SmudgeClass::Mark(MarkType mark) 216 { 217 Validate(); 218 if (ObjectClass::Mark(mark)) { 219 if (mark == MARK_DOWN) { 220 CELL origin = Coord_Cell(Coord); 221 222 for (int w = 0; w < Class->Width; w++) { 223 for (int h = 0; h < Class->Height; h++) { 224 CELL newcell = origin + w + (h*MAP_CELL_W); 225 if (Map.In_Radar(newcell)) { 226 CellClass * cell = &Map[newcell]; 227 228 if (Class->IsBib) { 229 cell->Smudge = Class->Type; 230 cell->SmudgeData = w + (h*Class->Width); 231 cell->Owner = ToOwn; 232 } else { 233 if (cell->Is_Generally_Clear()) { 234 if (Class->IsCrater && cell->Smudge != SMUDGE_NONE && SmudgeTypeClass::As_Reference(cell->Smudge).IsCrater) { 235 cell->SmudgeData++; 236 cell->SmudgeData = (int)MIN((int)cell->SmudgeData, (int)4); 237 } 238 239 if (cell->Smudge == SMUDGE_NONE) { 240 241 /* 242 ** Special selection of a crater that starts as close to the 243 ** specified coordinate as possible. 244 */ 245 if (Class->IsCrater) { 246 cell->Smudge = (SmudgeType)(SMUDGE_CRATER1 + CellClass::Spot_Index(Coord)); 247 } else { 248 cell->Smudge = Class->Type; 249 } 250 cell->SmudgeData = 0; 251 } 252 } 253 } 254 255 /* 256 ** Flag everything that might be overlapping this cell to redraw itself. 257 */ 258 cell->Redraw_Objects(); 259 } 260 } 261 } 262 263 /* 264 ** Whether it was successful in placing, or not, delete the smudge object. It isn't 265 ** needed once the map has been updated with the proper smudge data. 266 */ 267 Delete_This(); 268 return(true); 269 } 270 } 271 return(false); 272 } 273 274 275 /*********************************************************************************************** 276 * SmudgeClass::Read_INI -- Reads smudge data from an INI file. * 277 * * 278 * This routine is used by the scenario loader to read the smudge data in an INI file and * 279 * create the appropriate smudge objects on the map. * 280 * * 281 * INPUT: buffer -- Pointer to the INI file staging buffer. * 282 * * 283 * OUTPUT: none * 284 * * 285 * WARNINGS: none * 286 * * 287 * HISTORY: * 288 * 09/01/1994 JLB : Created. * 289 * 07/24/1995 JLB : Sets the smudge data value as well. * 290 *=============================================================================================*/ 291 void SmudgeClass::Read_INI(char *buffer) 292 { 293 char buf[128]; // Working string staging buffer. 294 295 int len = strlen(buffer) + 2; 296 char * tbuffer = buffer + len; 297 298 WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-len, buffer); 299 while (*tbuffer != '\0') { 300 SmudgeType smudge; // Smudge type. 301 302 WWGetPrivateProfileString(INI_Name(), tbuffer, NULL, buf, sizeof(buf)-1, buffer); 303 smudge = SmudgeTypeClass::From_Name(strtok(buf, ",")); 304 if (smudge != SMUDGE_NONE) { 305 char * ptr = strtok(NULL, ","); 306 if (ptr) { 307 int data = 0; 308 CELL cell = atoi(ptr); 309 ptr = strtok(NULL, ","); 310 if (ptr) data = atoi(ptr); 311 new SmudgeClass(smudge, Cell_Coord(cell)); 312 if (Map[cell].Smudge == smudge && data) { 313 Map[cell].SmudgeData = data; 314 } 315 } 316 } 317 tbuffer += strlen(tbuffer)+1; 318 } 319 } 320 321 322 /*********************************************************************************************** 323 * SmudgeClass::Write_INI -- Writes the smudge data to an INI file. * 324 * * 325 * This routine is used by the scenario editor to write the smudge data to an INI file. * 326 * * 327 * INPUT: buffer -- Pointer to the INI file staging buffer. * 328 * * 329 * OUTPUT: none * 330 * * 331 * WARNINGS: none * 332 * * 333 * HISTORY: * 334 * 09/01/1994 JLB : Created. * 335 * 07/24/1995 JLB : Records the smudge data as well. * 336 *=============================================================================================*/ 337 void SmudgeClass::Write_INI(char *buffer) 338 { 339 char uname[10]; 340 char buf[127]; 341 char *tbuffer; // Accumulation buffer of unit IDs. 342 343 /* 344 ** First, clear out all existing template data from the ini file. 345 */ 346 tbuffer = buffer + strlen(buffer) + 2; 347 WWGetPrivateProfileString(INI_Name(), NULL, NULL, tbuffer, ShapeBufferSize-strlen(buffer), buffer); 348 while (*tbuffer != '\0') { 349 WWWritePrivateProfileString(INI_Name(), tbuffer, NULL, buffer); 350 tbuffer += strlen(tbuffer)+1; 351 } 352 353 /* 354 ** Find all templates and write them to the file. 355 */ 356 for (CELL index = 0; index < MAP_CELL_TOTAL; index++) { 357 CellClass * ptr; 358 359 ptr = &Map[index]; 360 if (ptr->Smudge != SMUDGE_NONE) { 361 SmudgeTypeClass const * stype = &SmudgeTypeClass::As_Reference(ptr->Smudge); 362 if (!stype->IsBib) { 363 sprintf(uname, "%03d", index); 364 sprintf(buf, "%s,%d,%d", stype->IniName, index, ptr->SmudgeData); 365 WWWritePrivateProfileString(INI_Name(), uname, buf, buffer); 366 } 367 } 368 } 369 } 370 371 372 /*********************************************************************************************** 373 * SmudgeClass::Disown -- Disowns (removes) a building bib piece. * 374 * * 375 * This routine is used when a building is removed from the game. If there was any bib * 376 * attached, this routine will be called to disown the cells and remove the bib artwork. * 377 * * 378 * INPUT: cell -- The origin cell for this bib removal. * 379 * * 380 * OUTPUT: none * 381 * * 382 * WARNINGS: This is actually working on a temporary bib object. It is created for the sole * 383 * purpose of calling this routine. It will be deleted immediately afterward. * 384 * * 385 * HISTORY: * 386 * 07/04/1995 JLB : Created. * 387 *=============================================================================================*/ 388 void SmudgeClass::Disown(CELL cell) 389 { 390 Validate(); 391 if (Class->IsBib) { 392 for (int w = 0; w < Class->Width; w++) { 393 for (int h = 0; h < Class->Height; h++) { 394 CellClass & cellptr = Map[cell + w + (h*MAP_CELL_W)]; 395 396 if (cellptr.Overlay == OVERLAY_NONE || !OverlayTypeClass::As_Reference(cellptr.Overlay).IsWall) { 397 cellptr.Smudge = SMUDGE_NONE; 398 cellptr.SmudgeData = 0; 399 cellptr.Owner = HOUSE_NONE; 400 cellptr.Redraw_Objects(); 401 } 402 } 403 } 404 } 405 }