From b3feddfef372618c8a9d7a0abcaf18cfad866c18 Mon Sep 17 00:00:00 2001 From: daoge <3523206925@qq.com> Date: Tue, 3 Mar 2026 03:04:10 +0800 Subject: feat: TU19 (Dec 2014) Features & Content (#155) * try to resolve merge conflict * feat: TU19 (Dec 2014) Features & Content (#32) * December 2014 files * Working release build * Fix compilation issues * Add sound to Windows64Media * Add DLC content and force Tutorial DLC * Revert "Add DLC content and force Tutorial DLC" This reverts commit 97a43994725008e35fceb984d5549df9c8cea470. * Disable broken light packing * Disable breakpoint during DLC texture map load Allows DLC loading but the DLC textures are still broken * Fix post build not working * ... * fix vs2022 build * fix cmake build --------- Co-authored-by: Loki --- .../Common/GameRules/ConsoleGenerateStructure.h | 4 + .../Common/GameRules/ConsoleSchematicFile.cpp | 16 +- .../Common/GameRules/GameRuleManager.cpp | 50 +++-- .../Common/GameRules/LevelGenerationOptions.cpp | 241 +++++++++++++++++++-- .../Common/GameRules/LevelGenerationOptions.h | 12 +- Minecraft.Client/Common/GameRules/StartFeature.cpp | 14 +- Minecraft.Client/Common/GameRules/StartFeature.h | 4 +- .../XboxStructureActionPlaceContainer.cpp | 6 +- .../GameRules/XboxStructureActionPlaceSpawner.cpp | 4 +- 9 files changed, 293 insertions(+), 58 deletions(-) (limited to 'Minecraft.Client/Common/GameRules') diff --git a/Minecraft.Client/Common/GameRules/ConsoleGenerateStructure.h b/Minecraft.Client/Common/GameRules/ConsoleGenerateStructure.h index 5b97b108..91c4ef35 100644 --- a/Minecraft.Client/Common/GameRules/ConsoleGenerateStructure.h +++ b/Minecraft.Client/Common/GameRules/ConsoleGenerateStructure.h @@ -35,4 +35,8 @@ public: bool checkIntersects(int x0, int y0, int z0, int x1, int y1, int z1); virtual int getMinY(); + + EStructurePiece GetType() { return (EStructurePiece)0; } + void addAdditonalSaveData(CompoundTag *tag) {} + void readAdditonalSaveData(CompoundTag *tag) {} }; \ No newline at end of file diff --git a/Minecraft.Client/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Common/GameRules/ConsoleSchematicFile.cpp index 4a4e27b2..3b995000 100644 --- a/Minecraft.Client/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Common/GameRules/ConsoleSchematicFile.cpp @@ -278,7 +278,7 @@ __int64 ConsoleSchematicFile::applyBlocksAndData(LevelChunk *chunk, AABB *chunkB //{ // if(blockData[i] == Tile::sand_Id || blockData[i] == Tile::sandStone_Id) // { - // blockData[i] = Tile::whiteStone_Id; + // blockData[i] = Tile::endStone_Id; // } //} @@ -706,15 +706,19 @@ void ConsoleSchematicFile::generateSchematicFile(DataOutputStream *dos, Level *l shared_ptr e = *it; bool mobCanBeSaved = false; - if(bSaveMobs) + if (bSaveMobs) { - if( ( e->GetType() & eTYPE_MONSTER ) || ( e->GetType() & eTYPE_WATERANIMAL ) || ( e->GetType() & eTYPE_ANIMAL ) || - ( e->GetType() == eTYPE_CHICKEN ) || ( e->GetType() == eTYPE_WOLF ) || ( e->GetType() == eTYPE_VILLAGER) || ( e->GetType() == eTYPE_MUSHROOMCOW ) ) + if ( e->instanceof(eTYPE_MONSTER) || e->instanceof(eTYPE_WATERANIMAL) || e->instanceof(eTYPE_ANIMAL) || (e->GetType() == eTYPE_VILLAGER) ) + + // 4J-JEV: All these are derived from eTYPE_ANIMAL and true implicitly. + //|| ( e->GetType() == eTYPE_CHICKEN ) || ( e->GetType() == eTYPE_WOLF ) || ( e->GetType() == eTYPE_MUSHROOMCOW ) ) { mobCanBeSaved = true; } } - if(mobCanBeSaved || e->GetType() == eTYPE_MINECART || e->GetType() == eTYPE_BOAT || e->GetType() == eTYPE_PAINTING || e->GetType() == eTYPE_ITEM_FRAME) + + // 4J-JEV: Changed to check for instances of minecarts and hangingEntities instead of just eTYPE_PAINTING, eTYPE_ITEM_FRAME and eTYPE_MINECART + if (mobCanBeSaved || e->instanceof(eTYPE_MINECART) || e->GetType() == eTYPE_BOAT || e->instanceof(eTYPE_HANGING_ENTITY)) { CompoundTag *eTag = new CompoundTag(); if( e->save(eTag) ) @@ -725,7 +729,7 @@ void ConsoleSchematicFile::generateSchematicFile(DataOutputStream *dos, Level *l pos->get(1)->data -= yStart; pos->get(2)->data -= zStart; - if( e->GetType() == eTYPE_PAINTING || e->GetType() == eTYPE_ITEM_FRAME ) + if( e->instanceof(eTYPE_HANGING_ENTITY) ) { ((IntTag *) eTag->get(L"TileX") )->data -= xStart; ((IntTag *) eTag->get(L"TileY") )->data -= yStart; diff --git a/Minecraft.Client/Common/GameRules/GameRuleManager.cpp b/Minecraft.Client/Common/GameRules/GameRuleManager.cpp index 0c6a7804..6e5688cc 100644 --- a/Minecraft.Client/Common/GameRules/GameRuleManager.cpp +++ b/Minecraft.Client/Common/GameRules/GameRuleManager.cpp @@ -106,17 +106,14 @@ void GameRuleManager::loadGameRules(DLCPack *pack) DWORD dSize; byte *dData = dlcHeader->getData(dSize); - LevelGenerationOptions *createdLevelGenerationOptions = new LevelGenerationOptions(); + LevelGenerationOptions *createdLevelGenerationOptions = new LevelGenerationOptions(pack); // = loadGameRules(dData, dSize); //, strings); createdLevelGenerationOptions->setGrSource( dlcHeader ); + createdLevelGenerationOptions->setSrc( LevelGenerationOptions::eSrc_fromDLC ); readRuleFile(createdLevelGenerationOptions, dData, dSize, strings); - createdLevelGenerationOptions->setSrc( LevelGenerationOptions::eSrc_fromDLC ); - - - //createdLevelGenerationOptions->setSrc( LevelGenerationOptions::eSrc_fromDLC ); dlcHeader->lgo = createdLevelGenerationOptions; } @@ -128,15 +125,13 @@ void GameRuleManager::loadGameRules(DLCPack *pack) DWORD dSize; byte *dData = dlcFile->getData(dSize); - LevelGenerationOptions *createdLevelGenerationOptions = new LevelGenerationOptions(); + LevelGenerationOptions *createdLevelGenerationOptions = new LevelGenerationOptions(pack); // = loadGameRules(dData, dSize); //, strings); createdLevelGenerationOptions->setGrSource( new JustGrSource() ); - readRuleFile(createdLevelGenerationOptions, dData, dSize, strings); - createdLevelGenerationOptions->setSrc( LevelGenerationOptions::eSrc_tutorial ); - - //createdLevelGenerationOptions->set_DLCGameRulesFile( dlcFile ); + + readRuleFile(createdLevelGenerationOptions, dData, dSize, strings); createdLevelGenerationOptions->setLoadedData(); } @@ -659,6 +654,25 @@ void GameRuleManager::loadDefaultGameRules() #else // _XBOX +#ifdef _WINDOWS64 + File packedTutorialFile(L"Windows64Media\\Tutorial\\Tutorial.pck"); + if(!packedTutorialFile.exists()) packedTutorialFile = File(L"Windows64\\Tutorial\\Tutorial.pck"); +#elif defined(__ORBIS__) + File packedTutorialFile(L"/app0/orbis/Tutorial/Tutorial.pck"); +#elif defined(__PSVITA__) + File packedTutorialFile(L"PSVita/Tutorial/Tutorial.pck"); +#elif defined(__PS3__) + File packedTutorialFile(L"PS3/Tutorial/Tutorial.pck"); +#else + File packedTutorialFile(L"Tutorial\\Tutorial.pck"); +#endif + if(loadGameRulesPack(&packedTutorialFile)) + { + m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(app.GetString(IDS_PLAY_TUTORIAL)); + //m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(L"Tutorial"); + m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME)); + } +#if 0 wstring fpTutorial = L"Tutorial.pck"; if(app.getArchiveFileSize(fpTutorial) >= 0) { @@ -667,25 +681,18 @@ void GameRuleManager::loadDefaultGameRules() if ( app.m_dlcManager.readDLCDataFile(dwFilesProcessed,fpTutorial,pack,true) ) { app.m_dlcManager.addPack(pack); - m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(app.GetString(IDS_PLAY_TUTORIAL)); - m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME)); + //m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(app.GetString(IDS_PLAY_TUTORIAL)); + //m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME)); } else delete pack; } - /*StringTable *strings = new StringTable(baStrings.data, baStrings.length); - LevelGenerationOptions *lgo = new LevelGenerationOptions(); - lgo->setGrSource( new JustGrSource() ); - lgo->setSrc( LevelGenerationOptions::eSrc_tutorial ); - readRuleFile(lgo, tutorial.data, tutorial.length, strings); - lgo->setLoadedData();*/ - +#endif #endif } bool GameRuleManager::loadGameRulesPack(File *path) { bool success = false; -#ifdef _XBOX if(path->exists()) { DLCPack *pack = new DLCPack(L"",0xffffffff); @@ -700,12 +707,13 @@ bool GameRuleManager::loadGameRulesPack(File *path) delete pack; } } -#endif return success; } void GameRuleManager::setLevelGenerationOptions(LevelGenerationOptions *levelGen) { + unloadCurrentGameRules(); + m_currentGameRuleDefinitions = NULL; m_currentLevelGenerationOptions = levelGen; diff --git a/Minecraft.Client/Common/GameRules/LevelGenerationOptions.cpp b/Minecraft.Client/Common/GameRules/LevelGenerationOptions.cpp index 717b066e..9ebd3428 100644 --- a/Minecraft.Client/Common/GameRules/LevelGenerationOptions.cpp +++ b/Minecraft.Client/Common/GameRules/LevelGenerationOptions.cpp @@ -7,6 +7,7 @@ #include "..\..\..\Minecraft.World\net.minecraft.world.phys.h" #include "..\..\..\Minecraft.World\net.minecraft.world.level.h" #include "..\..\..\Minecraft.World\net.minecraft.world.level.chunk.h" +#include "Common\DLC\DLCGameRulesHeader.h" #include "..\..\StringTable.h" #include "LevelGenerationOptions.h" #include "ConsoleGameRules.h" @@ -41,7 +42,7 @@ void JustGrSource::setBaseSavePath(const wstring &x) { m_baseSavePath = x; m_bRe bool JustGrSource::ready() { return true; } -LevelGenerationOptions::LevelGenerationOptions() +LevelGenerationOptions::LevelGenerationOptions(DLCPack *parentPack) { m_spawnPos = NULL; m_stringTable = NULL; @@ -49,6 +50,7 @@ LevelGenerationOptions::LevelGenerationOptions() m_hasLoadedData = false; m_seed = 0; + m_bHasBeenInCreative = true; m_useFlatWorld = false; m_bHaveMinY = false; m_minY = INT_MAX; @@ -56,6 +58,9 @@ LevelGenerationOptions::LevelGenerationOptions() m_pbBaseSaveData = NULL; m_dwBaseSaveSize = 0; + + m_parentDLCPack = parentPack; + m_bLoadingData = false; } LevelGenerationOptions::~LevelGenerationOptions() @@ -70,17 +75,17 @@ LevelGenerationOptions::~LevelGenerationOptions() { delete *it; } - + for(AUTO_VAR(it, m_biomeOverrides.begin()); it != m_biomeOverrides.end(); ++it) { delete *it; } - + for(AUTO_VAR(it, m_features.begin()); it != m_features.end(); ++it) { delete *it; } - + if (m_stringTable) if (!isTutorial()) delete m_stringTable; @@ -93,7 +98,7 @@ ConsoleGameRules::EGameRuleType LevelGenerationOptions::getActionType() { return void LevelGenerationOptions::writeAttributes(DataOutputStream *dos, UINT numAttrs) { GameRuleDefinition::writeAttributes(dos, numAttrs + 5); - + ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnX); dos->writeUTF(_toString(m_spawnPos->x)); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_spawnY); @@ -110,12 +115,12 @@ void LevelGenerationOptions::writeAttributes(DataOutputStream *dos, UINT numAttr void LevelGenerationOptions::getChildren(vector *children) { GameRuleDefinition::getChildren(children); - + vector used_schematics; for (AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end(); it++) if ( !(*it)->isComplete() ) used_schematics.push_back( *it ); - + for(AUTO_VAR(it, m_structureRules.begin()); it!=m_structureRules.end(); it++) children->push_back( *it ); for(AUTO_VAR(it, used_schematics.begin()); it!=used_schematics.end(); it++) @@ -190,24 +195,24 @@ void LevelGenerationOptions::addAttribute(const wstring &attributeName, const ws { if(attributeValue.compare(L"true") == 0) m_useFlatWorld = true; app.DebugPrintf("LevelGenerationOptions: Adding parameter flatworld=%s\n",m_useFlatWorld?"TRUE":"FALSE"); - } + } else if(attributeName.compare(L"saveName") == 0) { - wstring string(getString(attributeValue)); + wstring string(attributeValue); if(!string.empty()) setDefaultSaveName( string ); else setDefaultSaveName( attributeValue ); app.DebugPrintf("LevelGenerationOptions: Adding parameter saveName=%ls\n", getDefaultSaveName().c_str()); } else if(attributeName.compare(L"worldName") == 0) { - wstring string(getString(attributeValue)); + wstring string(attributeValue); if(!string.empty()) setWorldName( string ); else setWorldName( attributeValue ); app.DebugPrintf("LevelGenerationOptions: Adding parameter worldName=%ls\n", getWorldName()); } else if(attributeName.compare(L"displayName") == 0) { - wstring string(getString(attributeValue)); + wstring string(attributeValue); if(!string.empty()) setDisplayName( string ); else setDisplayName( attributeValue ); app.DebugPrintf("LevelGenerationOptions: Adding parameter displayName=%ls\n", getDisplayName()); @@ -228,6 +233,12 @@ void LevelGenerationOptions::addAttribute(const wstring &attributeName, const ws setBaseSavePath( attributeValue ); app.DebugPrintf("LevelGenerationOptions: Adding parameter baseSaveName=%ls\n", getBaseSavePath().c_str()); } + else if(attributeName.compare(L"hasBeenInCreative") == 0) + { + bool value = _fromString(attributeValue); + m_bHasBeenInCreative = value; + app.DebugPrintf("LevelGenerationOptions: Adding parameter gameMode=%d\n", m_bHasBeenInCreative); + } else { GameRuleDefinition::addAttribute(attributeName, attributeValue); @@ -297,7 +308,7 @@ bool LevelGenerationOptions::checkIntersects(int x0, int y0, int z0, int x1, int m_bHaveMinY = true; } - + // 4J Stu - We DO NOT intersect if our upper bound is below the lower bound for all schematics if( y1 < m_minY ) return false; @@ -413,14 +424,14 @@ void LevelGenerationOptions::getBiomeOverride(int biomeId, BYTE &tile, BYTE &top } } -bool LevelGenerationOptions::isFeatureChunk(int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature) +bool LevelGenerationOptions::isFeatureChunk(int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature, int *orientation) { bool isFeature = false; for(AUTO_VAR(it, m_features.begin()); it != m_features.end(); ++it) { StartFeature *sf = *it; - if(sf->isFeatureChunk(chunkX, chunkZ, feature)) + if(sf->isFeatureChunk(chunkX, chunkZ, feature, orientation)) { isFeature = true; break; @@ -442,15 +453,175 @@ unordered_map *LevelGenerationOptions::getUnfin = new unordered_map(); for (AUTO_VAR(it, usedFiles.begin()); it!=usedFiles.end(); it++) out->insert( pair(*it, getSchematicFile(*it)) ); - + return out; } +void LevelGenerationOptions::loadBaseSaveData() +{ + int mountIndex = -1; + if(m_parentDLCPack != NULL) mountIndex = m_parentDLCPack->GetDLCMountIndex(); + + if(mountIndex > -1) + { +#ifdef _DURANGO + if(StorageManager.MountInstalledDLC(ProfileManager.GetPrimaryPad(),mountIndex,&LevelGenerationOptions::packMounted,this,L"WPACK")!=ERROR_IO_PENDING) +#else + if(StorageManager.MountInstalledDLC(ProfileManager.GetPrimaryPad(),mountIndex,&LevelGenerationOptions::packMounted,this,"WPACK")!=ERROR_IO_PENDING) +#endif + { + // corrupt DLC + setLoadedData(); + app.DebugPrintf("Failed to mount LGO DLC %d for pad %d\n",mountIndex,ProfileManager.GetPrimaryPad()); + } + else + { + m_bLoadingData = true; + app.DebugPrintf("Attempted to mount DLC data for LGO %d\n", mountIndex); + } + } + else + { + setLoadedData(); + app.SetAction(ProfileManager.GetPrimaryPad(), eAppAction_ReloadTexturePack); + } +} + +int LevelGenerationOptions::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicenceMask) +{ + LevelGenerationOptions *lgo = (LevelGenerationOptions *)pParam; + lgo->m_bLoadingData = false; + if(dwErr!=ERROR_SUCCESS) + { + // corrupt DLC + app.DebugPrintf("Failed to mount LGO DLC for pad %d: %d\n",iPad,dwErr); + } + else + { + app.DebugPrintf("Mounted DLC for LGO, attempting to load data\n"); + DWORD dwFilesProcessed = 0; + int gameRulesCount = lgo->m_parentDLCPack->getDLCItemsCount(DLCManager::e_DLCType_GameRulesHeader); + for(int i = 0; i < gameRulesCount; ++i) + { + DLCGameRulesHeader *dlcFile = (DLCGameRulesHeader *) lgo->m_parentDLCPack->getFile(DLCManager::e_DLCType_GameRulesHeader, i); + + if (!dlcFile->getGrfPath().empty()) + { + File grf( app.getFilePath(lgo->m_parentDLCPack->GetPackID(), dlcFile->getGrfPath(),true, L"WPACK:" ) ); + if (grf.exists()) + { +#ifdef _UNICODE + wstring path = grf.getPath(); + const WCHAR *pchFilename=path.c_str(); + HANDLE fileHandle = CreateFile( + pchFilename, // file name + GENERIC_READ, // access mode + 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... + NULL, // Unused + OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it + FILE_FLAG_SEQUENTIAL_SCAN, // file attributes + NULL // Unsupported + ); +#else + const char *pchFilename=wstringtofilename(grf.getPath()); + HANDLE fileHandle = CreateFile( + pchFilename, // file name + GENERIC_READ, // access mode + 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... + NULL, // Unused + OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it + FILE_FLAG_SEQUENTIAL_SCAN, // file attributes + NULL // Unsupported + ); +#endif + + if( fileHandle != INVALID_HANDLE_VALUE ) + { + DWORD dwFileSize = grf.length(); + DWORD bytesRead; + PBYTE pbData = (PBYTE) new BYTE[dwFileSize]; + BOOL bSuccess = ReadFile(fileHandle,pbData,dwFileSize,&bytesRead,NULL); + if(bSuccess==FALSE) + { + app.FatalLoadError(); + } + CloseHandle(fileHandle); + + // 4J-PB - is it possible that we can get here after a read fail and it's not an error? + dlcFile->setGrfData(pbData, dwFileSize, lgo->m_stringTable); + + delete [] pbData; + + app.m_gameRules.setLevelGenerationOptions( dlcFile->lgo ); + } + } + } + } + if(lgo->requiresBaseSave() && !lgo->getBaseSavePath().empty() ) + { + File save(app.getFilePath(lgo->m_parentDLCPack->GetPackID(), lgo->getBaseSavePath(),true, L"WPACK:" )); + if (save.exists()) + { +#ifdef _UNICODE + wstring path = save.getPath(); + const WCHAR *pchFilename=path.c_str(); + HANDLE fileHandle = CreateFile( + pchFilename, // file name + GENERIC_READ, // access mode + 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... + NULL, // Unused + OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it + FILE_FLAG_SEQUENTIAL_SCAN, // file attributes + NULL // Unsupported + ); +#else + const char *pchFilename=wstringtofilename(save.getPath()); + HANDLE fileHandle = CreateFile( + pchFilename, // file name + GENERIC_READ, // access mode + 0, // share mode // TODO 4J Stu - Will we need to share file? Probably not but... + NULL, // Unused + OPEN_EXISTING , // how to create // TODO 4J Stu - Assuming that the file already exists if we are opening to read from it + FILE_FLAG_SEQUENTIAL_SCAN, // file attributes + NULL // Unsupported + ); +#endif + + if( fileHandle != INVALID_HANDLE_VALUE ) + { + DWORD bytesRead,dwFileSize = GetFileSize(fileHandle,NULL); + PBYTE pbData = (PBYTE) new BYTE[dwFileSize]; + BOOL bSuccess = ReadFile(fileHandle,pbData,dwFileSize,&bytesRead,NULL); + if(bSuccess==FALSE) + { + app.FatalLoadError(); + } + CloseHandle(fileHandle); + + // 4J-PB - is it possible that we can get here after a read fail and it's not an error? + lgo->setBaseSaveData(pbData, dwFileSize); + } + } + + } +#ifdef _DURANGO + DWORD result = StorageManager.UnmountInstalledDLC(L"WPACK"); +#else + DWORD result = StorageManager.UnmountInstalledDLC("WPACK"); +#endif + + } + + lgo->setLoadedData(); + + return 0; +} + void LevelGenerationOptions::reset_start() { for ( AUTO_VAR( it, m_schematicRules.begin()); - it != m_schematicRules.end(); - it++ ) + it != m_schematicRules.end(); + it++ ) { (*it)->reset(); } @@ -478,9 +649,38 @@ bool LevelGenerationOptions::isFromDLC() { return getSrc() == eSrc_fromDLC; } bool LevelGenerationOptions::requiresTexturePack() { return info()->requiresTexturePack(); } UINT LevelGenerationOptions::getRequiredTexturePackId() { return info()->getRequiredTexturePackId(); } -wstring LevelGenerationOptions::getDefaultSaveName() { return info()->getDefaultSaveName(); } -LPCWSTR LevelGenerationOptions::getWorldName() { return info()->getWorldName(); } -LPCWSTR LevelGenerationOptions::getDisplayName() { return info()->getDisplayName(); } + +wstring LevelGenerationOptions::getDefaultSaveName() +{ + switch (getSrc()) + { + case eSrc_fromSave: return getString( info()->getDefaultSaveName() ); + case eSrc_fromDLC: return getString( info()->getDefaultSaveName() ); + case eSrc_tutorial: return app.GetString(IDS_TUTORIALSAVENAME); + } + return L""; +} +LPCWSTR LevelGenerationOptions::getWorldName() +{ + switch (getSrc()) + { + case eSrc_fromSave: return getString( info()->getWorldName() ); + case eSrc_fromDLC: return getString( info()->getWorldName() ); + case eSrc_tutorial: return app.GetString(IDS_PLAY_TUTORIAL); + } + return L""; +} +LPCWSTR LevelGenerationOptions::getDisplayName() +{ + switch (getSrc()) + { + case eSrc_fromSave: return getString( info()->getDisplayName() ); + case eSrc_fromDLC: return getString( info()->getDisplayName() ); + case eSrc_tutorial: return L""; + } + return L""; +} + wstring LevelGenerationOptions::getGrfPath() { return info()->getGrfPath(); } bool LevelGenerationOptions::requiresBaseSave() { return info()->requiresBaseSave(); } wstring LevelGenerationOptions::getBaseSavePath() { return info()->getBaseSavePath(); } @@ -506,6 +706,7 @@ bool LevelGenerationOptions::hasLoadedData() { return m_hasLoadedData; } void LevelGenerationOptions::setLoadedData() { m_hasLoadedData = true; } __int64 LevelGenerationOptions::getLevelSeed() { return m_seed; } +int LevelGenerationOptions::getLevelHasBeenInCreative() { return m_bHasBeenInCreative; } Pos *LevelGenerationOptions::getSpawnPos() { return m_spawnPos; } bool LevelGenerationOptions::getuseFlatWorld() { return m_useFlatWorld; } diff --git a/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h b/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h index 0cc9da79..aa128ff8 100644 --- a/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h +++ b/Minecraft.Client/Common/GameRules/LevelGenerationOptions.h @@ -149,6 +149,7 @@ private: __int64 m_seed; bool m_useFlatWorld; Pos *m_spawnPos; + int m_bHasBeenInCreative; vector m_schematicRules; vector m_structureRules; bool m_bHaveMinY; @@ -162,8 +163,11 @@ private: StringTable *m_stringTable; + DLCPack *m_parentDLCPack; + bool m_bLoadingData; + public: - LevelGenerationOptions(); + LevelGenerationOptions(DLCPack *parentPack = NULL); ~LevelGenerationOptions(); virtual ConsoleGameRules::EGameRuleType getActionType(); @@ -174,6 +178,7 @@ public: virtual void addAttribute(const wstring &attributeName, const wstring &attributeValue); __int64 getLevelSeed(); + int getLevelHasBeenInCreative(); Pos *getSpawnPos(); bool getuseFlatWorld(); @@ -197,12 +202,15 @@ public: LevelRuleset *getRequiredGameRules(); void getBiomeOverride(int biomeId, BYTE &tile, BYTE &topTile); - bool isFeatureChunk(int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature); + bool isFeatureChunk(int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature, int *orientation = NULL); void loadStringTable(StringTable *table); LPCWSTR getString(const wstring &key); unordered_map *getUnfinishedSchematicFiles(); + + void loadBaseSaveData(); + static int packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicenceMask); // 4J-JEV: // ApplySchematicRules contain limited state diff --git a/Minecraft.Client/Common/GameRules/StartFeature.cpp b/Minecraft.Client/Common/GameRules/StartFeature.cpp index 9d5f15c0..7f0c8b5c 100644 --- a/Minecraft.Client/Common/GameRules/StartFeature.cpp +++ b/Minecraft.Client/Common/GameRules/StartFeature.cpp @@ -6,12 +6,13 @@ StartFeature::StartFeature() { m_chunkX = 0; m_chunkZ = 0; + m_orientation = 0; m_feature = StructureFeature::eFeature_Temples; } void StartFeature::writeAttributes(DataOutputStream *dos, UINT numAttrs) { - GameRuleDefinition::writeAttributes(dos, numAttrs + 3); + GameRuleDefinition::writeAttributes(dos, numAttrs + 4); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_chunkX); dos->writeUTF(_toString(m_chunkX)); @@ -19,6 +20,8 @@ void StartFeature::writeAttributes(DataOutputStream *dos, UINT numAttrs) dos->writeUTF(_toString(m_chunkZ)); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_feature); dos->writeUTF(_toString((int)m_feature)); + ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_orientation); + dos->writeUTF(_toString(m_orientation)); } void StartFeature::addAttribute(const wstring &attributeName, const wstring &attributeValue) @@ -35,6 +38,12 @@ void StartFeature::addAttribute(const wstring &attributeName, const wstring &att m_chunkZ = value; app.DebugPrintf("StartFeature: Adding parameter chunkZ=%d\n",m_chunkZ); } + else if(attributeName.compare(L"orientation") == 0) + { + int value = _fromString(attributeValue); + m_orientation = value; + app.DebugPrintf("StartFeature: Adding parameter orientation=%d\n",m_orientation); + } else if(attributeName.compare(L"feature") == 0) { int value = _fromString(attributeValue); @@ -47,7 +56,8 @@ void StartFeature::addAttribute(const wstring &attributeName, const wstring &att } } -bool StartFeature::isFeatureChunk(int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature) +bool StartFeature::isFeatureChunk(int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature, int *orientation) { + if(orientation != NULL) *orientation = m_orientation; return chunkX == m_chunkX && chunkZ == m_chunkZ && feature == m_feature; } \ No newline at end of file diff --git a/Minecraft.Client/Common/GameRules/StartFeature.h b/Minecraft.Client/Common/GameRules/StartFeature.h index d3f1280a..b198a2fa 100644 --- a/Minecraft.Client/Common/GameRules/StartFeature.h +++ b/Minecraft.Client/Common/GameRules/StartFeature.h @@ -7,7 +7,7 @@ using namespace std; class StartFeature : public GameRuleDefinition { private: - int m_chunkX, m_chunkZ; + int m_chunkX, m_chunkZ, m_orientation; StructureFeature::EFeatureTypes m_feature; public: @@ -18,5 +18,5 @@ public: virtual void writeAttributes(DataOutputStream *dos, UINT numAttrs); virtual void addAttribute(const wstring &attributeName, const wstring &attributeValue); - bool isFeatureChunk(int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature); + bool isFeatureChunk(int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature, int *orientation); }; \ No newline at end of file diff --git a/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceContainer.cpp b/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceContainer.cpp index 8184f45b..d81a2b03 100644 --- a/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceContainer.cpp +++ b/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceContainer.cpp @@ -74,16 +74,16 @@ bool XboxStructureActionPlaceContainer::placeContainerInLevel(StructurePiece *st { // Remove the current tile entity level->removeTileEntity( worldX, worldY, worldZ ); - level->setTile( worldX, worldY, worldZ, 0 ); + level->setTileAndData( worldX, worldY, worldZ, 0, 0, Tile::UPDATE_ALL ); } - level->setTile( worldX, worldY, worldZ, m_tile ); + level->setTileAndData( worldX, worldY, worldZ, m_tile, 0, Tile::UPDATE_ALL ); shared_ptr container = dynamic_pointer_cast(level->getTileEntity( worldX, worldY, worldZ )); app.DebugPrintf("XboxStructureActionPlaceContainer - placing a container at (%d,%d,%d)\n", worldX, worldY, worldZ); if ( container != NULL ) { - level->setData( worldX, worldY, worldZ, m_data); + level->setData( worldX, worldY, worldZ, m_data, Tile::UPDATE_CLIENTS); // Add items int slotId = 0; for(AUTO_VAR(it, m_items.begin()); it != m_items.end() && (slotId < container->getContainerSize()); ++it, ++slotId ) diff --git a/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceSpawner.cpp b/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceSpawner.cpp index 1eca3342..3f6204af 100644 --- a/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceSpawner.cpp +++ b/Minecraft.Client/Common/GameRules/XboxStructureActionPlaceSpawner.cpp @@ -50,10 +50,10 @@ bool XboxStructureActionPlaceSpawner::placeSpawnerInLevel(StructurePiece *struct { // Remove the current tile entity level->removeTileEntity( worldX, worldY, worldZ ); - level->setTile( worldX, worldY, worldZ, 0 ); + level->setTileAndData( worldX, worldY, worldZ, 0, 0, Tile::UPDATE_ALL ); } - level->setTile( worldX, worldY, worldZ, m_tile ); + level->setTileAndData( worldX, worldY, worldZ, m_tile, 0, Tile::UPDATE_ALL ); shared_ptr entity = dynamic_pointer_cast(level->getTileEntity( worldX, worldY, worldZ )); #ifndef _CONTENT_PACKAGE -- cgit v1.2.3