TU19: merge Minecraft.Client/Platform/Common/GameRules

This commit is contained in:
Tropical 2026-03-22 01:27:23 -05:00
parent 87b4af678b
commit 3fa28df4da
10 changed files with 328 additions and 109 deletions

View file

@ -42,4 +42,8 @@ public:
bool checkIntersects(int x0, int y0, int z0, int x1, int y1, int z1); bool checkIntersects(int x0, int y0, int z0, int x1, int y1, int z1);
virtual int getMinY(); virtual int getMinY();
EStructurePiece GetType() { return (EStructurePiece)0; }
void addAdditonalSaveData(CompoundTag* tag) {}
void readAdditonalSaveData(CompoundTag* tag) {}
}; };

View file

@ -744,19 +744,24 @@ void ConsoleSchematicFile::generateSchematicFile(
bool mobCanBeSaved = false; bool mobCanBeSaved = false;
if (bSaveMobs) { if (bSaveMobs) {
if ((e->GetType() & eTYPE_MONSTER) || if (e->instanceof(eTYPE_MONSTER) ||
(e->GetType() & eTYPE_WATERANIMAL) || e->instanceof(eTYPE_WATERANIMAL) ||
(e->GetType() & eTYPE_ANIMAL) || e->instanceof(eTYPE_ANIMAL) || (e->GetType() == eTYPE_VILLAGER))
(e->GetType() == eTYPE_CHICKEN) ||
(e->GetType() == eTYPE_WOLF) || // 4J-JEV: All these are derived from eTYPE_ANIMAL and true
(e->GetType() == eTYPE_VILLAGER) || // implicitly.
(e->GetType() == eTYPE_MUSHROOMCOW)) { //|| ( e->GetType() == eTYPE_CHICKEN ) || ( e->GetType() ==
// eTYPE_WOLF ) || ( e->GetType() == eTYPE_MUSHROOMCOW ) )
{
mobCanBeSaved = true; mobCanBeSaved = true;
} }
} }
if (mobCanBeSaved || e->GetType() == eTYPE_MINECART ||
e->GetType() == eTYPE_BOAT || e->GetType() == eTYPE_PAINTING || // 4J-JEV: Changed to check for instances of minecarts and
e->GetType() == eTYPE_ITEM_FRAME) { // 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(); CompoundTag* eTag = new CompoundTag();
if (e->save(eTag)) { if (e->save(eTag)) {
ListTag<DoubleTag>* pos = ListTag<DoubleTag>* pos =
@ -766,8 +771,7 @@ void ConsoleSchematicFile::generateSchematicFile(
pos->get(1)->data -= yStart; pos->get(1)->data -= yStart;
pos->get(2)->data -= zStart; pos->get(2)->data -= zStart;
if (e->GetType() == eTYPE_PAINTING || if (e->instanceof(eTYPE_HANGING_ENTITY)) {
e->GetType() == eTYPE_ITEM_FRAME) {
((IntTag*)eTag->get(L"TileX"))->data -= xStart; ((IntTag*)eTag->get(L"TileX"))->data -= xStart;
((IntTag*)eTag->get(L"TileY"))->data -= yStart; ((IntTag*)eTag->get(L"TileY"))->data -= yStart;
((IntTag*)eTag->get(L"TileZ"))->data -= zStart; ((IntTag*)eTag->get(L"TileZ"))->data -= zStart;

View file

@ -106,18 +106,15 @@ void GameRuleManager::loadGameRules(DLCPack* pack) {
uint8_t* dData = dlcHeader->getData(dSize); uint8_t* dData = dlcHeader->getData(dSize);
LevelGenerationOptions* createdLevelGenerationOptions = LevelGenerationOptions* createdLevelGenerationOptions =
new LevelGenerationOptions(); new LevelGenerationOptions(pack);
// = loadGameRules(dData, dSize); //, strings); // = loadGameRules(dData, dSize); //, strings);
createdLevelGenerationOptions->setGrSource(dlcHeader); createdLevelGenerationOptions->setGrSource(dlcHeader);
readRuleFile(createdLevelGenerationOptions, dData, dSize, strings);
createdLevelGenerationOptions->setSrc( createdLevelGenerationOptions->setSrc(
LevelGenerationOptions::eSrc_fromDLC); LevelGenerationOptions::eSrc_fromDLC);
// createdLevelGenerationOptions->setSrc( readRuleFile(createdLevelGenerationOptions, dData, dSize, strings);
// LevelGenerationOptions::eSrc_fromDLC );
dlcHeader->lgo = createdLevelGenerationOptions; dlcHeader->lgo = createdLevelGenerationOptions;
} }
@ -130,16 +127,14 @@ void GameRuleManager::loadGameRules(DLCPack* pack) {
uint8_t* dData = dlcFile->getData(dSize); uint8_t* dData = dlcFile->getData(dSize);
LevelGenerationOptions* createdLevelGenerationOptions = LevelGenerationOptions* createdLevelGenerationOptions =
new LevelGenerationOptions(); new LevelGenerationOptions(pack);
// = loadGameRules(dData, dSize); //, strings); // = loadGameRules(dData, dSize); //, strings);
createdLevelGenerationOptions->setGrSource(new JustGrSource()); createdLevelGenerationOptions->setGrSource(new JustGrSource());
readRuleFile(createdLevelGenerationOptions, dData, dSize, strings);
createdLevelGenerationOptions->setSrc( createdLevelGenerationOptions->setSrc(
LevelGenerationOptions::eSrc_tutorial); LevelGenerationOptions::eSrc_tutorial);
// createdLevelGenerationOptions->set_DLCGameRulesFile( dlcFile ); readRuleFile(createdLevelGenerationOptions, dData, dSize, strings);
createdLevelGenerationOptions->setLoadedData(); createdLevelGenerationOptions->setLoadedData();
} }
@ -661,67 +656,46 @@ void GameRuleManager::loadDefaultGameRules() {
#else // _XBOX #else // _XBOX
std::wstring fpTutorial = L"Tutorial.pck"; #ifdef _WINDOWS64
if (app.getArchiveFileSize(fpTutorial) >= 0) { File packedTutorialFile(L"Windows64Media\\Tutorial\\Tutorial.pck");
DLCPack* pack = new DLCPack(L"", 0xffffffff); if (!packedTutorialFile.exists())
unsigned int dwFilesProcessed = 0; packedTutorialFile = File(L"Windows64\\Tutorial\\Tutorial.pck");
if (app.m_dlcManager.readDLCDataFile(dwFilesProcessed, fpTutorial, pack, #elif defined(__ORBIS__)
true)) { File packedTutorialFile(L"/app0/orbis/Tutorial/Tutorial.pck");
app.m_dlcManager.addPack(pack); #elif defined(__PSVITA__)
if (!m_levelGenerators.getLevelGenerators()->empty()) { File packedTutorialFile(L"PSVita/Tutorial/Tutorial.pck");
m_levelGenerators.getLevelGenerators()->at(0)->setWorldName( #elif defined(__PS3__)
app.GetString(IDS_PLAY_TUTORIAL)); File packedTutorialFile(L"PS3/Tutorial/Tutorial.pck");
m_levelGenerators.getLevelGenerators() #else
->at(0) File packedTutorialFile(L"Tutorial\\Tutorial.pck");
->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME)); #endif
} else { if (loadGameRulesPack(&packedTutorialFile)) {
app.DebugPrintf( m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(
"loadDefaultGameRules: Tutorial.pck parsed OK but no level " app.GetString(IDS_PLAY_TUTORIAL));
"generators were added (missing " // m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(L"Tutorial");
"GameRules/LevelGenerationOptions tag?)\n"); m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(
} app.GetString(IDS_TUTORIALSAVENAME));
} else {
app.DebugPrintf(
"loadDefaultGameRules: readDLCDataFile failed for Tutorial.pck "
"(version too old, IO error, or DLC_TYPE_GameRules not "
"found)\n");
delete pack;
}
} else {
app.DebugPrintf(
"loadDefaultGameRules: Tutorial.pck not found in archive\n");
} }
#if 0
// Linux/PC port fallback: if Tutorial.pck parsing didn't populate level std::wstring fpTutorial = L"Tutorial.pck";
// generators (e.g. DLC version mismatch, missing GameRules tag), create a if(app.getArchiveFileSize(fpTutorial) >= 0)
// minimal placeholder so the game doesn't crash with vector::at(0) in {
// LoadTrial(). DLCPack *pack = new DLCPack(L"",0xffffffff);
if (m_levelGenerators.getLevelGenerators()->empty()) { DWORD dwFilesProcessed = 0;
app.DebugPrintf( if ( app.m_dlcManager.readDLCDataFile(dwFilesProcessed,fpTutorial,pack,true) )
"loadDefaultGameRules: creating minimal fallback " {
"LevelGenerationOptions\n"); app.m_dlcManager.addPack(pack);
LevelGenerationOptions* lgo = new LevelGenerationOptions(); //m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(app.GetString(IDS_PLAY_TUTORIAL));
lgo->setGrSource(new JustGrSource()); //m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME));
lgo->setSrc(LevelGenerationOptions::eSrc_tutorial); }
lgo->setWorldName(app.GetString(IDS_PLAY_TUTORIAL)); else delete pack;
lgo->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME)); }
lgo->setLoadedData(); #endif
addLevelGenerationOptions(lgo);
}
/*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 GameRuleManager::loadGameRulesPack(File* path) {
bool success = false; bool success = false;
#ifdef _XBOX
if (path->exists()) { if (path->exists()) {
DLCPack* pack = new DLCPack(L"", 0xffffffff); DLCPack* pack = new DLCPack(L"", 0xffffffff);
unsigned int dwFilesProcessed = 0; unsigned int dwFilesProcessed = 0;
@ -733,12 +707,13 @@ bool GameRuleManager::loadGameRulesPack(File* path) {
delete pack; delete pack;
} }
} }
#endif
return success; return success;
} }
void GameRuleManager::setLevelGenerationOptions( void GameRuleManager::setLevelGenerationOptions(
LevelGenerationOptions* levelGen) { LevelGenerationOptions* levelGen) {
unloadCurrentGameRules();
m_currentGameRuleDefinitions = NULL; m_currentGameRuleDefinitions = NULL;
m_currentLevelGenerationOptions = levelGen; m_currentLevelGenerationOptions = levelGen;

View file

@ -51,20 +51,24 @@ void JustGrSource::setBaseSavePath(const std::wstring& x) {
bool JustGrSource::ready() { return true; } bool JustGrSource::ready() { return true; }
LevelGenerationOptions::LevelGenerationOptions() { LevelGenerationOptions::LevelGenerationOptions(DLCPack* parentPack) {
m_spawnPos = NULL; m_spawnPos = NULL;
m_stringTable = NULL; m_stringTable = NULL;
m_hasLoadedData = false; m_hasLoadedData = false;
m_seed = 0; m_seed = 0;
m_bHasBeenInCreative = true;
m_useFlatWorld = false; m_useFlatWorld = false;
m_bHaveMinY = false; m_bHaveMinY = false;
m_minY = INT_MAX; m_minY = INT_MAX;
m_bRequiresGameRules = false; m_bRequiresGameRules = false;
m_pbBaseSaveData = NULL; m_pbBaseSaveData = NULL;
m_baseSaveSize = 0; m_dwBaseSaveSize = 0;
m_parentDLCPack = parentPack;
m_bLoadingData = false;
} }
LevelGenerationOptions::~LevelGenerationOptions() { LevelGenerationOptions::~LevelGenerationOptions() {
@ -235,6 +239,12 @@ void LevelGenerationOptions::addAttribute(const std::wstring& attributeName,
app.DebugPrintf( app.DebugPrintf(
"LevelGenerationOptions: Adding parameter baseSaveName=%ls\n", "LevelGenerationOptions: Adding parameter baseSaveName=%ls\n",
getBaseSavePath().c_str()); getBaseSavePath().c_str());
} else if (attributeName.compare(L"hasBeenInCreative") == 0) {
bool value = _fromString<bool>(attributeValue);
m_bHasBeenInCreative = value;
app.DebugPrintf(
"LevelGenerationOptions: Adding parameter gameMode=%d\n",
m_bHasBeenInCreative);
} else { } else {
GameRuleDefinition::addAttribute(attributeName, attributeValue); GameRuleDefinition::addAttribute(attributeName, attributeValue);
} }
@ -252,9 +262,8 @@ void LevelGenerationOptions::processSchematics(LevelChunk* chunk) {
rule->processSchematic(chunkBox, chunk); rule->processSchematic(chunkBox, chunk);
} }
// 4jcraft added cast to unsigned int cx = (chunk->x << 4);
int cx = ((unsigned)chunk->x << 4); int cz = (chunk->z << 4);
int cz = ((unsigned)chunk->z << 4);
for (AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end(); for (AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end();
it++) { it++) {
@ -420,12 +429,13 @@ void LevelGenerationOptions::getBiomeOverride(int biomeId, std::uint8_t& tile,
} }
bool LevelGenerationOptions::isFeatureChunk( bool LevelGenerationOptions::isFeatureChunk(
int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature) { int chunkX, int chunkZ, StructureFeature::EFeatureTypes feature,
int* orientation) {
bool isFeature = false; bool isFeature = false;
for (AUTO_VAR(it, m_features.begin()); it != m_features.end(); ++it) { for (AUTO_VAR(it, m_features.begin()); it != m_features.end(); ++it) {
StartFeature* sf = *it; StartFeature* sf = *it;
if (sf->isFeatureChunk(chunkX, chunkZ, feature)) { if (sf->isFeatureChunk(chunkX, chunkZ, feature, orientation)) {
isFeature = true; isFeature = true;
break; break;
} }
@ -452,6 +462,180 @@ LevelGenerationOptions::getUnfinishedSchematicFiles() {
return out; 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
std::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
std::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() { void LevelGenerationOptions::reset_start() {
for (AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end(); for (AUTO_VAR(it, m_schematicRules.begin()); it != m_schematicRules.end();
it++) { it++) {
@ -484,13 +668,37 @@ std::uint32_t LevelGenerationOptions::getRequiredTexturePackId() {
return info()->getRequiredTexturePackId(); return info()->getRequiredTexturePackId();
} }
std::wstring LevelGenerationOptions::getDefaultSaveName() { std::wstring LevelGenerationOptions::getDefaultSaveName() {
return info()->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"";
} }
const wchar_t* LevelGenerationOptions::getWorldName() { LPCWSTR LevelGenerationOptions::getWorldName() {
return info()->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"";
} }
const wchar_t* LevelGenerationOptions::getDisplayName() { LPCWSTR LevelGenerationOptions::getDisplayName() {
return info()->getDisplayName(); switch (getSrc()) {
case eSrc_fromSave:
return getString(info()->getDisplayName());
case eSrc_fromDLC:
return getString(info()->getDisplayName());
case eSrc_tutorial:
return L"";
}
return L"";
} }
std::wstring LevelGenerationOptions::getGrfPath() { std::wstring LevelGenerationOptions::getGrfPath() {
return info()->getGrfPath(); return info()->getGrfPath();
@ -549,7 +757,10 @@ void LevelGenerationOptions::deleteBaseSaveData() {
bool LevelGenerationOptions::hasLoadedData() { return m_hasLoadedData; } bool LevelGenerationOptions::hasLoadedData() { return m_hasLoadedData; }
void LevelGenerationOptions::setLoadedData() { m_hasLoadedData = true; } void LevelGenerationOptions::setLoadedData() { m_hasLoadedData = true; }
__int64 LevelGenerationOptions::getLevelSeed() { return m_seed; } int64_t LevelGenerationOptions::getLevelSeed() { return m_seed; }
int LevelGenerationOptions::getLevelHasBeenInCreative() {
return m_bHasBeenInCreative;
}
Pos* LevelGenerationOptions::getSpawnPos() { return m_spawnPos; } Pos* LevelGenerationOptions::getSpawnPos() { return m_spawnPos; }
bool LevelGenerationOptions::getuseFlatWorld() { return m_useFlatWorld; } bool LevelGenerationOptions::getuseFlatWorld() { return m_useFlatWorld; }

View file

@ -146,9 +146,10 @@ public:
private: private:
// This should match the "MapOptionsRule" definition in the XML schema // This should match the "MapOptionsRule" definition in the XML schema
__int64 m_seed; int64_t m_seed;
bool m_useFlatWorld; bool m_useFlatWorld;
Pos* m_spawnPos; Pos* m_spawnPos;
int m_bHasBeenInCreative;
std::vector<ApplySchematicRuleDefinition*> m_schematicRules; std::vector<ApplySchematicRuleDefinition*> m_schematicRules;
std::vector<ConsoleGenerateStructure*> m_structureRules; std::vector<ConsoleGenerateStructure*> m_structureRules;
bool m_bHaveMinY; bool m_bHaveMinY;
@ -162,8 +163,11 @@ private:
StringTable* m_stringTable; StringTable* m_stringTable;
DLCPack* m_parentDLCPack;
bool m_bLoadingData;
public: public:
LevelGenerationOptions(); LevelGenerationOptions(DLCPack* parentPack = NULL);
~LevelGenerationOptions(); ~LevelGenerationOptions();
virtual ConsoleGameRules::EGameRuleType getActionType(); virtual ConsoleGameRules::EGameRuleType getActionType();
@ -176,7 +180,8 @@ public:
virtual void addAttribute(const std::wstring& attributeName, virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue); const std::wstring& attributeValue);
__int64 getLevelSeed(); int64_t getLevelSeed();
int getLevelHasBeenInCreative();
Pos* getSpawnPos(); Pos* getSpawnPos();
bool getuseFlatWorld(); bool getuseFlatWorld();
@ -204,7 +209,8 @@ public:
void getBiomeOverride(int biomeId, std::uint8_t& tile, void getBiomeOverride(int biomeId, std::uint8_t& tile,
std::uint8_t& topTile); std::uint8_t& topTile);
bool isFeatureChunk(int chunkX, int chunkZ, bool isFeatureChunk(int chunkX, int chunkZ,
StructureFeature::EFeatureTypes feature); StructureFeature::EFeatureTypes feature,
int* orientation = NULL);
void loadStringTable(StringTable* table); void loadStringTable(StringTable* table);
const wchar_t* getString(const std::wstring& key); const wchar_t* getString(const std::wstring& key);
@ -212,6 +218,10 @@ public:
std::unordered_map<std::wstring, ConsoleSchematicFile*>* std::unordered_map<std::wstring, ConsoleSchematicFile*>*
getUnfinishedSchematicFiles(); getUnfinishedSchematicFiles();
void loadBaseSaveData();
static int packMounted(LPVOID pParam, int iPad, DWORD dwErr,
DWORD dwLicenceMask);
// 4J-JEV: // 4J-JEV:
// ApplySchematicRules contain limited state // ApplySchematicRules contain limited state
// which needs to be reset BEFORE a new game starts. // which needs to be reset BEFORE a new game starts.

View file

@ -5,12 +5,13 @@
StartFeature::StartFeature() { StartFeature::StartFeature() {
m_chunkX = 0; m_chunkX = 0;
m_chunkZ = 0; m_chunkZ = 0;
m_orientation = 0;
m_feature = StructureFeature::eFeature_Temples; m_feature = StructureFeature::eFeature_Temples;
} }
void StartFeature::writeAttributes(DataOutputStream* dos, void StartFeature::writeAttributes(DataOutputStream* dos,
unsigned int numAttrs) { unsigned int numAttrs) {
GameRuleDefinition::writeAttributes(dos, numAttrs + 3); GameRuleDefinition::writeAttributes(dos, numAttrs + 4);
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_chunkX); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_chunkX);
dos->writeUTF(_toString(m_chunkX)); dos->writeUTF(_toString(m_chunkX));
@ -18,6 +19,8 @@ void StartFeature::writeAttributes(DataOutputStream* dos,
dos->writeUTF(_toString(m_chunkZ)); dos->writeUTF(_toString(m_chunkZ));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_feature); ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_feature);
dos->writeUTF(_toString((int)m_feature)); dos->writeUTF(_toString((int)m_feature));
ConsoleGameRules::write(dos, ConsoleGameRules::eGameRuleAttr_orientation);
dos->writeUTF(_toString(m_orientation));
} }
void StartFeature::addAttribute(const std::wstring& attributeName, void StartFeature::addAttribute(const std::wstring& attributeName,
@ -30,6 +33,11 @@ void StartFeature::addAttribute(const std::wstring& attributeName,
int value = _fromString<int>(attributeValue); int value = _fromString<int>(attributeValue);
m_chunkZ = value; m_chunkZ = value;
app.DebugPrintf("StartFeature: Adding parameter chunkZ=%d\n", m_chunkZ); app.DebugPrintf("StartFeature: Adding parameter chunkZ=%d\n", m_chunkZ);
} else if (attributeName.compare(L"orientation") == 0) {
int value = _fromString<int>(attributeValue);
m_orientation = value;
app.DebugPrintf("StartFeature: Adding parameter orientation=%d\n",
m_orientation);
} else if (attributeName.compare(L"feature") == 0) { } else if (attributeName.compare(L"feature") == 0) {
int value = _fromString<int>(attributeValue); int value = _fromString<int>(attributeValue);
m_feature = (StructureFeature::EFeatureTypes)value; m_feature = (StructureFeature::EFeatureTypes)value;
@ -41,6 +49,8 @@ void StartFeature::addAttribute(const std::wstring& attributeName,
} }
bool StartFeature::isFeatureChunk(int chunkX, int chunkZ, bool StartFeature::isFeatureChunk(int chunkX, int chunkZ,
StructureFeature::EFeatureTypes feature) { StructureFeature::EFeatureTypes feature,
int* orientation) {
if (orientation != NULL) *orientation = m_orientation;
return chunkX == m_chunkX && chunkZ == m_chunkZ && feature == m_feature; return chunkX == m_chunkX && chunkZ == m_chunkZ && feature == m_feature;
} }

View file

@ -6,7 +6,7 @@
class StartFeature : public GameRuleDefinition { class StartFeature : public GameRuleDefinition {
private: private:
int m_chunkX, m_chunkZ; int m_chunkX, m_chunkZ, m_orientation;
StructureFeature::EFeatureTypes m_feature; StructureFeature::EFeatureTypes m_feature;
public: public:
@ -21,5 +21,6 @@ public:
const std::wstring& attributeValue); const std::wstring& attributeValue);
bool isFeatureChunk(int chunkX, int chunkZ, bool isFeatureChunk(int chunkX, int chunkZ,
StructureFeature::EFeatureTypes feature); StructureFeature::EFeatureTypes feature,
int* orientation);
}; };

View file

@ -19,7 +19,7 @@ XboxStructureActionPlaceContainer::~XboxStructureActionPlaceContainer() {
// 4J-JEV: Super class handles attr-facing fine. // 4J-JEV: Super class handles attr-facing fine.
// void XboxStructureActionPlaceContainer::writeAttributes(DataOutputStream // void XboxStructureActionPlaceContainer::writeAttributes(DataOutputStream
// *dos, unsigned int numAttrs) // *dos, UINT numAttrs)
void XboxStructureActionPlaceContainer::getChildren( void XboxStructureActionPlaceContainer::getChildren(
std::vector<GameRuleDefinition*>* children) { std::vector<GameRuleDefinition*>* children) {
@ -69,10 +69,12 @@ bool XboxStructureActionPlaceContainer::placeContainerInLevel(
if (level->getTileEntity(worldX, worldY, worldZ) != NULL) { if (level->getTileEntity(worldX, worldY, worldZ) != NULL) {
// Remove the current tile entity // Remove the current tile entity
level->removeTileEntity(worldX, worldY, worldZ); 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);
std::shared_ptr<Container> container = std::shared_ptr<Container> container =
std::dynamic_pointer_cast<Container>( std::dynamic_pointer_cast<Container>(
level->getTileEntity(worldX, worldY, worldZ)); level->getTileEntity(worldX, worldY, worldZ));
@ -82,7 +84,8 @@ bool XboxStructureActionPlaceContainer::placeContainerInLevel(
"(%d,%d,%d)\n", "(%d,%d,%d)\n",
worldX, worldY, worldZ); worldX, worldY, worldZ);
if (container != NULL) { if (container != NULL) {
level->setData(worldX, worldY, worldZ, m_data); level->setData(worldX, worldY, worldZ, m_data,
Tile::UPDATE_CLIENTS);
// Add items // Add items
int slotId = 0; int slotId = 0;
for (AUTO_VAR(it, m_items.begin()); for (AUTO_VAR(it, m_items.begin());

View file

@ -24,8 +24,7 @@ public:
ConsoleGameRules::EGameRuleType ruleType); ConsoleGameRules::EGameRuleType ruleType);
// 4J-JEV: Super class handles attr-facing fine. // 4J-JEV: Super class handles attr-facing fine.
// virtual void writeAttributes(DataOutputStream *dos, unsigned int // virtual void writeAttributes(DataOutputStream *dos, UINT numAttributes);
// numAttributes);
virtual void addAttribute(const std::wstring& attributeName, virtual void addAttribute(const std::wstring& attributeName,
const std::wstring& attributeValue); const std::wstring& attributeValue);

View file

@ -45,10 +45,12 @@ bool XboxStructureActionPlaceSpawner::placeSpawnerInLevel(
if (level->getTileEntity(worldX, worldY, worldZ) != NULL) { if (level->getTileEntity(worldX, worldY, worldZ) != NULL) {
// Remove the current tile entity // Remove the current tile entity
level->removeTileEntity(worldX, worldY, worldZ); 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);
std::shared_ptr<MobSpawnerTileEntity> entity = std::shared_ptr<MobSpawnerTileEntity> entity =
std::dynamic_pointer_cast<MobSpawnerTileEntity>( std::dynamic_pointer_cast<MobSpawnerTileEntity>(
level->getTileEntity(worldX, worldY, worldZ)); level->getTileEntity(worldX, worldY, worldZ));