BASE.CPP (29460B)
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/BASE.CPP 1 3/03/97 10:24a 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 : BASE.CPP * 24 * * 25 * Programmer : Bill Randolph * 26 * * 27 * Start Date : 03/27/95 * 28 * * 29 * Last Update : July 30, 1996 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * BaseClass::Get_Building -- Returns ptr to the built building for the given node * 34 * BaseClass::Get_Node -- Finds the node that matches the cell specified. * 35 * BaseClass::Get_Node -- Returns ptr to the node corresponding to given object * 36 * BaseClass::Is_Built -- Tells if given item in the list has been built yet * 37 * BaseClass::Is_Node -- Tells if the given building is part of our base list * 38 * BaseClass::Load -- loads from a saved game file * 39 * BaseClass::Next_Buildable -- returns ptr to the next node that needs to be built * 40 * BaseClass::Read_INI -- INI reading routine * 41 * BaseClass::Save -- saves to a saved game file * 42 * BaseClass::Write_INI -- Writes all the base information to the INI database. * 43 * BaseNodeClass::operator != -- inequality operator * 44 * BaseNodeClass::operator == -- equality operator * 45 * BaseNodeClass::operator > -- greater-than operator * 46 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 47 48 #include "function.h" 49 50 51 /*********************************************************************************************** 52 * BaseNodeClass::operator == -- equality operator * 53 * * 54 * INPUT: * 55 * node node to test against * 56 * * 57 * OUTPUT: * 58 * true = equal, false = not equal * 59 * * 60 * WARNINGS: * 61 * none. * 62 * * 63 * HISTORY: * 64 * 03/24/1995 BRR : Created. * 65 *=============================================================================================*/ 66 int BaseNodeClass::operator == (BaseNodeClass const & node) 67 { 68 return(Type == node.Type && Cell == node.Cell); 69 } 70 71 72 /*********************************************************************************************** 73 * BaseNodeClass::operator != -- inequality operator * 74 * * 75 * INPUT: * 76 * node node to test against * 77 * * 78 * OUTPUT: * 79 * comparison result * 80 * * 81 * WARNINGS: * 82 * none. * 83 * * 84 * HISTORY: * 85 * 03/24/1995 BRR : Created. * 86 *=============================================================================================*/ 87 int BaseNodeClass::operator !=(BaseNodeClass const & node) 88 { 89 return(!(*this == node)); 90 } 91 92 93 /*********************************************************************************************** 94 * BaseNodeClass::operator > -- greater-than operator * 95 * * 96 * INPUT: * 97 * node node to test against * 98 * * 99 * OUTPUT: * 100 * comparison result * 101 * * 102 * WARNINGS: * 103 * none. * 104 * * 105 * HISTORY: * 106 * 03/24/1995 BRR : Created. * 107 *=============================================================================================*/ 108 int BaseNodeClass::operator > (BaseNodeClass const & ) 109 { 110 return(true); 111 } 112 113 114 /*********************************************************************************************** 115 * BaseClass::Load -- loads from a saved game file * 116 * * 117 * INPUT: * 118 * file open file * 119 * * 120 * OUTPUT: * 121 * true = success, false = failure * 122 * * 123 * WARNINGS: * 124 * none. * 125 * * 126 * HISTORY: * 127 * 03/24/1995 BRR : Created. * 128 * 07/04/1996 JLB : Converted to demand driven data source. * 129 *=============================================================================================*/ 130 bool BaseClass::Load(Straw & file) 131 { 132 int num_struct; 133 int i; 134 BaseNodeClass node; 135 136 /* 137 ** Read in & check the size of this class 138 */ 139 if (file.Get(&i, sizeof(i)) != sizeof(i)) { 140 return(false); 141 } 142 143 if (i != sizeof(*this)) { 144 return(false); 145 } 146 147 /* 148 ** Read in the House & the number of structures in the base 149 */ 150 if (file.Get(&House, sizeof(House)) != sizeof(House)) { 151 return(false); 152 } 153 154 if (file.Get(&num_struct, sizeof(num_struct)) != sizeof(num_struct)) { 155 return(false); 156 } 157 158 /* 159 ** Read each node entry & add it to the list 160 */ 161 for (i = 0; i < num_struct; i++) { 162 if (file.Get(&node, sizeof(node)) != sizeof(node)) { 163 return(false); 164 } 165 Nodes.Add(node); 166 } 167 168 return(true); 169 } 170 171 172 /*********************************************************************************************** 173 * BaseClass::Save -- saves to a saved game file * 174 * * 175 * INPUT: * 176 * file open file * 177 * * 178 * OUTPUT: * 179 * true = success, false = failure * 180 * * 181 * WARNINGS: * 182 * none. * 183 * * 184 * HISTORY: * 185 * 03/24/1995 BRR : Created. * 186 * 07/04/1996 JLB : Converted to supply driven data output. * 187 *=============================================================================================*/ 188 bool BaseClass::Save(Pipe & file) const 189 { 190 int num_struct; 191 int i; 192 BaseNodeClass node; 193 194 /* 195 ** Write the size of this class 196 */ 197 i = sizeof(*this); 198 file.Put(&i, sizeof(i)); 199 200 /* 201 ** Write the House & the number of structures in the base 202 */ 203 file.Put(&House, sizeof(House)); 204 205 num_struct = Nodes.Count(); 206 file.Put(&num_struct, sizeof(num_struct)); 207 208 /* 209 ** Write each node entry 210 */ 211 for (i = 0; i < num_struct; i++) { 212 node = Nodes[i]; 213 file.Put(&node, sizeof(node)); 214 } 215 216 return(true); 217 } 218 219 220 /*********************************************************************************************** 221 * BaseClass::Is_Built -- Tells if given item in the list has been built yet * 222 * * 223 * INPUT: * 224 * index index into base list * 225 * * 226 * OUTPUT: * 227 * true = yes, false = no * 228 * * 229 * WARNINGS: * 230 * none. * 231 * * 232 * HISTORY: * 233 * 03/24/1995 BRR : Created. * 234 *=============================================================================================*/ 235 bool BaseClass::Is_Built(int index) const 236 { 237 if (Get_Building(index) != NULL) { 238 return(true); 239 } else { 240 return(false); 241 } 242 } 243 244 245 /*********************************************************************************************** 246 * BaseClass::Get_Building -- Returns ptr to the built building for the given node * 247 * * 248 * INPUT: * 249 * obj pointer to building to test * 250 * * 251 * OUTPUT: * 252 * ptr to already-built building, NULL if none * 253 * * 254 * WARNINGS: * 255 * none. * 256 * * 257 * HISTORY: * 258 * 03/24/1995 BRR : Created. * 259 * 07/30/1996 JLB : Handle arbitrary overlapper list length. * 260 *=============================================================================================*/ 261 BuildingClass * BaseClass::Get_Building(int index) const 262 { 263 ObjectClass * obj[1 + ARRAY_SIZE(Map[(CELL)0].Overlapper)]; 264 265 /* 266 ** Check the location on the map where this building should be; if it's 267 ** there, return a pointer to it. 268 */ 269 CELL cell = Nodes[index].Cell; 270 271 obj[0] = Map[cell].Cell_Building(); 272 int count = 1; 273 for (int xindex = 0; xindex < ARRAY_SIZE(Map[cell].Overlapper); xindex++) { 274 if (Map[cell].Overlapper[xindex] != NULL) { 275 obj[count++] = Map[cell].Overlapper[xindex]; 276 } 277 } 278 279 BuildingClass * bldg = NULL; 280 for (int i = 0; i < count; i++) { 281 if (obj[i] && 282 Coord_Cell(obj[i]->Coord) == Nodes[index].Cell && 283 obj[i]->What_Am_I() == RTTI_BUILDING && 284 ((BuildingClass *)obj[i])->Class->Type == Nodes[index].Type) { 285 286 bldg = (BuildingClass *)obj[i]; 287 break; 288 } 289 } 290 291 return(bldg); 292 } 293 294 295 /*********************************************************************************************** 296 * BaseClass::Is_Node -- Tells if the given building is part of our base list * 297 * * 298 * INPUT: * 299 * obj pointer to building to test * 300 * * 301 * OUTPUT: * 302 * true = building is a node in the list, false = isn't * 303 * * 304 * WARNINGS: * 305 * none. * 306 * * 307 * HISTORY: * 308 * 03/24/1995 BRR : Created. * 309 *=============================================================================================*/ 310 bool BaseClass::Is_Node(BuildingClass const * obj) 311 { 312 if (Get_Node(obj) != NULL) { 313 return(true); 314 } else { 315 return(false); 316 } 317 } 318 319 320 /*********************************************************************************************** 321 * BaseClass::Get_Node -- Returns ptr to the node corresponding to given object * 322 * * 323 * INPUT: * 324 * obj pointer to building to test * 325 * * 326 * OUTPUT: * 327 * ptr to node * 328 * * 329 * WARNINGS: * 330 * none. * 331 * * 332 * HISTORY: * 333 * 03/24/1995 BRR : Created. * 334 *=============================================================================================*/ 335 BaseNodeClass * BaseClass::Get_Node(BuildingClass const * obj) 336 { 337 for (int i = 0; i < Nodes.Count(); i++) { 338 if (obj->Class->Type == Nodes[i].Type && Coord_Cell(obj->Coord) == Nodes[i].Cell) { 339 return(&Nodes[i]); 340 } 341 } 342 return(NULL); 343 } 344 345 346 /*********************************************************************************************** 347 * BaseClass::Get_Node -- Finds the node that matches the cell specified. * 348 * * 349 * This routine is used to find a matching node the corresponds to the cell specified. * 350 * * 351 * INPUT: cell -- The cell to use in finding a match. * 352 * * 353 * OUTPUT: Returns a pointer to the matching node if found. If not found, then NULL is * 354 * returned. * 355 * * 356 * WARNINGS: none * 357 * * 358 * HISTORY: * 359 * 03/12/1996 JLB : Created. * 360 *=============================================================================================*/ 361 BaseNodeClass * BaseClass::Get_Node(CELL cell) 362 { 363 for (int index = 0; index < Nodes.Count(); index++) { 364 if (cell == Nodes[index].Cell) { 365 return(&Nodes[index]); 366 } 367 } 368 return(NULL); 369 } 370 371 372 /*********************************************************************************************** 373 * BaseClass::Next_Buildable -- returns ptr to the next node that needs to be built * 374 * * 375 * If 'type' is not NONE, returns ptr to the next "hole" in the list of the given type. * 376 * Otherwise, returns ptr to the next hole in the list of any type. * 377 * * 378 * INPUT: * 379 * type type of building to check for * 380 * * 381 * OUTPUT: * 382 * ptr to a BaseNodeClass, NULL if none * 383 * * 384 * WARNINGS: * 385 * none. * 386 * * 387 * HISTORY: * 388 * 03/24/1995 BRR : Created. * 389 *=============================================================================================*/ 390 BaseNodeClass * BaseClass::Next_Buildable(StructType type) 391 { 392 /* 393 ** Loop through all node entries, returning a pointer to the first 394 ** un-built one that matches the requested type. 395 */ 396 for (int i = 0; i < Nodes.Count(); i++) { 397 398 /* 399 ** For STRUCT_NONE, return the first hole found 400 */ 401 if (type == STRUCT_NONE) { 402 if (!Is_Built(i)) { 403 return(&Nodes[i]); 404 } 405 406 } else { 407 408 /* 409 ** For a "real" building type, return the first hold for that type 410 */ 411 if (Nodes[i].Type==type && !Is_Built(i)) { 412 return(&Nodes[i]); 413 } 414 } 415 } 416 417 418 // If no entry could be found, then create a fake one that will allow 419 // placement of the building. Make it static and reuse the next time this 420 // routine is called. 421 422 return(NULL); 423 } 424 425 426 /*********************************************************************************************** 427 * BaseClass::Read_INI -- INI reading routine * 428 * * 429 * INI entry format: * 430 * BLDG=COORDINATE * 431 * BLDG=COORDINATE * 432 * ... * 433 * * 434 * INPUT: * 435 * buffer pointer to loaded INI file * 436 * * 437 * OUTPUT: * 438 * none. * 439 * * 440 * WARNINGS: * 441 * This routines assumes there is only one base defined for the scenario. * 442 * * 443 * HISTORY: * 444 * 03/24/1995 BRR : Created. * 445 * 02/20/1996 JLB : Fixed to know what house to build base from. * 446 *=============================================================================================*/ 447 void BaseClass::Read_INI(CCINIClass & ini) 448 { 449 char buf[128]; 450 char uname[10]; 451 BaseNodeClass node; // node to add to list 452 453 Mono_Clear_Screen(); 454 /* 455 ** First, determine the house of the human player, and set the Base's house 456 ** accordingly. 457 */ 458 House = ini.Get_HousesType(INI_Name(), "Player", PlayerPtr->Class->House); 459 460 /* 461 ** Read the number of buildings that will go into the base node list 462 */ 463 int count = ini.Get_Int(INI_Name(), "Count", 0); 464 465 /* 466 ** Read each entry in turn, in the same order they were written out. 467 */ 468 for (int i = 0; i < count; i++) { 469 470 /* 471 ** Get an INI entry 472 */ 473 sprintf(uname,"%03d",i); 474 ini.Get_String(INI_Name(), uname, NULL, buf, sizeof(buf)); 475 476 /* 477 ** Set the node's building type 478 */ 479 node.Type = BuildingTypeClass::From_Name(strtok(buf,",")); 480 481 /* 482 ** Read & set the node's coordinate 483 */ 484 node.Cell = atoi(strtok(NULL,",")); 485 486 /* 487 ** Add this node to the Base's list 488 */ 489 Nodes.Add(node); 490 } 491 } 492 493 494 /*********************************************************************************************** 495 * BaseClass::Write_INI -- Writes all the base information to the INI database. * 496 * * 497 * Use this routine to write all prebuild base information to the INI database specified. * 498 * * 499 * INPUT: ini -- Reference to the INI database to store the data to. * 500 * * 501 * OUTPUT: none * 502 * * 503 * WARNINGS: If there was any preexisting prebuild base data in the database, it will be * 504 * be erased by this routine. * 505 * * 506 * HISTORY: * 507 * 07/30/1996 JLB : Created. * 508 *=============================================================================================*/ 509 void BaseClass::Write_INI(CCINIClass & ini) 510 { 511 /* 512 ** Clear out all existing base data from the ini file. 513 */ 514 ini.Clear(INI_Name()); 515 516 if (House != HOUSE_NONE) { 517 518 /* 519 ** Write out the owner of this buildable list. 520 */ 521 ini.Put_HousesType(INI_Name(), "Player", House); 522 523 /* 524 ** Save the # of buildings in the Nodes list. This is essential because 525 ** they must be read in the same order they were created, so "000" must be 526 ** read first, etc. 527 */ 528 ini.Put_Int(INI_Name(), "Count", Nodes.Count()); 529 530 /* 531 ** Write each entry into the INI 532 */ 533 for (int i = 0; i < Nodes.Count(); i++) { 534 char buf[128]; 535 char uname[10]; 536 537 sprintf(uname,"%03d",i); 538 sprintf(buf,"%s,%d", 539 BuildingTypeClass::As_Reference(Nodes[i].Type).IniName, 540 Nodes[i].Cell); 541 542 ini.Put_String(INI_Name(), uname, buf); 543 } 544 } 545 }