the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 715 lines 24 kB view raw
1#include "stdafx.h" 2 3#include <unordered_set> 4 5#include "..\..\..\Minecraft.World\StringHelpers.h" 6#include "..\..\..\Minecraft.World\Pos.h" 7#include "..\..\..\Minecraft.World\net.minecraft.world.phys.h" 8#include "..\..\..\Minecraft.World\net.minecraft.world.level.h" 9#include "..\..\..\Minecraft.World\net.minecraft.world.level.chunk.h" 10#include "Common\DLC\DLCGameRulesHeader.h" 11#include "..\..\StringTable.h" 12#include "LevelGenerationOptions.h" 13#include "ConsoleGameRules.h" 14 15JustGrSource::JustGrSource() 16{ 17 m_displayName = L"Default_DisplayName"; 18 m_worldName= L"Default_WorldName"; 19 m_defaultSaveName = L"Default_DefaultSaveName"; 20 m_bRequiresTexturePack = false; 21 m_requiredTexturePackId = 0; 22 m_grfPath = L"__NO_GRF_PATH__"; 23 m_bRequiresBaseSave = false; 24} 25 26bool JustGrSource::requiresTexturePack() {return m_bRequiresTexturePack;} 27UINT JustGrSource::getRequiredTexturePackId() {return m_requiredTexturePackId;} 28wstring JustGrSource::getDefaultSaveName() {return m_defaultSaveName;} 29LPCWSTR JustGrSource::getWorldName() {return m_worldName.c_str();} 30LPCWSTR JustGrSource::getDisplayName() {return m_displayName.c_str();} 31wstring JustGrSource::getGrfPath() {return m_grfPath;} 32bool JustGrSource::requiresBaseSave() { return m_bRequiresBaseSave; }; 33wstring JustGrSource::getBaseSavePath() { return m_baseSavePath; }; 34 35void JustGrSource::setRequiresTexturePack(bool x) {m_bRequiresTexturePack = x;} 36void JustGrSource::setRequiredTexturePackId(UINT x) {m_requiredTexturePackId = x;} 37void JustGrSource::setDefaultSaveName(const wstring &x) {m_defaultSaveName = x;} 38void JustGrSource::setWorldName(const wstring &x) {m_worldName = x;} 39void JustGrSource::setDisplayName(const wstring &x) {m_displayName = x;} 40void JustGrSource::setGrfPath(const wstring &x) {m_grfPath = x;} 41void JustGrSource::setBaseSavePath(const wstring &x) { m_baseSavePath = x; m_bRequiresBaseSave = true; } 42 43bool JustGrSource::ready() { return true; } 44 45LevelGenerationOptions::LevelGenerationOptions(DLCPack *parentPack) 46{ 47 m_spawnPos = NULL; 48 m_stringTable = NULL; 49 50 m_hasLoadedData = false; 51 52 m_seed = 0; 53 m_bHasBeenInCreative = true; 54 m_useFlatWorld = false; 55 m_bHaveMinY = false; 56 m_minY = INT_MAX; 57 m_bRequiresGameRules = false; 58 59 m_pbBaseSaveData = NULL; 60 m_dwBaseSaveSize = 0; 61 62 m_parentDLCPack = parentPack; 63 m_bLoadingData = false; 64} 65 66LevelGenerationOptions::~LevelGenerationOptions() 67{ 68 clearSchematics(); 69 if(m_spawnPos != NULL) delete m_spawnPos; 70 for(AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end(); ++it) 71 { 72 delete *it; 73 } 74 for(AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end(); ++it) 75 { 76 delete *it; 77 } 78 79 for(AUTO_VAR(it, m_biomeOverrides.begin()); it != m_biomeOverrides.end(); ++it) 80 { 81 delete *it; 82 } 83 84 for(AUTO_VAR(it, m_features.begin()); it != m_features.end(); ++it) 85 { 86 delete *it; 87 } 88 89 if (m_stringTable) 90 if (!isTutorial()) 91 delete m_stringTable; 92 93 if (isFromSave()) delete m_pSrc; 94} 95 96ConsoleGameRules::EGameRuleType LevelGenerationOptions::getActionType() { return ConsoleGameRules::eGameRuleType_LevelGenerationOptions; } 97 98void LevelGenerationOptions::writeAttributes(DataOutputStream *dos, UINT numAttrs) 99{ 100 GameRuleDefinition::writeAttributes(dos, numAttrs + 5); 101 102 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnX); 103 dos->writeUTF(_toString(m_spawnPos->x)); 104 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnY); 105 dos->writeUTF(_toString(m_spawnPos->y)); 106 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnZ); 107 dos->writeUTF(_toString(m_spawnPos->z)); 108 109 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_seed); 110 dos->writeUTF(_toString(m_seed)); 111 ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_flatworld); 112 dos->writeUTF(_toString(m_useFlatWorld)); 113} 114 115void LevelGenerationOptions::getChildren(vector<GameRuleDefinition *> *children) 116{ 117 GameRuleDefinition::getChildren(children); 118 119 vector<ApplySchematicRuleDefinition *> used_schematics; 120 for (AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end(); it++) 121 if ( !(*it)->isComplete() ) 122 used_schematics.push_back( *it ); 123 124 for(AUTO_VAR(it, m_structureRules.begin()); it!=m_structureRules.end(); it++) 125 children->push_back( *it ); 126 for(AUTO_VAR(it, used_schematics.begin()); it!=used_schematics.end(); it++) 127 children->push_back( *it ); 128 for(AUTO_VAR(it, m_biomeOverrides.begin()); it != m_biomeOverrides.end(); ++it) 129 children->push_back( *it ); 130 for(AUTO_VAR(it, m_features.begin()); it != m_features.end(); ++it) 131 children->push_back( *it ); 132} 133 134GameRuleDefinition *LevelGenerationOptions::addChild(ConsoleGameRules::EGameRuleType ruleType) 135{ 136 GameRuleDefinition *rule = NULL; 137 if(ruleType == ConsoleGameRules::eGameRuleType_ApplySchematic) 138 { 139 rule = new ApplySchematicRuleDefinition(this); 140 m_schematicRules.push_back((ApplySchematicRuleDefinition *)rule); 141 } 142 else if(ruleType == ConsoleGameRules::eGameRuleType_GenerateStructure) 143 { 144 rule = new ConsoleGenerateStructure(); 145 m_structureRules.push_back((ConsoleGenerateStructure *)rule); 146 } 147 else if(ruleType == ConsoleGameRules::eGameRuleType_BiomeOverride) 148 { 149 rule = new BiomeOverride(); 150 m_biomeOverrides.push_back((BiomeOverride *)rule); 151 } 152 else if(ruleType == ConsoleGameRules::eGameRuleType_StartFeature) 153 { 154 rule = new StartFeature(); 155 m_features.push_back((StartFeature *)rule); 156 } 157 else 158 { 159#ifndef _CONTENT_PACKAGE 160 wprintf(L"LevelGenerationOptions: Attempted to add invalid child rule - %d\n", ruleType ); 161#endif 162 } 163 return rule; 164} 165 166void LevelGenerationOptions::addAttribute(const wstring &attributeName, const wstring &attributeValue) 167{ 168 if(attributeName.compare(L"seed") == 0) 169 { 170 m_seed = _fromString<__int64>(attributeValue); 171 app.DebugPrintf("LevelGenerationOptions: Adding parameter m_seed=%I64d\n",m_seed); 172 } 173 else if(attributeName.compare(L"spawnX") == 0) 174 { 175 if(m_spawnPos == NULL) m_spawnPos = new Pos(); 176 int value = _fromString<int>(attributeValue); 177 m_spawnPos->x = value; 178 app.DebugPrintf("LevelGenerationOptions: Adding parameter spawnX=%d\n",value); 179 } 180 else if(attributeName.compare(L"spawnY") == 0) 181 { 182 if(m_spawnPos == NULL) m_spawnPos = new Pos(); 183 int value = _fromString<int>(attributeValue); 184 m_spawnPos->y = value; 185 app.DebugPrintf("LevelGenerationOptions: Adding parameter spawnY=%d\n",value); 186 } 187 else if(attributeName.compare(L"spawnZ") == 0) 188 { 189 if(m_spawnPos == NULL) m_spawnPos = new Pos(); 190 int value = _fromString<int>(attributeValue); 191 m_spawnPos->z = value; 192 app.DebugPrintf("LevelGenerationOptions: Adding parameter spawnZ=%d\n",value); 193 } 194 else if(attributeName.compare(L"flatworld") == 0) 195 { 196 if(attributeValue.compare(L"true") == 0) m_useFlatWorld = true; 197 app.DebugPrintf("LevelGenerationOptions: Adding parameter flatworld=%s\n",m_useFlatWorld?"TRUE":"FALSE"); 198 } 199 else if(attributeName.compare(L"saveName") == 0) 200 { 201 wstring string(attributeValue); 202 if(!string.empty()) setDefaultSaveName( string ); 203 else setDefaultSaveName( attributeValue ); 204 app.DebugPrintf("LevelGenerationOptions: Adding parameter saveName=%ls\n", getDefaultSaveName().c_str()); 205 } 206 else if(attributeName.compare(L"worldName") == 0) 207 { 208 wstring string(attributeValue); 209 if(!string.empty()) setWorldName( string ); 210 else setWorldName( attributeValue ); 211 app.DebugPrintf("LevelGenerationOptions: Adding parameter worldName=%ls\n", getWorldName()); 212 } 213 else if(attributeName.compare(L"displayName") == 0) 214 { 215 wstring string(attributeValue); 216 if(!string.empty()) setDisplayName( string ); 217 else setDisplayName( attributeValue ); 218 app.DebugPrintf("LevelGenerationOptions: Adding parameter displayName=%ls\n", getDisplayName()); 219 } 220 else if(attributeName.compare(L"texturePackId") == 0) 221 { 222 setRequiredTexturePackId( _fromString<unsigned int>(attributeValue) ); 223 setRequiresTexturePack( true ); 224 app.DebugPrintf("LevelGenerationOptions: Adding parameter texturePackId=%0x\n", getRequiredTexturePackId()); 225 } 226 else if(attributeName.compare(L"isTutorial") == 0) 227 { 228 if(attributeValue.compare(L"true") == 0) setSrc(eSrc_tutorial); 229 app.DebugPrintf("LevelGenerationOptions: Adding parameter isTutorial=%s\n",isTutorial()?"TRUE":"FALSE"); 230 } 231 else if(attributeName.compare(L"baseSaveName") == 0) 232 { 233 setBaseSavePath( attributeValue ); 234 app.DebugPrintf("LevelGenerationOptions: Adding parameter baseSaveName=%ls\n", getBaseSavePath().c_str()); 235 } 236 else if(attributeName.compare(L"hasBeenInCreative") == 0) 237 { 238 bool value = _fromString<bool>(attributeValue); 239 m_bHasBeenInCreative = value; 240 app.DebugPrintf("LevelGenerationOptions: Adding parameter gameMode=%d\n", m_bHasBeenInCreative); 241 } 242 else 243 { 244 GameRuleDefinition::addAttribute(attributeName, attributeValue); 245 } 246} 247 248void LevelGenerationOptions::processSchematics(LevelChunk *chunk) 249{ 250 PIXBeginNamedEvent(0,"Processing schematics for chunk (%d,%d)", chunk->x, chunk->z); 251 AABB *chunkBox = AABB::newTemp(chunk->x*16,0,chunk->z*16,chunk->x*16 + 16,Level::maxBuildHeight,chunk->z*16 + 16); 252 for( AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end();++it) 253 { 254 ApplySchematicRuleDefinition *rule = *it; 255 rule->processSchematic(chunkBox, chunk); 256 } 257 258 int cx = (chunk->x << 4); 259 int cz = (chunk->z << 4); 260 261 for( AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end(); it++ ) 262 { 263 ConsoleGenerateStructure *structureStart = *it; 264 265 if (structureStart->getBoundingBox()->intersects(cx, cz, cx + 15, cz + 15)) 266 { 267 BoundingBox *bb = new BoundingBox(cx, cz, cx + 15, cz + 15); 268 structureStart->postProcess(chunk->level, NULL, bb); 269 delete bb; 270 } 271 } 272 PIXEndNamedEvent(); 273} 274 275void LevelGenerationOptions::processSchematicsLighting(LevelChunk *chunk) 276{ 277 PIXBeginNamedEvent(0,"Processing schematics (lighting) for chunk (%d,%d)", chunk->x, chunk->z); 278 AABB *chunkBox = AABB::newTemp(chunk->x*16,0,chunk->z*16,chunk->x*16 + 16,Level::maxBuildHeight,chunk->z*16 + 16); 279 for( AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end();++it) 280 { 281 ApplySchematicRuleDefinition *rule = *it; 282 rule->processSchematicLighting(chunkBox, chunk); 283 } 284 PIXEndNamedEvent(); 285} 286 287bool LevelGenerationOptions::checkIntersects(int x0, int y0, int z0, int x1, int y1, int z1) 288{ 289 PIXBeginNamedEvent(0,"Check Intersects"); 290 291 // As an optimisation, we can quickly discard things below a certain y which makes most ore checks faster due to 292 // a) ores generally being below ground/sea level and b) tutorial world additions generally being above ground/sea level 293 if(!m_bHaveMinY) 294 { 295 for(AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end();++it) 296 { 297 ApplySchematicRuleDefinition *rule = *it; 298 int minY = rule->getMinY(); 299 if(minY < m_minY) m_minY = minY; 300 } 301 302 for( AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end(); it++ ) 303 { 304 ConsoleGenerateStructure *structureStart = *it; 305 int minY = structureStart->getMinY(); 306 if(minY < m_minY) m_minY = minY; 307 } 308 309 m_bHaveMinY = true; 310 } 311 312 // 4J Stu - We DO NOT intersect if our upper bound is below the lower bound for all schematics 313 if( y1 < m_minY ) return false; 314 315 bool intersects = false; 316 for(AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end();++it) 317 { 318 ApplySchematicRuleDefinition *rule = *it; 319 intersects = rule->checkIntersects(x0,y0,z0,x1,y1,z1); 320 if(intersects) break; 321 } 322 323 if(!intersects) 324 { 325 for( AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end(); it++ ) 326 { 327 ConsoleGenerateStructure *structureStart = *it; 328 intersects = structureStart->checkIntersects(x0,y0,z0,x1,y1,z1); 329 if(intersects) break; 330 } 331 } 332 PIXEndNamedEvent(); 333 return intersects; 334} 335 336void LevelGenerationOptions::clearSchematics() 337{ 338 for(AUTO_VAR(it, m_schematics.begin()); it != m_schematics.end(); ++it) 339 { 340 delete it->second; 341 } 342 m_schematics.clear(); 343} 344 345ConsoleSchematicFile *LevelGenerationOptions::loadSchematicFile(const wstring &filename, PBYTE pbData, DWORD dwLen) 346{ 347 // If we have already loaded this, just return 348 AUTO_VAR(it, m_schematics.find(filename)); 349 if(it != m_schematics.end()) 350 { 351#ifndef _CONTENT_PACKAGE 352 wprintf(L"We have already loaded schematic file %ls\n", filename.c_str() ); 353#endif 354 it->second->incrementRefCount(); 355 return it->second; 356 } 357 358 ConsoleSchematicFile *schematic = NULL; 359 byteArray data(pbData,dwLen); 360 ByteArrayInputStream bais(data); 361 DataInputStream dis(&bais); 362 schematic = new ConsoleSchematicFile(); 363 schematic->load(&dis); 364 m_schematics[filename] = schematic; 365 bais.reset(); 366 return schematic; 367} 368 369ConsoleSchematicFile *LevelGenerationOptions::getSchematicFile(const wstring &filename) 370{ 371 ConsoleSchematicFile *schematic = NULL; 372 // If we have already loaded this, just return 373 AUTO_VAR(it, m_schematics.find(filename)); 374 if(it != m_schematics.end()) 375 { 376 schematic = it->second; 377 } 378 return schematic; 379} 380 381void LevelGenerationOptions::releaseSchematicFile(const wstring &filename) 382{ 383 // 4J Stu - We don't want to delete them when done, but probably want to keep a set of active schematics for the current world 384 //AUTO_VAR(it, m_schematics.find(filename)); 385 //if(it != m_schematics.end()) 386 //{ 387 // ConsoleSchematicFile *schematic = it->second; 388 // schematic->decrementRefCount(); 389 // if(schematic->shouldDelete()) 390 // { 391 // delete schematic; 392 // m_schematics.erase(it); 393 // } 394 //} 395} 396 397void LevelGenerationOptions::loadStringTable(StringTable *table) 398{ 399 m_stringTable = table; 400} 401 402LPCWSTR LevelGenerationOptions::getString(const wstring &key) 403{ 404 if(m_stringTable == NULL) 405 { 406 return L""; 407 } 408 else 409 { 410 return m_stringTable->getString(key); 411 } 412} 413 414void LevelGenerationOptions::getBiomeOverride(int biomeId, BYTE &tile, BYTE &topTile) 415{ 416 for(AUTO_VAR(it, m_biomeOverrides.begin()); it != m_biomeOverrides.end(); ++it) 417 { 418 BiomeOverride *bo = *it; 419 if(bo->isBiome(biomeId)) 420 { 421 bo->getTileValues(tile,topTile); 422 break; 423 } 424 } 425} 426 427bool LevelGenerationOptions::isFeatureChunk(int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature, int *orientation) 428{ 429 bool isFeature = false; 430 431 for(AUTO_VAR(it, m_features.begin()); it != m_features.end(); ++it) 432 { 433 StartFeature *sf = *it; 434 if(sf->isFeatureChunk(chunkX, chunkZ, feature, orientation)) 435 { 436 isFeature = true; 437 break; 438 } 439 } 440 return isFeature; 441} 442 443unordered_map<wstring, ConsoleSchematicFile *> *LevelGenerationOptions::getUnfinishedSchematicFiles() 444{ 445 // Clean schematic rules. 446 unordered_set<wstring> usedFiles = unordered_set<wstring>(); 447 for (AUTO_VAR(it, m_schematicRules.begin()); it!=m_schematicRules.end(); it++) 448 if ( !(*it)->isComplete() ) 449 usedFiles.insert( (*it)->getSchematicName() ); 450 451 // Clean schematic files. 452 unordered_map<wstring, ConsoleSchematicFile *> *out 453 = new unordered_map<wstring, ConsoleSchematicFile *>(); 454 for (AUTO_VAR(it, usedFiles.begin()); it!=usedFiles.end(); it++) 455 out->insert( pair<wstring, ConsoleSchematicFile *>(*it, getSchematicFile(*it)) ); 456 457 return out; 458} 459 460void LevelGenerationOptions::loadBaseSaveData() 461{ 462 int mountIndex = -1; 463 if(m_parentDLCPack != NULL) mountIndex = m_parentDLCPack->GetDLCMountIndex(); 464 465 if(mountIndex > -1) 466 { 467#ifdef _DURANGO 468 if(StorageManager.MountInstalledDLC(ProfileManager.GetPrimaryPad(),mountIndex,&LevelGenerationOptions::packMounted,this,L"WPACK")!=ERROR_IO_PENDING) 469#else 470 if(StorageManager.MountInstalledDLC(ProfileManager.GetPrimaryPad(),mountIndex,&LevelGenerationOptions::packMounted,this,"WPACK")!=ERROR_IO_PENDING) 471#endif 472 { 473 // corrupt DLC 474 setLoadedData(); 475 app.DebugPrintf("Failed to mount LGO DLC %d for pad %d\n",mountIndex,ProfileManager.GetPrimaryPad()); 476 } 477 else 478 { 479 m_bLoadingData = true; 480 app.DebugPrintf("Attempted to mount DLC data for LGO %d\n", mountIndex); 481 } 482 } 483 else 484 { 485 setLoadedData(); 486 app.SetAction(ProfileManager.GetPrimaryPad(), eAppAction_ReloadTexturePack); 487 } 488} 489 490int LevelGenerationOptions::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicenceMask) 491{ 492 LevelGenerationOptions *lgo = (LevelGenerationOptions *)pParam; 493 lgo->m_bLoadingData = false; 494 if(dwErr!=ERROR_SUCCESS) 495 { 496 // corrupt DLC 497 app.DebugPrintf("Failed to mount LGO DLC for pad %d: %d\n",iPad,dwErr); 498 } 499 else 500 { 501 app.DebugPrintf("Mounted DLC for LGO, attempting to load data\n"); 502 DWORD dwFilesProcessed = 0; 503 int gameRulesCount = lgo->m_parentDLCPack->getDLCItemsCount(DLCManager::e_DLCType_GameRulesHeader); 504 for(int i = 0; i < gameRulesCount; ++i) 505 { 506 DLCGameRulesHeader *dlcFile = (DLCGameRulesHeader *) lgo->m_parentDLCPack->getFile(DLCManager::e_DLCType_GameRulesHeader, i); 507 508 if (!dlcFile->getGrfPath().empty()) 509 { 510 File grf( app.getFilePath(lgo->m_parentDLCPack->GetPackID(), dlcFile->getGrfPath(),true, L"WPACK:" ) ); 511 if (grf.exists()) 512 { 513#ifdef _UNICODE 514 wstring path = grf.getPath(); 515 const WCHAR *pchFilename=path.c_str(); 516 HANDLE fileHandle = CreateFile( 517 pchFilename, // file name 518 GENERIC_READ, // access mode 519 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... 520 NULL, // Unused 521 OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it 522 FILE_FLAG_SEQUENTIAL_SCAN, // file attributes 523 NULL // Unsupported 524 ); 525#else 526 const char *pchFilename=wstringtofilename(grf.getPath()); 527 HANDLE fileHandle = CreateFile( 528 pchFilename, // file name 529 GENERIC_READ, // access mode 530 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... 531 NULL, // Unused 532 OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it 533 FILE_FLAG_SEQUENTIAL_SCAN, // file attributes 534 NULL // Unsupported 535 ); 536#endif 537 538 if( fileHandle != INVALID_HANDLE_VALUE ) 539 { 540 DWORD dwFileSize = grf.length(); 541 DWORD bytesRead; 542 PBYTE pbData = (PBYTE) new BYTE[dwFileSize]; 543 BOOL bSuccess = ReadFile(fileHandle,pbData,dwFileSize,&bytesRead,NULL); 544 if(bSuccess==FALSE) 545 { 546 app.FatalLoadError(); 547 } 548 CloseHandle(fileHandle); 549 550 // 4J-PB - is it possible that we can get here after a read fail and it's not an error? 551 dlcFile->setGrfData(pbData, dwFileSize, lgo->m_stringTable); 552 553 delete [] pbData; 554 555 app.m_gameRules.setLevelGenerationOptions( dlcFile->lgo ); 556 } 557 } 558 } 559 } 560 if(lgo->requiresBaseSave() && !lgo->getBaseSavePath().empty() ) 561 { 562 File save(app.getFilePath(lgo->m_parentDLCPack->GetPackID(), lgo->getBaseSavePath(),true, L"WPACK:" )); 563 if (save.exists()) 564 { 565#ifdef _UNICODE 566 wstring path = save.getPath(); 567 const WCHAR *pchFilename=path.c_str(); 568 HANDLE fileHandle = CreateFile( 569 pchFilename, // file name 570 GENERIC_READ, // access mode 571 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... 572 NULL, // Unused 573 OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it 574 FILE_FLAG_SEQUENTIAL_SCAN, // file attributes 575 NULL // Unsupported 576 ); 577#else 578 const char *pchFilename=wstringtofilename(save.getPath()); 579 HANDLE fileHandle = CreateFile( 580 pchFilename, // file name 581 GENERIC_READ, // access mode 582 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... 583 NULL, // Unused 584 OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it 585 FILE_FLAG_SEQUENTIAL_SCAN, // file attributes 586 NULL // Unsupported 587 ); 588#endif 589 590 if( fileHandle != INVALID_HANDLE_VALUE ) 591 { 592 DWORD bytesRead,dwFileSize = GetFileSize(fileHandle,NULL); 593 PBYTE pbData = (PBYTE) new BYTE[dwFileSize]; 594 BOOL bSuccess = ReadFile(fileHandle,pbData,dwFileSize,&bytesRead,NULL); 595 if(bSuccess==FALSE) 596 { 597 app.FatalLoadError(); 598 } 599 CloseHandle(fileHandle); 600 601 // 4J-PB - is it possible that we can get here after a read fail and it's not an error? 602 lgo->setBaseSaveData(pbData, dwFileSize); 603 } 604 } 605 606 } 607#ifdef _DURANGO 608 DWORD result = StorageManager.UnmountInstalledDLC(L"WPACK"); 609#else 610 DWORD result = StorageManager.UnmountInstalledDLC("WPACK"); 611#endif 612 613 } 614 615 lgo->setLoadedData(); 616 617 return 0; 618} 619 620void LevelGenerationOptions::reset_start() 621{ 622 for ( AUTO_VAR( it, m_schematicRules.begin()); 623 it != m_schematicRules.end(); 624 it++ ) 625 { 626 (*it)->reset(); 627 } 628} 629 630void LevelGenerationOptions::reset_finish() 631{ 632 //if (m_spawnPos) { delete m_spawnPos; m_spawnPos = NULL; } 633 //if (m_stringTable) { delete m_stringTable; m_stringTable = NULL; } 634 635 if (isFromDLC()) 636 { 637 m_hasLoadedData = false; 638 } 639} 640 641 642GrSource *LevelGenerationOptions::info() { return m_pSrc; } 643void LevelGenerationOptions::setSrc(eSrc src) { m_src = src; } 644LevelGenerationOptions::eSrc LevelGenerationOptions::getSrc() { return m_src; } 645 646bool LevelGenerationOptions::isTutorial() { return getSrc() == eSrc_tutorial; } 647bool LevelGenerationOptions::isFromSave() { return getSrc() == eSrc_fromSave; } 648bool LevelGenerationOptions::isFromDLC() { return getSrc() == eSrc_fromDLC; } 649 650bool LevelGenerationOptions::requiresTexturePack() { return info()->requiresTexturePack(); } 651UINT LevelGenerationOptions::getRequiredTexturePackId() { return info()->getRequiredTexturePackId(); } 652 653wstring LevelGenerationOptions::getDefaultSaveName() 654{ 655 switch (getSrc()) 656 { 657 case eSrc_fromSave: return getString( info()->getDefaultSaveName() ); 658 case eSrc_fromDLC: return getString( info()->getDefaultSaveName() ); 659 case eSrc_tutorial: return app.GetString(IDS_TUTORIALSAVENAME); 660 } 661 return L""; 662} 663LPCWSTR LevelGenerationOptions::getWorldName() 664{ 665 switch (getSrc()) 666 { 667 case eSrc_fromSave: return getString( info()->getWorldName() ); 668 case eSrc_fromDLC: return getString( info()->getWorldName() ); 669 case eSrc_tutorial: return app.GetString(IDS_PLAY_TUTORIAL); 670 } 671 return L""; 672} 673LPCWSTR LevelGenerationOptions::getDisplayName() 674{ 675 switch (getSrc()) 676 { 677 case eSrc_fromSave: return getString( info()->getDisplayName() ); 678 case eSrc_fromDLC: return getString( info()->getDisplayName() ); 679 case eSrc_tutorial: return L""; 680 } 681 return L""; 682} 683 684wstring LevelGenerationOptions::getGrfPath() { return info()->getGrfPath(); } 685bool LevelGenerationOptions::requiresBaseSave() { return info()->requiresBaseSave(); } 686wstring LevelGenerationOptions::getBaseSavePath() { return info()->getBaseSavePath(); } 687 688void LevelGenerationOptions::setGrSource(GrSource *grs) { m_pSrc = grs; } 689 690void LevelGenerationOptions::setRequiresTexturePack(bool x) { info()->setRequiresTexturePack(x); } 691void LevelGenerationOptions::setRequiredTexturePackId(UINT x) { info()->setRequiredTexturePackId(x); } 692void LevelGenerationOptions::setDefaultSaveName(const wstring &x) { info()->setDefaultSaveName(x); } 693void LevelGenerationOptions::setWorldName(const wstring &x) { info()->setWorldName(x); } 694void LevelGenerationOptions::setDisplayName(const wstring &x) { info()->setDisplayName(x); } 695void LevelGenerationOptions::setGrfPath(const wstring &x) { info()->setGrfPath(x); } 696void LevelGenerationOptions::setBaseSavePath(const wstring &x) { info()->setBaseSavePath(x); } 697 698bool LevelGenerationOptions::ready() { return info()->ready(); } 699 700void LevelGenerationOptions::setBaseSaveData(PBYTE pbData, DWORD dwSize) { m_pbBaseSaveData = pbData; m_dwBaseSaveSize = dwSize; } 701PBYTE LevelGenerationOptions::getBaseSaveData(DWORD &size) { size = m_dwBaseSaveSize; return m_pbBaseSaveData; } 702bool LevelGenerationOptions::hasBaseSaveData() { return m_dwBaseSaveSize > 0 && m_pbBaseSaveData != NULL; } 703void LevelGenerationOptions::deleteBaseSaveData() { if(m_pbBaseSaveData) delete m_pbBaseSaveData; m_pbBaseSaveData = NULL; m_dwBaseSaveSize = 0; } 704 705bool LevelGenerationOptions::hasLoadedData() { return m_hasLoadedData; } 706void LevelGenerationOptions::setLoadedData() { m_hasLoadedData = true; } 707 708__int64 LevelGenerationOptions::getLevelSeed() { return m_seed; } 709int LevelGenerationOptions::getLevelHasBeenInCreative() { return m_bHasBeenInCreative; } 710Pos *LevelGenerationOptions::getSpawnPos() { return m_spawnPos; } 711bool LevelGenerationOptions::getuseFlatWorld() { return m_useFlatWorld; } 712 713bool LevelGenerationOptions::requiresGameRules() { return m_bRequiresGameRules; } 714void LevelGenerationOptions::setRequiredGameRules(LevelRuleset *rules) { m_requiredGameRules = rules; m_bRequiresGameRules = true; } 715LevelRuleset *LevelGenerationOptions::getRequiredGameRules() { return m_requiredGameRules; }