diff --git a/.gitea/emerald_logo.png b/.gitea/emerald_logo.png new file mode 100644 index 00000000..36b8cfe8 Binary files /dev/null and b/.gitea/emerald_logo.png differ diff --git a/.gitea/workflows/nightly.yml b/.gitea/workflows/nightly.yml index 9632345c..3331471c 100644 --- a/.gitea/workflows/nightly.yml +++ b/.gitea/workflows/nightly.yml @@ -4,12 +4,7 @@ on: workflow_dispatch: push: branches: - - 'main' - paths-ignore: - - '.gitignore' - - '*.md' - - '.gitea/**' - - '!.gitea/workflows/nightly.yml' + - main permissions: contents: write @@ -20,6 +15,9 @@ concurrency: jobs: build: + if: > + !github.event.head_commit || + !contains(github.event.head_commit.message, '[skip ci]') runs-on: ubuntu-24.04 steps: - name: Checkout @@ -77,6 +75,9 @@ jobs: release: needs: build + if: > + !github.event.head_commit || + !contains(github.event.head_commit.message, '[skip ci]') runs-on: ubuntu-24.04 steps: - name: Download build artifacts diff --git a/Minecraft.Client/Common/App_enums.h b/Minecraft.Client/Common/App_enums.h index 1232a7c7..c054b252 100644 --- a/Minecraft.Client/Common/App_enums.h +++ b/Minecraft.Client/Common/App_enums.h @@ -223,6 +223,7 @@ enum eMinecraftColour eMinecraftColour_Foliage_JungleHills, eMinecraftColour_Foliage_Savanna, eMinecraftColour_Foliage_RoofedForest, + eMinecraftColour_Foliage_Mesa, eMinecraftColour_Grass_Common, eMinecraftColour_Grass_Ocean, @@ -250,6 +251,7 @@ enum eMinecraftColour eMinecraftColour_Grass_JungleHills, eMinecraftColour_Grass_Savanna, eMinecraftColour_Grass_RoofedForest, + eMinecraftColour_Grass_Mesa, eMinecraftColour_Water_Ocean, eMinecraftColour_Water_Plains, @@ -274,6 +276,7 @@ enum eMinecraftColour eMinecraftColour_Water_ExtremeHillsEdge, eMinecraftColour_Water_Jungle, eMinecraftColour_Water_JungleHills, + eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Ocean, eMinecraftColour_Sky_Plains, @@ -615,6 +618,7 @@ enum _eTerrainFeatureType eTerrainFeature_Ravine, eTerrainFeature_NetherFortress, eTerrainFeature_StrongholdEndPortal, + eTerrainFeature_OceanMonument, eTerrainFeature_Count }; diff --git a/Minecraft.Client/Common/Audio/SoundEngine.cpp b/Minecraft.Client/Common/Audio/SoundEngine.cpp index f09bad8c..449aad21 100644 --- a/Minecraft.Client/Common/Audio/SoundEngine.cpp +++ b/Minecraft.Client/Common/Audio/SoundEngine.cpp @@ -139,6 +139,12 @@ const char *SoundEngine::m_szStreamFileA[eStream_Max]= // The End "the_end_dragon_alive", "the_end_end", + + // Battle + "BattleMode1", + "BattleMode2", + "BattleMode3", + "BattleMode4", // CDs "11", @@ -189,7 +195,7 @@ void SoundEngine::init(Options* pOptions) return; } -void SoundEngine::SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1) +void SoundEngine::SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCreativeMin, int iCreativeMax, int iMenuMin, int iMenuMax, int iBattleMin, int iBattleMax, int iCD1) { m_iStream_Overworld_Min=iOverworldMin; m_iStream_Overworld_Max=iOverWorldMax; @@ -197,6 +203,12 @@ void SoundEngine::SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int i m_iStream_Nether_Max=iNetherMax; m_iStream_End_Min=iEndMin; m_iStream_End_Max=iEndMax; + m_iStream_Creative_Min = iCreativeMin; + m_iStream_Creative_Max = iCreativeMax; + m_iStream_Menu_Min = iMenuMin; + m_iStream_Menu_Max = iMenuMax; + m_iStream_Battle_Min = iBattleMin; + m_iStream_Battle_Max = iBattleMax; m_iStream_CD_1=iCD1; // array to monitor recently played tracks @@ -402,12 +414,15 @@ SoundEngine::SoundEngine() m_bHeardTrackA=nullptr; // Start the streaming music playing some music from the overworld - SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, - eStream_Nether1,eStream_Nether4, - eStream_end_dragon,eStream_end_end, - eStream_CD_1); + SetStreamingSounds(eStream_Overworld_Calm1, eStream_Overworld_piano3, + eStream_Nether1, eStream_Nether4, + eStream_end_dragon, eStream_end_end, + eStream_Overworld_Creative1, eStream_Overworld_Creative6, + eStream_Overworld_Menu1, eStream_Overworld_Menu4, + eStream_BattleMode1, eStream_BattleMode4, + eStream_CD_1); - m_musicID=getMusicID(LevelData::DIMENSION_OVERWORLD); + m_musicID = getMusicID(eMusicDomain_Menu); m_StreamingAudioInfo.bIs3D=false; m_StreamingAudioInfo.x=0; @@ -661,81 +676,83 @@ void SoundEngine::playUI(int iSound, float volume, float pitch) // playStreaming // ///////////////////////////////////////////// -void SoundEngine::playStreaming(const wstring& name, float x, float y , float z, float volume, float pitch, bool bMusicDelay) +void SoundEngine::playStreaming(const wstring& name, float x, float y, float z, float volume, float pitch, bool bMusicDelay) { // This function doesn't actually play a streaming sound, just sets states and an id for the music tick to play it // Level audio will be played when a play with an empty name comes in // CD audio will be played when a named stream comes in - m_StreamingAudioInfo.x=x; - m_StreamingAudioInfo.y=y; - m_StreamingAudioInfo.z=z; - m_StreamingAudioInfo.volume=volume; - m_StreamingAudioInfo.pitch=pitch; + m_StreamingAudioInfo.x = x; + m_StreamingAudioInfo.y = y; + m_StreamingAudioInfo.z = z; + m_StreamingAudioInfo.volume = volume; + m_StreamingAudioInfo.pitch = pitch; - if(m_StreamState==eMusicStreamState_Playing) - { - m_StreamState=eMusicStreamState_Stop; - } - else if(m_StreamState==eMusicStreamState_Opening) - { - m_StreamState=eMusicStreamState_OpeningCancel; - } + if(m_StreamState == eMusicStreamState_Playing) + m_StreamState = eMusicStreamState_Stop; + else if(m_StreamState == eMusicStreamState_Opening) + m_StreamState = eMusicStreamState_OpeningCancel; if(name.empty()) { // music, or stop CD - m_StreamingAudioInfo.bIs3D=false; + m_StreamingAudioInfo.bIs3D = false; - // we need a music id // random delay of up to 3 minutes for music - m_iMusicDelay = random->nextInt(20 * 60 * 3);//random->nextInt(20 * 60 * 10) + 20 * 60 * 10; + m_iMusicDelay = random->nextInt(20 * 60 * 3); #ifdef _DEBUG - m_iMusicDelay=0; + m_iMusicDelay = 0; #endif - Minecraft *pMinecraft=Minecraft::GetInstance(); - bool playerInEnd=false; - bool playerInNether=false; + Minecraft *pMinecraft = Minecraft::GetInstance(); - for(unsigned int i=0;ilocalplayers[i]!=nullptr) + if(pMinecraft->localplayers[i] != nullptr) { - if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_END) - { - playerInEnd=true; - } - else if(pMinecraft->localplayers[i]->dimension==LevelData::DIMENSION_NETHER) - { - playerInNether=true; - } + if(pMinecraft->localplayers[i]->dimension == LevelData::DIMENSION_END) + playerInEnd = true; + else if(pMinecraft->localplayers[i]->dimension == LevelData::DIMENSION_NETHER) + playerInNether = true; } } + if(playerInEnd) - { - m_musicID = getMusicID(LevelData::DIMENSION_END); - } + m_musicID = getMusicID(eMusicDomain_End); else if(playerInNether) - { - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); - } + m_musicID = getMusicID(eMusicDomain_Nether); else { - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); + // @3UR: in ida it looks like they didnt have a var for the player but idc its cleaner + MultiplayerLocalPlayer* pPlayer = pMinecraft->localplayers[i-1].get(); + + if(pPlayer != nullptr && pPlayer->abilities.instabuild && pPlayer->abilities.mayfly) + m_musicID = getMusicID(eMusicDomain_Creative); + // TODO(3UR): this is a part of minigames also in the future other minigame ids will need to be handled for now TU30 only checks for BATTLE + //else if(pMinecraft->GetCustomGameMode() && CustomGameModeInst::GetId() == EMiniGameId::BATTLE) // @3UR: thanks https://github.com/GRAnimated/MinecraftLCE/blob/6947670d152582457bfe02bd909ee30a7ab7eb55/src/Minecraft.World/net/minecraft/world/level/gamemode/minigames/EMiniGameId.h#L3 + // m_musicID = getMusicID(eMuszicDomain_Battle); + else + m_musicID = getMusicID(eMusicDomain_Overworld); } } else { // jukebox - m_StreamingAudioInfo.bIs3D=true; - m_musicID=getMusicID(name); - m_iMusicDelay=0; + m_StreamingAudioInfo.bIs3D=true; + m_musicID=getMusicID(name); + m_iMusicDelay=0; } } + int SoundEngine::GetRandomishTrack(int iStart,int iEnd) { // 4J-PB - make it more likely that we'll get a track we've not heard for a while, although repeating tracks sometimes is fine @@ -1305,7 +1322,7 @@ void SoundEngine::playMusicUpdate() m_StreamState=eMusicStreamState_Stop; // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_END); + m_musicID = getMusicID(eMusicDomain_End); SetIsPlayingEndMusic(true); SetIsPlayingNetherMusic(false); } @@ -1316,7 +1333,7 @@ void SoundEngine::playMusicUpdate() m_StreamState=eMusicStreamState_Stop; // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + m_musicID = getMusicID(eMusicDomain_Nether); SetIsPlayingEndMusic(false); SetIsPlayingNetherMusic(true); } @@ -1325,7 +1342,7 @@ void SoundEngine::playMusicUpdate() m_StreamState=eMusicStreamState_Stop; // Set the end track - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); + m_musicID = getMusicID(eMusicDomain_Overworld); SetIsPlayingEndMusic(false); SetIsPlayingNetherMusic(false); } @@ -1334,7 +1351,7 @@ void SoundEngine::playMusicUpdate() { m_StreamState=eMusicStreamState_Stop; // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + m_musicID = getMusicID(eMusicDomain_Nether); SetIsPlayingNetherMusic(true); SetIsPlayingEndMusic(false); } @@ -1344,7 +1361,7 @@ void SoundEngine::playMusicUpdate() { m_StreamState=eMusicStreamState_Stop; // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_END); + m_musicID = getMusicID(eMusicDomain_End); SetIsPlayingNetherMusic(false); SetIsPlayingEndMusic(true); } @@ -1352,7 +1369,7 @@ void SoundEngine::playMusicUpdate() { m_StreamState=eMusicStreamState_Stop; // set the Nether track - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); + m_musicID = getMusicID(eMusicDomain_Overworld); SetIsPlayingNetherMusic(false); SetIsPlayingEndMusic(false); } @@ -1432,19 +1449,19 @@ void SoundEngine::playMusicUpdate() } if(playerInEnd) { - m_musicID = getMusicID(LevelData::DIMENSION_END); + m_musicID = getMusicID(eMusicDomain_End); SetIsPlayingEndMusic(true); SetIsPlayingNetherMusic(false); } else if(playerInNether) { - m_musicID = getMusicID(LevelData::DIMENSION_NETHER); + m_musicID = getMusicID(eMusicDomain_Nether); SetIsPlayingNetherMusic(true); SetIsPlayingEndMusic(false); } else { - m_musicID = getMusicID(LevelData::DIMENSION_OVERWORLD); + m_musicID = getMusicID(eMusicDomain_Overworld); SetIsPlayingNetherMusic(false); SetIsPlayingEndMusic(false); } diff --git a/Minecraft.Client/Common/Audio/SoundEngine.h b/Minecraft.Client/Common/Audio/SoundEngine.h index 77d7b1dc..c8f6cafb 100644 --- a/Minecraft.Client/Common/Audio/SoundEngine.h +++ b/Minecraft.Client/Common/Audio/SoundEngine.h @@ -47,6 +47,11 @@ enum eMUSICFILES // The End eStream_end_dragon, eStream_end_end, + // Battle + eStream_BattleMode1, + eStream_BattleMode2, + eStream_BattleMode3, + eStream_BattleMode4, eStream_CD_1, eStream_CD_2, eStream_CD_3, @@ -62,6 +67,26 @@ enum eMUSICFILES eStream_Max, }; +// @3UR: This may not even be an enum—this is mostly guesswork. +// Why? Previously it used LevelData::DIMENSION_XXX enum, and it's unlikely they +// would have extended that with all this additional data. +// It also does not match up in IDA: LevelData::DIMENSION_END is 1, +// but now we see getMusicId(v5, 4); instead of 1. +// +// This suggests they likely introduced an entirely new enum. +// +// Additionally, there was never a case for 3, so it's skipped. +// That might indicate they extended an existing enum, but it's unclear. +enum eMUSICDOMAIN +{ + eMusicDomain_Nether = 0, + eMusicDomain_Overworld = 1, + eMusicDomain_Menu = 2, + eMusicDomain_End = 4, + eMusicDomain_Creative = 5, + eMusicDomain_Battle = 6, +}; + enum eMUSICTYPE { eMusicType_None, @@ -134,7 +159,7 @@ public: bool isStreamingWavebankReady(); // 4J Added int getMusicID(int iDomain); int getMusicID(const wstring& name); - void SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCD1); + void SetStreamingSounds(int iOverworldMin, int iOverWorldMax, int iNetherMin, int iNetherMax, int iEndMin, int iEndMax, int iCreativeMin, int iCreativeMax, int iMenuMin, int iMenuMax, int iBattleMin, int iBattleMax, int iCD1); void updateMiniAudio(); void playMusicUpdate(); @@ -184,6 +209,9 @@ private: int m_iStream_Overworld_Min,m_iStream_Overworld_Max; int m_iStream_Nether_Min,m_iStream_Nether_Max; int m_iStream_End_Min,m_iStream_End_Max; + int m_iStream_Creative_Min,m_iStream_Creative_Max; + int m_iStream_Menu_Min,m_iStream_Menu_Max; + int m_iStream_Battle_Min,m_iStream_Battle_Max; int m_iStream_CD_1; bool *m_bHeardTrackA; diff --git a/Minecraft.Client/Common/Colours/ColourTable.cpp b/Minecraft.Client/Common/Colours/ColourTable.cpp index 72a4780c..335240c8 100644 --- a/Minecraft.Client/Common/Colours/ColourTable.cpp +++ b/Minecraft.Client/Common/Colours/ColourTable.cpp @@ -37,6 +37,7 @@ const wchar_t *ColourTable::ColourTableElements[eMinecraftColour_COUNT] = L"Foliage_JungleHills", L"Foliage_Savanna", L"Foliage_RoofedForest", + L"Foliage_Mesa", L"Grass_Common", L"Grass_Ocean", @@ -64,6 +65,7 @@ const wchar_t *ColourTable::ColourTableElements[eMinecraftColour_COUNT] = L"Grass_JungleHills", L"Grass_Savanna", L"Grass_RoofedForest", + L"Grass_Mesa", L"Water_Ocean", L"Water_Plains", @@ -88,6 +90,7 @@ const wchar_t *ColourTable::ColourTableElements[eMinecraftColour_COUNT] = L"Water_ExtremeHillsEdge", L"Water_Jungle", L"Water_JungleHills", + L"Water_Mesa", L"Sky_Ocean", L"Sky_Plains", @@ -265,17 +268,23 @@ const wchar_t *ColourTable::ColourTableElements[eMinecraftColour_COUNT] = L"Mob_Endermite_Colour1", L"Mob_Endermite_Colour2", + + L"Armour_Default_Leather_Colour", + + L"Under_Water_Clear_Colour", L"Under_Lava_Clear_Colour", L"In_Cloud_Base_Colour", + L"Under_Water_Fog_Colour", L"Under_Lava_Fog_Colour", L"In_Cloud_Fog_Colour", + L"Default_Fog_Colour", L"Nether_Fog_Colour", L"End_Fog_Colour", @@ -333,14 +342,19 @@ const wchar_t *ColourTable::ColourTableElements[eMinecraftColour_COUNT] = void ColourTable::staticCtor() { - for(unsigned int i = eMinecraftColour_NOT_SET; i < eMinecraftColour_COUNT; ++i) + for(unsigned int i = 0; i < eMinecraftColour_COUNT; ++i) { + // Critical check: Stop if we hit a NULL pointer or reach the end of the defined array + if (i >= _countof(ColourTableElements) || ColourTableElements[i] == nullptr) + break; + s_colourNamesMap.insert( unordered_map::value_type( ColourTableElements[i], static_cast(i)) ); } } ColourTable::ColourTable(PBYTE pbData, DWORD dwLength) { + XMemSet(m_colourValues, 0, sizeof(m_colourValues)); loadColoursFromData(pbData, dwLength); } @@ -376,7 +390,11 @@ void ColourTable::setColour(const wstring &colourName, int value) auto it = s_colourNamesMap.find(colourName); if(it != s_colourNamesMap.end()) { - m_colourValues[static_cast(it->second)] = value; + int id = static_cast(it->second); + if (id >= 0 && id < eMinecraftColour_COUNT) + { + m_colourValues[id] = value; + } } } @@ -387,5 +405,10 @@ void ColourTable::setColour(const wstring &colourName, const wstring &value) unsigned int ColourTable::getColour(eMinecraftColour id) { - return m_colourValues[static_cast(id)]; + int idx = static_cast(id); + if (idx >= 0 && idx < eMinecraftColour_COUNT) + { + return m_colourValues[idx]; + } + return 0; // Return black for invalid IDs } diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index f5ede7d9..8c7f979e 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -3791,10 +3791,13 @@ void CMinecraftApp::HandleXuiActions(void) // need to stop the streaming audio - by playing streaming audio from the default texture pack now // reset the streaming sounds back to the normal ones #ifndef _XBOX - pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, - eStream_Nether1,eStream_Nether4, - eStream_end_dragon,eStream_end_end, - eStream_CD_1); + pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, + eStream_Nether1,eStream_Nether4, + eStream_end_dragon,eStream_end_end, + eStream_Overworld_Creative1,eStream_Overworld_Creative6, + eStream_Overworld_Menu1,eStream_Overworld_Menu4, + eStream_BattleMode1,eStream_BattleMode4, + eStream_CD_1); #endif pMinecraft->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); diff --git a/Minecraft.Client/Common/DLC/DLCAudioFile.cpp b/Minecraft.Client/Common/DLC/DLCAudioFile.cpp index 85ea3095..cbf4008c 100644 --- a/Minecraft.Client/Common/DLC/DLCAudioFile.cpp +++ b/Minecraft.Client/Common/DLC/DLCAudioFile.cpp @@ -26,10 +26,12 @@ PBYTE DLCAudioFile::getData(DWORD &dwBytes) return m_pbData; } +// @3UR: thanks https://github.com/LCERD/PCK-Studio/blob/500fc74395ce99fe20cbd7598999bfab3b606745/PckStudio.Core/IO/PckAudio/PckAudioFileWriter.cs#L15 const WCHAR *DLCAudioFile::wchTypeNamesA[]= { - L"CUENAME", - L"CREDIT", + L"CUENAME", + L"CREDIT", + L"CREDITID", }; DLCAudioFile::EAudioParameterType DLCAudioFile::getParameterType(const wstring ¶mName) @@ -76,7 +78,7 @@ void DLCAudioFile::addParameter(EAudioType type, EAudioParameterType ptype, cons case XC_LANGUAGE_JAPANESE: case XC_LANGUAGE_TCHINESE: case XC_LANGUAGE_KOREAN: - maximumChars = 35; + maximumChars = 55; // @3UR: this is 55 in TU30 break; } wstring creditValue = value; @@ -88,23 +90,6 @@ void DLCAudioFile::addParameter(EAudioType type, EAudioParameterType ptype, cons i++; } size_t iLast=creditValue.find_last_of(L" ", i); - switch(XGetLanguage()) - { - case XC_LANGUAGE_JAPANESE: - case XC_LANGUAGE_TCHINESE: - case XC_LANGUAGE_KOREAN: - iLast = maximumChars; - break; - default: - iLast=creditValue.find_last_of(L" ", i); - break; - } - - // if a space was found, include the space on this line - if(iLast!=i) - { - iLast++; - } app.AddCreditText((creditValue.substr(0, iLast)).c_str()); creditValue = creditValue.substr(iLast); @@ -117,6 +102,9 @@ void DLCAudioFile::addParameter(EAudioType type, EAudioParameterType ptype, cons m_parameters[type].push_back(value); //m_parameters[(int)type] = value; break; + // @3UR: in IDA for TU30 this is literally just empty... + case e_AudioParamType_CreditId: + break; } } @@ -170,6 +158,14 @@ bool DLCAudioFile::processDLCDataFile(PBYTE pbData, DWORD dwLength) for(unsigned int i=0;i(pFile->dwType); + + //Bounds Checking + if (type < 0 || type >= e_AudioType_Max) + { + app.DebugPrintf("Error parser: EAudioType (%d) out of bounds!\n", type); + + continue; + } // Params unsigned int uiParameterCount=*(unsigned int *)pbTemp; pbTemp+=sizeof(int); @@ -182,7 +178,8 @@ bool DLCAudioFile::processDLCDataFile(PBYTE pbData, DWORD dwLength) if(it != parameterMapping.end() ) { - addParameter(type,static_cast(pParams->dwType),(WCHAR *)pParams->wchData); + //addParameter(type,static_cast(pParams->dwType),(WCHAR *)pParams->wchData); + addParameter(type, it->second, (WCHAR *)pParams->wchData); } pbTemp+=sizeof(C4JStorage::DLC_FILE_PARAM)+(sizeof(WCHAR)*pParams->dwWchCount); pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; diff --git a/Minecraft.Client/Common/DLC/DLCAudioFile.h b/Minecraft.Client/Common/DLC/DLCAudioFile.h index 50131785..429dab3b 100644 --- a/Minecraft.Client/Common/DLC/DLCAudioFile.h +++ b/Minecraft.Client/Common/DLC/DLCAudioFile.h @@ -14,7 +14,15 @@ public: e_AudioType_Overworld = 0, e_AudioType_Nether, - e_AudioType_End, + e_AudioType_End, + + // @3UR: thanks https://github.com/LCERD/PCK-Studio/blob/500fc74395ce99fe20cbd7598999bfab3b606745/PckStudio.Core/FileFormats/PckAudioFile.cs#L25 + e_AudioType_Creative, + e_AudioType_Menu, + e_AudioType_Battle, + e_AudioType_Tumble, + e_AudioType_Glide, + e_AudioType_BuildOff, e_AudioType_Max, }; @@ -24,6 +32,7 @@ public: e_AudioParamType_Cuename = 0, e_AudioParamType_Credit, + e_AudioParamType_CreditId, e_AudioParamType_Max, diff --git a/Minecraft.Client/Common/UI/UIController.cpp b/Minecraft.Client/Common/UI/UIController.cpp index 05ade3f9..d582fe93 100644 --- a/Minecraft.Client/Common/UI/UIController.cpp +++ b/Minecraft.Client/Common/UI/UIController.cpp @@ -2064,10 +2064,13 @@ void UIController::NavigateToHomeMenu() { // need to stop the streaming audio - by playing streaming audio from the default texture pack now // reset the streaming sounds back to the normal ones - pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, - eStream_Nether1,eStream_Nether4, - eStream_end_dragon,eStream_end_end, - eStream_CD_1); + pMinecraft->soundEngine->SetStreamingSounds(eStream_Overworld_Calm1,eStream_Overworld_piano3, + eStream_Nether1,eStream_Nether4, + eStream_end_dragon,eStream_end_end, + eStream_Overworld_Creative1,eStream_Overworld_Creative6, + eStream_Overworld_Menu1,eStream_Overworld_Menu4, + eStream_BattleMode1,eStream_BattleMode4, + eStream_CD_1); pMinecraft->soundEngine->playStreaming(L"", 0, 0, 0, 1, 1); // if(pDLCTexPack->m_pStreamedWaveBank!=nullptr) diff --git a/Minecraft.Client/Common/res/TitleUpdate/res/colours.col b/Minecraft.Client/Common/res/TitleUpdate/res/colours.col index 4f16a4e9..ae3fd62b 100644 Binary files a/Minecraft.Client/Common/res/TitleUpdate/res/colours.col and b/Minecraft.Client/Common/res/TitleUpdate/res/colours.col differ diff --git a/Minecraft.Client/Common/res/TitleUpdate/res/colours.xml b/Minecraft.Client/Common/res/TitleUpdate/res/colours.xml index 2e4e35f7..e9b3dade 100644 --- a/Minecraft.Client/Common/res/TitleUpdate/res/colours.xml +++ b/Minecraft.Client/Common/res/TitleUpdate/res/colours.xml @@ -30,6 +30,7 @@ + @@ -60,6 +61,7 @@ + @@ -85,6 +87,7 @@ + diff --git a/Minecraft.Client/DLCTexturePack.cpp b/Minecraft.Client/DLCTexturePack.cpp index 8fe1860b..2661ba65 100644 --- a/Minecraft.Client/DLCTexturePack.cpp +++ b/Minecraft.Client/DLCTexturePack.cpp @@ -473,18 +473,63 @@ int DLCTexturePack::packMounted(LPVOID pParam,int iPad,DWORD dwErr,DWORD dwLicen DLCAudioFile *dlcFile = static_cast(pack->getFile(DLCManager::e_DLCType_Audio, 0)); texturePack->setHasAudio(true); // init the streaming sound ids for this texture pack - int iOverworldStart, iNetherStart, iEndStart; - int iOverworldC, iNetherC, iEndC; + int iOverworldC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Overworld); + int iNetherC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Nether); + int iEndStart=iOverworldC+iNetherC; + int iEndC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_End); + int iAfterEnd=iOverworldC+iNetherC+iEndC; + int iCreativeC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Creative); - iOverworldStart=0; - iOverworldC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Overworld); - iNetherStart=iOverworldC; - iNetherC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Nether); - iEndStart=iOverworldC+iNetherC; - iEndC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_End); + int iCreativeStart, iCreativeRange; + if(iCreativeC) + { + iCreativeStart=iAfterEnd; + iCreativeRange=iCreativeC; + iAfterEnd+=iCreativeC; + } + else + { + iCreativeStart=0; + iCreativeRange=iOverworldC; + } - Minecraft::GetInstance()->soundEngine->SetStreamingSounds(iOverworldStart,iOverworldStart+iOverworldC-1, - iNetherStart,iNetherStart+iNetherC-1,iEndStart,iEndStart+iEndC-1,iEndStart+iEndC); // push the CD start to after + int iMenuC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Menu); + int iMenuStart, iMenuRange; + if(iMenuC) + { + iMenuStart=iAfterEnd; + iMenuRange=iMenuC; + iAfterEnd+=iMenuC; + } + else + { + iMenuStart=0; + iMenuRange=iOverworldC; + } + + int iBattleC=dlcFile->GetCountofType(DLCAudioFile::e_AudioType_Battle); + if(iBattleC) + { + Minecraft::GetInstance()->soundEngine->SetStreamingSounds( + 0,iOverworldC-1, + iOverworldC,iOverworldC+iNetherC-1, + iEndStart,iEndStart+iEndC-1, + iCreativeStart,iCreativeStart+iCreativeRange-1, + iMenuStart,iMenuStart+iMenuRange-1, + iAfterEnd,iAfterEnd+iBattleC-1, + iAfterEnd+iBattleC); + } + else + { + Minecraft::GetInstance()->soundEngine->SetStreamingSounds( + 0,iOverworldC-1, + iOverworldC,iOverworldC+iNetherC-1, + iEndStart,iEndStart+iEndC-1, + iCreativeStart,iCreativeStart+iCreativeRange-1, + iMenuStart,iMenuStart+iMenuRange-1, + 0,iOverworldC-1, + iAfterEnd); + } } #endif } diff --git a/Minecraft.Client/Gui.cpp b/Minecraft.Client/Gui.cpp index f3e99874..582f25bd 100644 --- a/Minecraft.Client/Gui.cpp +++ b/Minecraft.Client/Gui.cpp @@ -1164,6 +1164,7 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) wfeature[eTerrainFeature_Mineshaft] = L"Mineshaft: "; wfeature[eTerrainFeature_Village] = L"Village: "; wfeature[eTerrainFeature_Ravine] = L"Ravine: "; + wfeature[eTerrainFeature_OceanMonument] = L"Monument: "; // maxW in font units: physical width divided by font scale float maxW = (static_cast(g_rScreenWidth) - debugLeft - 8) / fontScale; @@ -1174,7 +1175,7 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) { FEATURE_DATA *pFeatureData = app.m_vTerrainFeatures[i]; int type = pFeatureData->eTerrainFeature; - if (type < eTerrainFeature_Stronghold || type > eTerrainFeature_Ravine) continue; + if (type < eTerrainFeature_Stronghold || type > eTerrainFeature_OceanMonument) continue; if (truncated[type]) continue; wstring itemInfo = L"[" + std::to_wstring(pFeatureData->x * 16) + L", " + std::to_wstring(pFeatureData->z * 16) + L"] "; @@ -1190,7 +1191,7 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse) } lines.push_back(L""); // Spacer - for (int i = eTerrainFeature_Stronghold; i <= static_cast(eTerrainFeature_Ravine); i++) + for (int i = eTerrainFeature_Stronghold; i <= static_cast(eTerrainFeature_OceanMonument); i++) { lines.push_back(wfeature[i]); } diff --git a/Minecraft.World/Biome.cpp b/Minecraft.World/Biome.cpp index f5991734..607b2099 100644 --- a/Minecraft.World/Biome.cpp +++ b/Minecraft.World/Biome.cpp @@ -11,69 +11,70 @@ #include "net.minecraft.world.level.biome.h" #include "PerlinNoise.h" + Biome *Biome::biomes[256]; -Biome *Biome::ocean = nullptr; -Biome *Biome::plains = nullptr; -Biome *Biome::desert = nullptr; -Biome *Biome::extremeHills = nullptr; -Biome *Biome::forest = nullptr; -Biome *Biome::taiga = nullptr; -Biome *Biome::swampland = nullptr; -Biome *Biome::river = nullptr; -Biome *Biome::hell = nullptr; -Biome *Biome::sky = nullptr; -Biome *Biome::frozenOcean = nullptr; -Biome *Biome::frozenRiver = nullptr; -Biome *Biome::iceFlats = nullptr; -Biome *Biome::iceMountains = nullptr; -Biome *Biome::mushroomIsland = nullptr; -Biome *Biome::mushroomIslandShore = nullptr; -Biome *Biome::beaches = nullptr; -Biome *Biome::desertHills = nullptr; -Biome *Biome::forestHills = nullptr; -Biome *Biome::taigaHills = nullptr; -Biome *Biome::smallerExtremeHills = nullptr; -Biome *Biome::jungle = nullptr; -Biome *Biome::jungleHills = nullptr; -Biome *Biome::jungleEdge = nullptr; -Biome *Biome::deepOcean = nullptr; -Biome *Biome::stoneBeach = nullptr; -Biome *Biome::coldBeach = nullptr; -Biome *Biome::birchForest = nullptr; -Biome *Biome::birchForestHills = nullptr; -Biome *Biome::roofedForest = nullptr; -Biome *Biome::coldTaiga = nullptr; -Biome *Biome::coldTaigaHills = nullptr; -Biome *Biome::megaTaiga = nullptr; -Biome *Biome::megaTaigaHills = nullptr; -Biome *Biome::extremeHills_plus = nullptr; -Biome *Biome::savanna = nullptr; -Biome *Biome::savannaPlateau = nullptr; -Biome *Biome::mesa = nullptr; -Biome *Biome::mesaPlateauF = nullptr; -Biome *Biome::mesaPlateau = nullptr; -Biome *Biome::theVoid = nullptr; -Biome *Biome::sunflowersPlains = nullptr; -Biome *Biome::desertM = nullptr; -Biome *Biome::extremeHillsM = nullptr; -Biome *Biome::flowerForest = nullptr; -Biome *Biome::taigaM = nullptr; -Biome *Biome::swamplandM = nullptr; -Biome *Biome::iceSpikes = nullptr; -Biome *Biome::jungleM = nullptr; -Biome *Biome::jungleEdgeM = nullptr; -Biome *Biome::birchForestM = nullptr; -Biome *Biome::birchForestHillsM = nullptr; -Biome *Biome::roofedForestM = nullptr; -Biome *Biome::coldTaigaM = nullptr; -Biome *Biome::redwoodTaiga = nullptr; -Biome *Biome::redwoodTaigaHills = nullptr; -Biome *Biome::extremeHills_plusM = nullptr; -Biome *Biome::savannaM = nullptr; -Biome *Biome::savannaPlateauM = nullptr; -Biome *Biome::mesaBryce = nullptr; -Biome *Biome::mesaPlateauFM = nullptr; +Biome *Biome::ocean = nullptr;//0 +Biome *Biome::plains = nullptr;//1 +Biome *Biome::desert = nullptr;//2 +Biome *Biome::extremeHills = nullptr;//3 +Biome *Biome::forest = nullptr;//4 +Biome *Biome::taiga = nullptr;//5 +Biome *Biome::swampland = nullptr;//6 +Biome *Biome::river = nullptr;//7 +Biome *Biome::hell = nullptr;//8 +Biome *Biome::sky = nullptr;//9 +Biome *Biome::frozenOcean = nullptr;//10 +Biome *Biome::frozenRiver = nullptr;//11 +Biome *Biome::iceFlats = nullptr;//12 +Biome *Biome::iceMountains = nullptr;//13 +Biome *Biome::mushroomIsland = nullptr;//14 +Biome *Biome::mushroomIslandShore = nullptr;//15 +Biome *Biome::beaches = nullptr;//16 +Biome *Biome::desertHills = nullptr;//17 +Biome *Biome::forestHills = nullptr;//18 +Biome *Biome::taigaHills = nullptr;//19 +Biome *Biome::smallerExtremeHills = nullptr;//20 +Biome *Biome::jungle = nullptr;//21 +Biome *Biome::jungleHills = nullptr;//22 +Biome *Biome::jungleEdge = nullptr;//23 +Biome *Biome::deepOcean = nullptr;//24 +Biome *Biome::stoneBeach = nullptr;//25 +Biome *Biome::coldBeach = nullptr;//26 +Biome *Biome::birchForest = nullptr;//27 +Biome *Biome::birchForestHills = nullptr;//28 +Biome *Biome::roofedForest = nullptr;//29 +Biome *Biome::coldTaiga = nullptr;//30 +Biome *Biome::coldTaigaHills = nullptr;//31 +Biome *Biome::megaTaiga = nullptr;//32 +Biome *Biome::megaTaigaHills = nullptr;//33 +Biome *Biome::extremeHills_plus = nullptr;//34 +Biome *Biome::savanna = nullptr;//35 +Biome *Biome::savannaPlateau = nullptr;//36 +Biome *Biome::mesa = nullptr;//37 +Biome *Biome::mesaPlateauF = nullptr;//38 +Biome *Biome::mesaPlateau = nullptr;//39 +Biome *Biome::theVoid = nullptr;//127 +Biome *Biome::sunflowersPlains = nullptr;//129 +Biome *Biome::desertM = nullptr;//130 +Biome *Biome::extremeHillsM = nullptr;//131 +Biome *Biome::flowerForest = nullptr;//132 +Biome *Biome::taigaM = nullptr;//133 +Biome *Biome::swamplandM = nullptr;//134 +Biome *Biome::iceSpikes = nullptr;//140 +Biome *Biome::jungleM = nullptr;//149 +Biome *Biome::jungleEdgeM = nullptr;//151 +Biome *Biome::birchForestM = nullptr;//155 +Biome *Biome::birchForestHillsM = nullptr;//156 +Biome *Biome::roofedForestM = nullptr;//157 +Biome *Biome::coldTaigaM = nullptr;//158 +Biome *Biome::redwoodTaiga = nullptr;//160 +Biome *Biome::redwoodTaigaHills = nullptr;//161 +Biome *Biome::extremeHills_plusM = nullptr;//162 +Biome *Biome::savannaM = nullptr;//163 +Biome *Biome::savannaPlateauM = nullptr;//164 +Biome *Biome::mesaBryce = nullptr;//165 +Biome *Biome::mesaPlateauFM = nullptr;//166 Biome *Biome::mesaPlateauM = nullptr;//167 void Biome::staticCtor() @@ -84,10 +85,10 @@ void Biome::staticCtor() Biome::extremeHills = (new ExtremeHillsBiome(3))->setColor(0x606060)->setName(L"Extreme Hills")->setDepthAndScale(0.3f, 1.5f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills, eMinecraftColour_Foliage_ExtremeHills, eMinecraftColour_Water_ExtremeHills,eMinecraftColour_Sky_ExtremeHills); Biome::forest = (new ForestBiome(4,0))->setColor(0x056621)->setName(L"Forest")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.7f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Forest, eMinecraftColour_Water_Forest,eMinecraftColour_Sky_Forest); Biome::taiga = (new TaigaBiome(5))->setColor(0x0b6659)->setName(L"Taiga")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.25f, 0.8f)->setDepthAndScale(0.1f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga); - Biome::coldTaiga = (new TaigaBiome(30))->setColor(0x0b6659)->setName(L"Cold Taiga")->setLeafColor(0x4EBA31)->setSnowCovered()->setTemperatureAndDownfall(-0.5f, 0.4f)->setDepthAndScale(0.1f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga); Biome::swampland = (new SwampBiome(6))->setColor(0x07F9B2)->setName(L"Swampland")->setLeafColor(0x8BAF48)->setDepthAndScale(-0.2f, 0.1f)->setTemperatureAndDownfall(0.8f, 0.9f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Swampland, eMinecraftColour_Foliage_Swampland, eMinecraftColour_Water_Swampland,eMinecraftColour_Sky_Swampland); Biome::river = (new RiverBiome(7))->setColor(0x0000ff)->setName(L"River")->setDepthAndScale(-0.5f, 0)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_River, eMinecraftColour_Foliage_River, eMinecraftColour_Water_River,eMinecraftColour_Sky_River); Biome::hell = (new HellBiome(8))->setColor(0xff0000)->setName(L"Hell")->setNoRain()->setTemperatureAndDownfall(2, 0)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Hell, eMinecraftColour_Foliage_Hell, eMinecraftColour_Water_Hell,eMinecraftColour_Sky_Hell); + Biome::sky = (new TheEndBiome(9))->setColor(0x8080ff)->setName(L"Sky")->setNoRain()->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Sky, eMinecraftColour_Foliage_Sky, eMinecraftColour_Water_Sky,eMinecraftColour_Sky_Sky); Biome::frozenOcean = (new OceanBiome(10))->setColor(0x9090a0)->setName(L"Frozen Ocean")->setSnowCovered()->setDepthAndScale(-1, 0.5f)->setTemperatureAndDownfall(0, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_FrozenOcean, eMinecraftColour_Foliage_FrozenOcean, eMinecraftColour_Water_FrozenOcean,eMinecraftColour_Sky_FrozenOcean); Biome::frozenRiver = (new RiverBiome(11))->setColor(0xa0a0ff)->setName(L"Frozen River")->setSnowCovered()->setDepthAndScale(-0.5f, 0)->setTemperatureAndDownfall(0, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_FrozenRiver, eMinecraftColour_Foliage_FrozenRiver, eMinecraftColour_Water_FrozenRiver,eMinecraftColour_Sky_FrozenRiver); @@ -95,34 +96,50 @@ void Biome::staticCtor() Biome::iceMountains = (new IceBiome(13))->setColor(0xa0a0a0)->setName(L"Ice Mountains")->setSnowCovered()->setDepthAndScale(0.3f, 1.3f)->setTemperatureAndDownfall(0, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_IceMountains, eMinecraftColour_Foliage_IceMountains, eMinecraftColour_Water_IceMountains,eMinecraftColour_Sky_IceMountains); Biome::mushroomIsland = (new MushroomIslandBiome(14))->setColor(0xff00ff)->setName(L"Mushroom Island")->setTemperatureAndDownfall(0.9f, 1.0f)->setDepthAndScale(0.2f, 1.0f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_MushroomIsland, eMinecraftColour_Foliage_MushroomIsland, eMinecraftColour_Water_MushroomIsland,eMinecraftColour_Sky_MushroomIsland); Biome::mushroomIslandShore = (new MushroomIslandBiome(15))->setColor(0xa000ff)->setName(L"Mushroom Island Shore")->setTemperatureAndDownfall(0.9f, 1.0f)->setDepthAndScale(-1, 0.1f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_MushroomIslandShore, eMinecraftColour_Foliage_MushroomIslandShore, eMinecraftColour_Water_MushroomIslandShore,eMinecraftColour_Sky_MushroomIslandShore); + + Biome::beaches = (new BeachBiome(16))->setColor(0xfade55)->setName(L"Beach")->setTemperatureAndDownfall(0.8f, 0.4f)->setDepthAndScale(0.0f, 0.1f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Beach, eMinecraftColour_Foliage_Beach, eMinecraftColour_Water_Beach,eMinecraftColour_Sky_Beach); + Biome::desertHills = (new DesertBiome(17))->setColor(0xd25f12)->setName(L"Desert Hills")->setNoRain()->setTemperatureAndDownfall(2, 0)->setDepthAndScale(0.3f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_DesertHills, eMinecraftColour_Foliage_DesertHills, eMinecraftColour_Water_DesertHills,eMinecraftColour_Sky_DesertHills); + Biome::forestHills = (new ForestBiome(18,0))->setColor(0x22551c)->setName(L"Forest Hills")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.7f, 0.8f)->setDepthAndScale(0.3f, 0.7f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_ForestHills, eMinecraftColour_Water_ForestHills,eMinecraftColour_Sky_ForestHills); + Biome::taigaHills = (new TaigaBiome(19))->setColor(0x163933)->setName(L"Taiga Hills")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.25f, 0.8f)->setDepthAndScale(0.3f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_TaigaHills, eMinecraftColour_Foliage_TaigaHills, eMinecraftColour_Water_TaigaHills,eMinecraftColour_Sky_TaigaHills); Biome::smallerExtremeHills = (new ExtremeHillsBiome(20))->setColor(0x72789a)->setName(L"Extreme Hills Edge")->setDepthAndScale(0.2f, 0.8f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHillsEdge, eMinecraftColour_Foliage_ExtremeHillsEdge, eMinecraftColour_Water_ExtremeHillsEdge,eMinecraftColour_Sky_ExtremeHillsEdge); Biome::jungle = (new JungleBiome(21, false))->setColor(0x537b09)->setName(L"Jungle")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(0.2f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_Jungle,eMinecraftColour_Sky_Jungle); Biome::jungleHills = (new JungleBiome(22, false))->setColor(0x2c4205)->setName(L"Jungle Hills")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(1.8f, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_JungleHills, eMinecraftColour_Foliage_JungleHills, eMinecraftColour_Water_JungleHills,eMinecraftColour_Sky_JungleHills); - //23 + Biome::jungleEdge = (new JungleBiome(23, true))->setColor(0x6458135)->setName(L"Jungle Edge")->setLeafColor(0x5470985)->setTemperatureAndDownfall(0.95F, 0.8F); Biome::deepOcean= (new OceanBiome(24))->setName(L"Deep Ocean")->setDepthAndScale(-1.8,0.1f)->setColor(0x000070)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Ocean, eMinecraftColour_Foliage_Ocean, eMinecraftColour_Water_Ocean,eMinecraftColour_Sky_Ocean);; - //25 - //26 + //public static final BiomeGenBase stoneBeach = (new BiomeGenStoneBeach(25)).setColor(10658436).setBiomeName("Stone Beach").setTemperatureRainfall(0.2F, 0.3F).setHeight(height_RockyWaters); + Biome::coldBeach = (new BeachBiome(26))->setColor(0xFAF0C0)->setName(L"Cold Beach")->setTemperatureAndDownfall(0.05F, 0.3F)->setDepthAndScale(0.0F, 0.025F)->setSnowCovered()->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_IcePlains, eMinecraftColour_Foliage_IcePlains, eMinecraftColour_Water_IcePlains, eMinecraftColour_Sky_IcePlains); Biome::birchForest=(new ForestBiome(27, 2))->setColor(0x307444)->setName(L"Birch Forest")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest); Biome::birchForestHills=(new ForestBiome(28, 2))->setColor(0x1f5f32)->setName(L"Birch Forest Hills")->setDepthAndScale(0.45f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_ForestHills); Biome::roofedForest = (new ForestBiome(29, 3))->setColor(0x056621)->setName(L"Roofed Forest")->setTemperatureAndDownfall(0.7f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_RoofedForest, eMinecraftColour_Foliage_RoofedForest, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest); - //30 - //31 + Biome::coldTaiga = (new TaigaBiome(30))->setColor(0x0b6659)->setName(L"Cold Taiga")->setLeafColor(0x4EBA31)->setSnowCovered()->setTemperatureAndDownfall(-0.5f, 0.4f)->setDepthAndScale(0.1f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga); Biome::coldTaigaHills = (new TaigaBiome(31))->setColor(0x163933)->setName(L"Cold Taiga Hills")->setLeafColor(0x4EBA31)->setSnowCovered()->setTemperatureAndDownfall(-0.5f, 0.4f)->setDepthAndScale(0.3f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_TaigaHills, eMinecraftColour_Foliage_TaigaHills, eMinecraftColour_Water_TaigaHills,eMinecraftColour_Sky_TaigaHills); Biome::megaTaiga = (new TaigaBiome(32,1))->setColor(0x0b6659)->setName(L"Mega Taiga")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.3f, 0.8f)->setDepthAndScale(0.1f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga); Biome::megaTaigaHills = (new TaigaBiome(33,2))->setColor(0x0b6659)->setName(L"Mega Taiga Hills")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.3f, 0.8f)->setDepthAndScale(0.3f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_TaigaHills, eMinecraftColour_Foliage_TaigaHills, eMinecraftColour_Water_TaigaHills,eMinecraftColour_Sky_TaigaHills); Biome::savanna = (new SavannaBiome(35))->setColor(0xbda235)->setName(L"Savanna")->setNoRain()->setTemperatureAndDownfall(1.2f, 0.0f) ->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Savanna, eMinecraftColour_Foliage_Savanna, eMinecraftColour_Sky_Desert, eMinecraftColour_Sky_Desert); + Biome::savannaPlateau = (new SavannaBiome(36))->setColor(0xa79d64)->setName(L"Savanna Plateau")->setNoRain()->setTemperatureAndDownfall(1.0f, 0.0f)->setDepthAndScale(1.5f, 0.025f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Savanna, eMinecraftColour_Foliage_Savanna, eMinecraftColour_Sky_Desert, eMinecraftColour_Sky_Desert); + Biome::mesa = (new MesaBiome(37, false, false))->setColor(0xd94515)->setName(L"Mesa")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert); + Biome::mesaPlateauF = (new MesaBiome(38, true, true))->setColor(0xb09765)->setName(L"Mesa Plateau F")->setDepthAndScale(1.5f, 0.025f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert); + Biome::mesaPlateau = (new MesaBiome(39, true, false))->setColor(0xca5936)->setName(L"Mesa Plateau")->setDepthAndScale(1.5f, 0.025f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert); + Biome::sunflowersPlains = (new PlainsBiome(129,true))->setColor(0x8db360)->setName(L"Sunflowers Plains")->setTemperatureAndDownfall(0.8f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Plains, eMinecraftColour_Foliage_Plains, eMinecraftColour_Water_Plains,eMinecraftColour_Sky_Plains); - Biome::flowerForest = (new ForestBiome(132, 1))->setColor(0x056621)->setName(L"Flower Forest")->setTemperatureAndDownfall(0.7f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Forest, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest); + Biome::flowerForest = (new ForestBiome(132, 1))->setColor(0x056621)->setName(L"Flower Forest")->setTemperatureAndDownfall(0.7f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Forest, eMinecraftColour_Water_Forest,eMinecraftColour_Sky_Forest); Biome::iceSpikes = (new IceBiome(140,true))->setColor(0xffffff)->setName(L"Ice Spikes")->setSnowCovered()->setTemperatureAndDownfall(0, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_IcePlains, eMinecraftColour_Foliage_IcePlains, eMinecraftColour_Water_IcePlains,eMinecraftColour_Sky_IcePlains); Biome::birchForestM=(new ForestBiome::MutatedBirchForestBiome(155, biomes[27]))->setColor(0x47875a)->setName(L"Birch Forest M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest); Biome::birchForestHillsM=(new ForestBiome::MutatedBirchForestBiome(156, biomes[28]))->setColor(0x47875a)->setName(L"Birch Forest Hills M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_ForestHills); Biome::roofedForestM=(new ForestBiome::MutatedForestBiome(157, biomes[29]))->setColor(0x177a35)->setName(L"Roofed Forest M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_RoofedForest, eMinecraftColour_Foliage_RoofedForest, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest); + + Biome::savannaM = (new MutatedSavannaBiome(163, biomes[35]))->setColor(0xe5da87)->setName(L"Savanna M")->setNoRain()->setTemperatureAndDownfall(1.1f, 0.0f)->setDepthAndScale(0.35f, 1.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Savanna, eMinecraftColour_Foliage_Savanna, eMinecraftColour_Sky_Desert, eMinecraftColour_Sky_Desert); + Biome::savannaPlateauM = (new MutatedSavannaBiome(164, biomes[36]))->setColor(0xd1c890)->setName(L"Savanna Plateau M")->setNoRain()->setTemperatureAndDownfall(1.0f, 0.0f)->setDepthAndScale(1.05f, 1.2125f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Savanna, eMinecraftColour_Foliage_Savanna, eMinecraftColour_Sky_Desert, eMinecraftColour_Sky_Desert); + + Biome::mesaBryce = (new MesaBiome(165, false, false))->setColor(0xd94515)->setName(L"Mesa (Bryce)")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert); + Biome::mesaPlateauFM = (new MesaBiome(166, true, true))->setColor(0xb09765)->setName(L"Mesa Plateau F M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert); + Biome::mesaPlateauM = (new MesaBiome(167, true, false))->setColor(0xca5936)->setName(L"Mesa Plateau M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert); } @@ -145,6 +162,8 @@ Biome::Biome(int id) : id(id) m_foliageColor = eMinecraftColour_NOT_SET; m_waterColor = eMinecraftColour_NOT_SET; + + biomes[id] = this; decorator = createDecorator(); @@ -315,17 +334,32 @@ void Biome::decorate(Level *level, Random *random, int xo, int zo) int Biome::getGrassColor() const { - return Minecraft::GetInstance()->getColourTable()->getColor( m_grassColor ); + Minecraft* pMc = Minecraft::GetInstance(); + if (pMc && pMc->getColourTable()) + { + return pMc->getColourTable()->getColor(m_grassColor); + } + return 0x00FF00; // Default green if not ready } -int Biome::getFoliageColor() const +int Biome::getFolageColor() const { - return Minecraft::GetInstance()->getColourTable()->getColor( m_foliageColor ); + Minecraft* pMc = Minecraft::GetInstance(); + if (pMc && pMc->getColourTable()) + { + return pMc->getColourTable()->getColor(m_foliageColor); + } + return 0x00FF00; // Default green if not ready } int Biome::getWaterColor() { - return Minecraft::GetInstance()->getColourTable()->getColor( m_waterColor ); + Minecraft* pMc = Minecraft::GetInstance(); + if (pMc && pMc->getColourTable()) + { + return pMc->getColourTable()->getColor(m_waterColor); + } + return 0x0000FF; // Default blue if not ready } float Biome::getTemperature(int x, int y, int z) @@ -352,12 +386,14 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock int noiseDepth = (int)(noiseVal / 3.0 + 3.0 + random->nextDouble() * 0.25); int localX = x & 15; int localZ = z & 15; + int seaLevel = level->seaLevel; - for (int y = 255; y >= 0; --y) + for (int y = Level::genDepthMinusOne; y >= 0; --y) { - int index = (localX * 16 + localZ) * 256 + y; + + int index = (localZ * 16 + localX) * Level::genDepth + y; - if (y <= random->nextInt(5)) + if (y <= 1 + random->nextInt(2)) { chunkBlocks[index] = static_cast(Tile::unbreakable_Id); continue; @@ -378,28 +414,28 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock topState = 0; fillerState = static_cast(Tile::stone_Id); } - else if (y >= 59 && y <= 64) + else if (y >= seaLevel - 4 && y <= seaLevel + 1) { topState = this->topMaterial; fillerState = this->material; } - if (y < 63 && topState == 0) + if (y < seaLevel && topState == 0) { if (this->getTemperature(x, y, z) < 0.15f) { topState = static_cast(Tile::ice_Id); } else { - topState = static_cast(Tile::water_Id); + topState = static_cast(Tile::calmWater_Id); } } runDepth = noiseDepth; - if (y >= 62) + if (y >= seaLevel - 1) { chunkBlocks[index] = topState; } - else if (y < 56 - noiseDepth) + else if (y < seaLevel - 7 - noiseDepth) { topState = 0; fillerState = static_cast(Tile::stone_Id); @@ -425,6 +461,23 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock } } +void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, byte* chunkData, int x, int z, double noiseVal) +{ + buildSurfaceAtDefault(level, random, chunkBlocks, x, z, noiseVal); + + int localX = x & 15; + int localZ = z & 15; + + for (int y = Level::genDepthMinusOne; y >= 0; --y) + { + int index = (localZ * 16 + localX) * Level::genDepth + y; + byte blockId = chunkBlocks[index]; + if (blockId == this->topMaterial && this->topMaterialData != 0) + chunkData[index] = this->topMaterialData; + else if (blockId == this->material && this->materialData != 0) + chunkData[index] = this->materialData; + } +} float Biome::getTemperature(const BlockPos& pos) { return getTemperature(pos.getX(), pos.getY(), pos.getZ()); @@ -451,7 +504,7 @@ int Biome::getTemperatureCategory() const void Biome::buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal) { - buildSurfaceAtDefault(level, random, primer->getBlockIds(), x, z, noiseVal); + buildSurfaceAtDefault(level, random, primer->getBlockIds(), primer->getBlockData(), x, z, noiseVal); } Feature *Biome::getFlowerFeature(Random *random, int x, int y, int z) diff --git a/Minecraft.World/Biome.h b/Minecraft.World/Biome.h index c3f94e31..39298ee8 100644 --- a/Minecraft.World/Biome.h +++ b/Minecraft.World/Biome.h @@ -101,7 +101,9 @@ public: wstring m_name; int color; byte topMaterial; + byte topMaterialData; byte material; + byte materialData; int leafColor; float depth; float scale; @@ -197,13 +199,13 @@ public: virtual void decorate(Level *level, Random *random, int xo, int zo); virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal); - + virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, const BlockPos& pos, double noiseVal); - + virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, byte* chunkData, int x, int z, double noiseVal); - virtual int getWaterColor(); + virtual int getWaterColor(); public: @@ -212,11 +214,10 @@ public: m_skyColor = (eMinecraftColour)skyRGB; } void setDebugName(const wstring& name) { m_name = name; } - int getWaterColor() const { return m_waterColor; } int getSkyColor() const { return m_skyColor; } virtual int getBaseBiomeId() const { return id; } - virtual int getFoliageColor() const; // rename from getFolageColor + virtual int getFolageColor() const; virtual bool isSame(const Biome* other) const; virtual int getTemperatureCategory() const; virtual void buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal); @@ -224,8 +225,6 @@ public: virtual float getCreatureProbability() const; virtual int getGrassColor() const; - virtual int Biome::getFolageColor()const{ - return getFoliageColor(); } virtual Feature *getFlowerFeature(Random *random, int x, int y, int z); virtual int getRandomDoublePlantType(Random *random); diff --git a/Minecraft.World/BiomeDecorator.cpp b/Minecraft.World/BiomeDecorator.cpp index f276c8c9..0ebadeed 100644 --- a/Minecraft.World/BiomeDecorator.cpp +++ b/Minecraft.World/BiomeDecorator.cpp @@ -55,7 +55,11 @@ void BiomeDecorator::_init() redStoneOreFeature = new OreFeature(Tile::redStoneOre_Id, 7); diamondOreFeature = new OreFeature(Tile::diamondOre_Id, 7); lapisOreFeature = new OreFeature(Tile::lapisOre_Id, 6); - + + graniteOreFeature = new OreFeature(Tile::stone_Id, StoneTile::GRANITE, 33); + dioriteOreFeature = new OreFeature(Tile::stone_Id, StoneTile::DIORITE, 33); + andesiteOreFeature = new OreFeature(Tile::stone_Id, StoneTile::ANDESITE, 33); + yellowFlowerFeature = new FlowerFeature(Tile::flower_Id); roseFlowerFeature = new FlowerFeature(Tile::rose_Id); brownMushroomFeature = new FlowerFeature(Tile::mushroom_brown_Id); @@ -214,11 +218,11 @@ void BiomeDecorator::decorate() } } - //int doublePlantsToGen = doublePlantCount; // <-- Usa una variabile specifica per bioma! + //int doublePlantsToGen = doublePlantCount; // //for (int i = 0; i < doublePlantsToGen; i++) //{ - // // Genera il punto centrale del cluster + // // int x = xo + random->nextInt(16) + 8; // int z = zo + random->nextInt(16) + 8; // int y = random->nextInt(Level::genDepth); @@ -228,7 +232,7 @@ void BiomeDecorator::decorate() // DoublePlantFeature* dpf = static_cast(doublePlantFeature); // dpf->setPlantType(plantType); // - // // La chiamata place() ora genererà il grappolo grazie al ciclo da 64 inserito nel Passo 1 + // // dpf->place(level, random, x, y, z); //} @@ -392,5 +396,10 @@ void BiomeDecorator::decorateOres() decorateDepthSpan(8, redStoneOreFeature, 0, Level::genDepth / 8); decorateDepthSpan(1, diamondOreFeature, 0, Level::genDepth / 8); decorateDepthAverage(1, lapisOreFeature, Level::genDepth / 8, Level::genDepth / 8); + + decorateDepthSpan(10, graniteOreFeature, 0, 80); + decorateDepthSpan(10, dioriteOreFeature, 0, 80); + decorateDepthSpan(10, andesiteOreFeature, 0, 80); + level->setInstaTick(false); } diff --git a/Minecraft.World/BiomeDecorator.h b/Minecraft.World/BiomeDecorator.h index dd70a2d1..2c7e9404 100644 --- a/Minecraft.World/BiomeDecorator.h +++ b/Minecraft.World/BiomeDecorator.h @@ -41,6 +41,9 @@ public: Feature *redStoneOreFeature; Feature *diamondOreFeature; Feature *lapisOreFeature; + Feature *graniteOreFeature; + Feature *dioriteOreFeature; + Feature *andesiteOreFeature; Feature *yellowFlowerFeature; Feature *roseFlowerFeature; Feature *brownMushroomFeature; diff --git a/Minecraft.World/BiomeInitLayer.cpp b/Minecraft.World/BiomeInitLayer.cpp index 648cf6ed..f813f890 100644 --- a/Minecraft.World/BiomeInitLayer.cpp +++ b/Minecraft.World/BiomeInitLayer.cpp @@ -4,12 +4,14 @@ #include "net.minecraft.world.level.h" #include "BiomeInitLayer.h" -BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptrparent, LevelType *levelType) : Layer(seed) +BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptr parent, LevelType *levelType) : Layer(seed) { this->parent = parent; + bLegacy1_1 = (levelType == LevelType::lvl_normal_1_1); - if(levelType == LevelType::lvl_normal_1_1) + if (bLegacy1_1) { + // 1.1 mode: flat list startBiomes = BiomeArray(6); startBiomes[0] = Biome::desert; startBiomes[1] = Biome::forest; @@ -20,30 +22,54 @@ BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptrparent, LevelType } else { - // Only use biomes that are actually initialized in Biome::staticCtor() - // to avoid null pointer crashes during world generation. - startBiomes = BiomeArray(14); - startBiomes[0] = Biome::desert; - startBiomes[1] = Biome::forest; - startBiomes[2] = Biome::extremeHills; - startBiomes[3] = Biome::swampland; - startBiomes[4] = Biome::plains; - startBiomes[5] = Biome::taiga; - startBiomes[6] = Biome::jungle; - startBiomes[7] = Biome::savanna; - startBiomes[8] = Biome::roofedForest; - startBiomes[9] = Biome::flowerForest; - startBiomes[10] = Biome::birchForest; - startBiomes[11] = Biome::sunflowersPlains; - startBiomes[12] = Biome::coldTaiga; - startBiomes[13] = Biome::megaTaiga; - //startBiomes[14] = Biome::iceSpikes; + + // + // RareBiomeLayer encodes a flag by setting k = plains->id + 128 + + // When rareBit is set and we would pick plains -> pick sunflowersPlains + + // desert biomes (Java: desert 30, savanna 20, plains 10 -> total 60) + desertBiomes = BiomeArray(6); + desertBiomes[0] = Biome::desert; + desertBiomes[1] = Biome::desert; + desertBiomes[2] = Biome::desert; + desertBiomes[3] = Biome::savanna; + desertBiomes[4] = Biome::savanna; + desertBiomes[5] = Biome::plains; + + // warm biomes (Java: forest, swamp, jungle, roofedForest, birchForest, plains...) + warmBiomes = BiomeArray(7); + warmBiomes[0] = Biome::forest; + warmBiomes[1] = Biome::swampland; + warmBiomes[2] = Biome::jungle; + warmBiomes[3] = Biome::roofedForest; + warmBiomes[4] = Biome::birchForest; + warmBiomes[5] = Biome::plains; + warmBiomes[6] = Biome::mesaPlateauF; + + // cool (Java: extremeHills, taiga, megaTaiga, forest, birchForest) + coolBiomes = BiomeArray(5); + coolBiomes[0] = Biome::extremeHills; + coolBiomes[1] = Biome::taiga; + coolBiomes[2] = Biome::megaTaiga; + coolBiomes[3] = Biome::forest; + coolBiomes[4] = Biome::birchForest; + + // icy (Java: iceFlats, coldTaiga) + icyBiomes = BiomeArray(3); + icyBiomes[0] = Biome::iceFlats; + icyBiomes[1] = Biome::iceFlats; + icyBiomes[2] = Biome::coldTaiga; } } BiomeInitLayer::~BiomeInitLayer() { delete [] startBiomes.data; + delete [] desertBiomes.data; + delete [] warmBiomes.data; + delete [] coolBiomes.data; + delete [] icyBiomes.data; } intArray BiomeInitLayer::getArea(int xo, int yo, int w, int h) @@ -56,33 +82,93 @@ intArray BiomeInitLayer::getArea(int xo, int yo, int w, int h) for (int x = 0; x < w; x++) { initRandom(x + xo, y + yo); - int old = b[x + y * w]; - if (old == 0) + int k = b[x + y * w]; + + // flat list + if (bLegacy1_1) { - result[x + y * w] = 0; - } - else if (old == Biome::mushroomIsland->id) - { - result[x + y * w] = old; - } - else if (old == 1) // Normal land - { - result[x + y * w] = startBiomes[nextRandom(startBiomes.length)]->id; - } - else // Snowy/Cold areas - { - int picked = startBiomes[nextRandom(startBiomes.length)]->id; - // Only let cold biomes remain in snowy areas, everything else becomes ice plains - if (picked == Biome::taiga->id || picked == Biome::coldTaiga->id || - picked == Biome::megaTaiga->id || picked == Biome::iceSpikes->id) + if (k == 0) { - result[x + y * w] = picked; + result[x + y * w] = 0; + } + else if (k == Biome::mushroomIsland->id) + { + result[x + y * w] = k; + } + else if (k == 1) + { + result[x + y * w] = startBiomes[nextRandom(startBiomes.length)]->id; + } + else // icy / cold + { + int picked = startBiomes[nextRandom(startBiomes.length)]->id; + if (picked == Biome::taiga->id || picked == Biome::coldTaiga->id || + picked == Biome::megaTaiga->id || picked == Biome::iceSpikes->id) + { + result[x + y * w] = picked; + } + else + { + result[x + y * w] = Biome::iceFlats->id; + } + } + continue; + } + + + + + // RareBiomeLayer sets k = plains->id + 128 when it picks a rare slot. + // plains->id = 1, so a rare plains = 129. We extract the high bit flag. + int rareBit = (k & 0xFF00) >> 8; // Java: (k & 3840) >> 8 + k = k & ~0xFF00; + + + if (k == 0 || k == Biome::ocean->id || k == Biome::deepOcean->id || + k == Biome::frozenOcean->id || k == Biome::frozenRiver->id) + { + result[x + y * w] = k; + } + + else if (k == Biome::mushroomIsland->id || k == Biome::mushroomIslandShore->id) + { + result[x + y * w] = k; + } + // Climate 1 & 2 & 3 + else if (k == 1 || k == 2 || k == 3) + { + if (rareBit > 0) + { + // If rare: pick from high-value variants + int r = nextRandom(3); + if (r == 0) result[x + y * w] = Biome::jungle->id; + else if (r == 1) result[x + y * w] = Biome::megaTaiga->id; + else result[x + y * w] = Biome::desertHills->id; } else { - result[x + y * w] = Biome::iceFlats->id; + + int r = nextRandom(20); + if (r < 6) result[x + y * w] = desertBiomes[nextRandom(desertBiomes.length)]->id; + else if (r < 13) result[x + y * w] = warmBiomes[nextRandom(warmBiomes.length)]->id; + else result[x + y * w] = coolBiomes[nextRandom(coolBiomes.length)]->id; } } + // Climate 4 + else if (k == 4 || k == Biome::iceFlats->id) + { + result[x + y * w] = icyBiomes[nextRandom(icyBiomes.length)]->id; + } + // Rare variant from RareBiomeLayer + else if (k == Biome::plains->id + 256) + { + result[x + y * w] = Biome::sunflowersPlains->id; + } + else + { + + result[x + y * w] = k; + } } } diff --git a/Minecraft.World/BiomeInitLayer.h b/Minecraft.World/BiomeInitLayer.h index 00bf3812..1907ef26 100644 --- a/Minecraft.World/BiomeInitLayer.h +++ b/Minecraft.World/BiomeInitLayer.h @@ -1,16 +1,25 @@ -#pragma once - -#include "Layer.h" - -class LevelType; - -class BiomeInitLayer : public Layer -{ -private: - BiomeArray startBiomes; - -public: - BiomeInitLayer(int64_t seed, shared_ptr parent, LevelType *levelType); - virtual ~BiomeInitLayer(); - intArray getArea(int xo, int yo, int w, int h); -}; \ No newline at end of file +#pragma once + +#include "Layer.h" + +class LevelType; + +class BiomeInitLayer : public Layer +{ +private: + + BiomeArray startBiomes; + + // matching Java GenLayerBiome + BiomeArray desertBiomes; + BiomeArray warmBiomes; + BiomeArray coolBiomes; + BiomeArray icyBiomes; + + bool bLegacy1_1; + +public: + BiomeInitLayer(int64_t seed, shared_ptr parent, LevelType *levelType); + virtual ~BiomeInitLayer(); + intArray getArea(int xo, int yo, int w, int h); +}; \ No newline at end of file diff --git a/Minecraft.World/BiomeSource.cpp b/Minecraft.World/BiomeSource.cpp index 649eec2b..b7592b1e 100644 --- a/Minecraft.World/BiomeSource.cpp +++ b/Minecraft.World/BiomeSource.cpp @@ -31,7 +31,7 @@ void BiomeSource::_init() playerSpawnBiomes.push_back(Biome::iceSpikes); } -void BiomeSource::_init(int64_t seed, LevelType *generator) +void BiomeSource::_init(int64_t seed, LevelType *generator, int xzSize) { _init(); @@ -48,15 +48,15 @@ BiomeSource::BiomeSource() } // 4J added -BiomeSource::BiomeSource(int64_t seed, LevelType *generator) +BiomeSource::BiomeSource(int64_t seed, LevelType *generator, int xzSize) { - _init(seed, generator); + _init(seed, generator, xzSize); } // 4J - removal of separate temperature & downfall layers brought forward from 1.2.3 BiomeSource::BiomeSource(Level *level) { - _init(level->getSeed(), level->getLevelData()->getGenerator()); + _init(level->getSeed(), level->getLevelData()->getGenerator(), level->getLevelData()->getXZSize()); } BiomeSource::~BiomeSource() @@ -595,12 +595,16 @@ bool BiomeSource::getIsMatch(float *frac) }; - // Don't want more than 15% ocean - if( frac[0] > 0.15f ) + // Don't want more than 15% ocean (normal + deep) + if (frac[0] + frac[24] > 0.15f) { return false; } + // But we need some ocean to be present (critical[0]) + frac[0] += frac[24]; + + // Consider mushroom shore & islands as the same by finding max frac[14] = ( ( frac[15] > frac[14] ) ? frac[15] : frac[14] ); diff --git a/Minecraft.World/BiomeSource.h b/Minecraft.World/BiomeSource.h index a1e8a50b..234e856e 100644 --- a/Minecraft.World/BiomeSource.h +++ b/Minecraft.World/BiomeSource.h @@ -25,11 +25,11 @@ private: protected: void _init(); - void _init(int64_t seed, LevelType *generator); + void _init(int64_t seed, LevelType *generator, int xzSize = 864); BiomeSource(); public: - BiomeSource(int64_t seed, LevelType *generator); + BiomeSource(int64_t seed, LevelType *generator, int xzSize = 864); BiomeSource(Level *level); private: static bool getIsMatch(float *frac); // 4J added diff --git a/Minecraft.World/BoundingBox.cpp b/Minecraft.World/BoundingBox.cpp index e93158f2..7aa206da 100644 --- a/Minecraft.World/BoundingBox.cpp +++ b/Minecraft.World/BoundingBox.cpp @@ -53,6 +53,19 @@ BoundingBox *BoundingBox::orientBox(int footX, int footY, int footZ, int offX, i } } +BoundingBox* BoundingBox::fromCorners(int x1, int y1, int z1, int x2, int y2, int z2) +{ + + return new BoundingBox( + x1 < x2 ? x1 : x2, + y1 < y2 ? y1 : y2, + z1 < z2 ? z1 : z2, + x1 > x2 ? x1 : x2, + y1 > y2 ? y1 : y2, + z1 > z2 ? z1 : z2 + ); +} + BoundingBox::BoundingBox(BoundingBox *other) { x0 = other->x0; diff --git a/Minecraft.World/BoundingBox.h b/Minecraft.World/BoundingBox.h index ac29883f..709573f2 100644 --- a/Minecraft.World/BoundingBox.h +++ b/Minecraft.World/BoundingBox.h @@ -11,6 +11,7 @@ public: BoundingBox(intArray sourceData); static BoundingBox *getUnknownBox(); static BoundingBox *orientBox(int footX, int footY, int footZ, int offX, int offY, int offZ, int width, int height, int depth, int orientation); + static BoundingBox *fromCorners(int x1, int y1, int z1, int x2, int y2, int z2); BoundingBox(BoundingBox *other); BoundingBox(int x0, int y0, int z0, int x1, int y1, int z1); BoundingBox(int x0, int z0, int x1, int z1); diff --git a/Minecraft.World/ChunkPrimer.cpp b/Minecraft.World/ChunkPrimer.cpp index 5443c448..66241103 100644 --- a/Minecraft.World/ChunkPrimer.cpp +++ b/Minecraft.World/ChunkPrimer.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "ChunkPrimer.h" #include "Tile.h" // for Tile::air (or your air tile) @@ -99,6 +99,11 @@ void ChunkPrimer::setBlockAndData(int x, int y, int z, int blockId, int data) setBlockAndData(getIndex(x, y, z), blockId, data); } +int ChunkPrimer::getBlockId(int x, int y, int z) const +{ + return getBlockId(getIndex(x, y, z)); +} + int ChunkPrimer::getState(int x, int y, int z) const { return getState(getIndex(x, y, z)); diff --git a/Minecraft.World/ChunkPrimer.h b/Minecraft.World/ChunkPrimer.h index 170716b7..12dca115 100644 --- a/Minecraft.World/ChunkPrimer.h +++ b/Minecraft.World/ChunkPrimer.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "stdafx.h" @@ -30,6 +30,7 @@ public: void setBlockAndData(int x, int y, int z, int blockId, int data); + int getBlockId(int x, int y, int z) const; int getState(int x, int y, int z) const; private: diff --git a/Minecraft.World/CustomLevelSource.cpp b/Minecraft.World/CustomLevelSource.cpp index 7281d298..a63802bd 100644 --- a/Minecraft.World/CustomLevelSource.cpp +++ b/Minecraft.World/CustomLevelSource.cpp @@ -108,9 +108,12 @@ CustomLevelSource::CustomLevelSource(Level *level, int64_t seed, bool generateSt mineShaftFeature = new MineShaftFeature(); scatteredFeature = new RandomScatteredLargeFeature(); canyonFeature = new CanyonFeature(); - + oceanMonument = new OceanMonumentFeature(); this->level = level; + oceanMonument->setLevel(level); // Link level reference + oceanMonument->prescanNearby(8); // Scan with access to seed/biomeSource + random = new Random(seed); pprandom = new Random(seed); // 4J - added, so that we can have a separate random for doing post-processing in parallel with creation perlinNoise3 = new PerlinNoise(random, 4); diff --git a/Minecraft.World/CustomLevelSource.h b/Minecraft.World/CustomLevelSource.h index 9a9cb8cf..761f045d 100644 --- a/Minecraft.World/CustomLevelSource.h +++ b/Minecraft.World/CustomLevelSource.h @@ -13,6 +13,7 @@ class StrongholdFeature; class VillageFeature; class MineShaftFeature; class RandomScatteredLargeFeature; +class OceanMonumentFeature; class CustomLevelSource : public ChunkSource { @@ -34,6 +35,7 @@ private: VillageFeature *villageFeature; MineShaftFeature *mineShaftFeature; RandomScatteredLargeFeature *scatteredFeature; + OceanMonumentFeature* oceanMonument; LargeFeature *canyonFeature; Level *level; #endif diff --git a/Minecraft.World/DeepOceanLayer.cpp b/Minecraft.World/DeepOceanLayer.cpp new file mode 100644 index 00000000..852b6f2f --- /dev/null +++ b/Minecraft.World/DeepOceanLayer.cpp @@ -0,0 +1,63 @@ +#include "stdafx.h" +#include "net.minecraft.world.level.biome.h" +#include "IntCache.h" +#include "DeepOceanLayer.h" + +DeepOceanLayer::DeepOceanLayer(int64_t seed, shared_ptr parent) : Layer(seed) +{ + this->parent = parent; +} + +intArray DeepOceanLayer::getArea(int xo, int yo, int w, int h) +{ + int i = xo - 1; + int j = yo - 1; + int k = w + 2; + int l = h + 2; + intArray aint = this->parent->getArea(i, j, k, l); + intArray aint1 = IntCache::allocate(w * h); + + for (int i1 = 0; i1 < h; ++i1) + { + for (int j1 = 0; j1 < w; ++j1) + { + int k1 = aint[j1 + 1 + (i1 + 1 - 1) * (w + 2)]; + int l1 = aint[j1 + 1 + 1 + (i1 + 1) * (w + 2)]; + int i2 = aint[j1 + 1 - 1 + (i1 + 1) * (w + 2)]; + int j2 = aint[j1 + 1 + (i1 + 1 + 1) * (w + 2)]; + int k2 = aint[j1 + 1 + (i1 + 1) * k]; + int l2 = 0; + + if (k1 == 0) + { + ++l2; + } + + if (l1 == 0) + { + ++l2; + } + + if (i2 == 0) + { + ++l2; + } + + if (j2 == 0) + { + ++l2; + } + + if (k2 == 0 && l2 > 3) + { + aint1[j1 + i1 * w] = Biome::deepOcean->id; + } + else + { + aint1[j1 + i1 * w] = k2; + } + } + } + + return aint1; +} diff --git a/Minecraft.World/DeepOceanLayer.h b/Minecraft.World/DeepOceanLayer.h new file mode 100644 index 00000000..4e345fee --- /dev/null +++ b/Minecraft.World/DeepOceanLayer.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Layer.h" + +class DeepOceanLayer : public Layer +{ +public: + DeepOceanLayer(int64_t seed, shared_ptr parent); + virtual ~DeepOceanLayer() {} + virtual intArray getArea(int xo, int yo, int w, int h) override; +}; diff --git a/Minecraft.World/Dimension.cpp b/Minecraft.World/Dimension.cpp index ea650ac3..82567c30 100644 --- a/Minecraft.World/Dimension.cpp +++ b/Minecraft.World/Dimension.cpp @@ -170,7 +170,12 @@ Vec3 *Dimension::getFogColor(float td, float a) const if (br < 0.0f) br = 0.0f; if (br > 1.0f) br = 1.0f; - unsigned int baseFogColour = Minecraft::GetInstance()->getColourTable()->getColor( eMinecraftColour_Default_Fog_Colour ); + unsigned int baseFogColour = 0x808080; // Gray default + Minecraft* pMc = Minecraft::GetInstance(); + if (pMc && pMc->getColourTable()) + { + baseFogColour = pMc->getColourTable()->getColor(eMinecraftColour_Default_Fog_Colour); + } float r = ((baseFogColour >> 16) & 0xff) / 255.0f; float g = ((baseFogColour >> 8) & 0xff) / 255.0f; float b = ((baseFogColour) & 0xff) / 255.0f; diff --git a/Minecraft.World/FishingHelper.cpp b/Minecraft.World/FishingHelper.cpp index 052670c7..dfa34b77 100644 --- a/Minecraft.World/FishingHelper.cpp +++ b/Minecraft.World/FishingHelper.cpp @@ -50,17 +50,16 @@ CatchType FishingHelper::getRandCatchType(int luck, Random* random) CatchTypeWeighedItem* catchTypeWeighedItem = nullptr; catchTypeArray.calcWeights(luck); // Recalculate the weights based on the luck level of the player catchTypeWeighedItem = static_cast(WeighedRandom::getRandomItem(random, catchTypeArray)); - return catchTypeWeighedItem->getType(); + return catchTypeWeighedItem->getType(); } CatchWeighedItem* FishingHelper::getRandCatch(CatchType catchType, Random* random) { - CatchWeighedItem* catchWeighedItem = nullptr; switch (catchType) { case CatchType::FISH: return static_cast(WeighedRandom::getRandomItem(random, fishingFishArray)); case CatchType::TREASURE: - return static_cast(WeighedRandom::getRandomItem(random, fishingTreasuresArray));; + return static_cast(WeighedRandom::getRandomItem(random, fishingTreasuresArray)); case CatchType::JUNK: return static_cast(WeighedRandom::getRandomItem(random, fishingJunkArray)); } diff --git a/Minecraft.World/Layer.cpp b/Minecraft.World/Layer.cpp index 7d9ffed9..7bb1677f 100644 --- a/Minecraft.World/Layer.cpp +++ b/Minecraft.World/Layer.cpp @@ -26,18 +26,21 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType *levelType) islandLayer = std::make_shared(1, islandLayer); islandLayer = std::make_shared(2001, islandLayer); islandLayer = std::make_shared(2, islandLayer); + islandLayer = std::make_shared(2, islandLayer); islandLayer = std::make_shared(2, islandLayer); islandLayer = std::make_shared(2002, islandLayer); islandLayer = std::make_shared(3, islandLayer); islandLayer = std::make_shared(2003, islandLayer); islandLayer = std::make_shared(4, islandLayer); + // islandLayer = shared_ptr(new AddMushroomIslandLayer(5, islandLayer)); // 4J - old position of mushroom island layer - int zoomLevel = 4; + int zoomLevel = 4; if (levelType == LevelType::lvl_largeBiomes) { - zoomLevel = 6; + zoomLevel = 6; } + shared_ptr riverLayer = islandLayer; riverLayer = ZoomLayer::zoom(1000, riverLayer, 0); @@ -48,10 +51,20 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType *levelType) shared_ptr biomeLayer = islandLayer; biomeLayer = ZoomLayer::zoom(1000, biomeLayer, 0); + biomeLayer = std::make_shared(200, biomeLayer, levelType); + biomeLayer = ZoomLayer::zoom(1000, biomeLayer, 2); - biomeLayer = std::make_shared(1000, biomeLayer); + + + shared_ptr hillsNoise = islandLayer; + hillsNoise = ZoomLayer::zoom(1000, hillsNoise, 0); + hillsNoise = std::make_shared(100, hillsNoise); + hillsNoise = ZoomLayer::zoom(1000, hillsNoise, 2); + + biomeLayer = std::make_shared(1000, biomeLayer, hillsNoise); + biomeLayer = std::make_shared(1001, biomeLayer); for (int i = 0; i < zoomLevel; i++) { @@ -65,6 +78,8 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType *levelType) // them at this scale actually lets us place them near enough other land, if we add them at the same scale as java then they have to be too far out to see for // the scale of our maps biomeLayer = std::make_shared(5, biomeLayer); + //Adding Deep Ocean here as well, now that we are at a suitable scale for LCE maps. + biomeLayer = std::make_shared(4, biomeLayer); } if (i == 1 ) diff --git a/Minecraft.World/MesaBiome.cpp b/Minecraft.World/MesaBiome.cpp new file mode 100644 index 00000000..8d06d5d5 --- /dev/null +++ b/Minecraft.World/MesaBiome.cpp @@ -0,0 +1,296 @@ +#include "stdafx.h" + + +#define _USE_MATH_DEFINES +#include +#include + +#include "MesaBiome.h" +#include "BiomeDecorator.h" +#include "net.minecraft.world.level.h" +#include "net.minecraft.world.level.tile.h" +#include "ColoredTile.h" +#include "SandTile.h" +#include "DirtTile.h" +#include "DyePowderItem.h" +#include "PerlinNoise.h" +#include "Random.h" + + +#undef max +#undef min + + +MesaBiome::MesaBiome(int id, bool mesaPlateau, bool hasTrees) : Biome(id) +{ + this->isMesaPlateau = mesaPlateau; + this->hasTrees = hasTrees; + + this->setNoRain(); + this->setTemperatureAndDownfall(2.0f, 0.0f); + + // Red Sand (id=12, data=1) + // Orange Stained Hardened Clay (id=159, data=1) + this->topMaterial = static_cast(Tile::sand_Id); + this->topMaterialData = static_cast(SandTile::RED_SAND); // 1 + this->material = static_cast(Tile::clayHardened_colored_Id); + this->materialData = static_cast(BAND_ORANGE); // 1 + + this->lastSeed = INVALID_SEED; + this->pillarNoise = nullptr; + this->pillarRoofNoise = nullptr; + this->clayBandsOffsetNoise = nullptr; + + + /*friendlies.clear(); + friendlies_chicken.clear(); + enemies.clear(); + waterFriendlies.clear(); + ambientFriendlies.clear();*/ + + + if (decorator) + { + decorator->treeCount = hasTrees ? 5 : -999; + decorator->deadBushCount = 20; + decorator->reedsCount = 3; + decorator->cactusCount = 5; + decorator->flowerCount = 0; + } +} + +MesaBiome::~MesaBiome() +{ + delete pillarNoise; + delete pillarRoofNoise; + delete clayBandsOffsetNoise; +} + + +void MesaBiome::initBands(int64_t /*seed*/) {} + + + + +int MesaBiome::getBandColor(int x, int y, int z) +{ + if (!clayBandsOffsetNoise) + return BAND_ORANGE; + + double noiseX = static_cast(x) / 512.0; + int offset = static_cast(std::round( + clayBandsOffsetNoise->getValue(noiseX, noiseX) * 2.0)); + + int index = ((y + offset) % 64 + 64) % 64; + return static_cast(static_cast(clayBands[index])); +} + + + +void MesaBiome::decorate(Level* level, Random* random, int xo, int zo) +{ + Biome::decorate(level, random, xo, zo); +} + +Feature* MesaBiome::getTreeFeature(Random* random) +{ + return Biome::getTreeFeature(random); +} + + + +void MesaBiome::buildSurfaceAtDefault(Level* level, Random* random, + byte* chunkBlocks, byte* chunkData, + int x, int z, double noiseVal) +{ + + int64_t seed = level->getSeed(); + if (lastSeed != seed) + { + lastSeed = seed; + + + std::fill(std::begin(clayBands), std::end(clayBands), + static_cast(BAND_HARDENED_CLAY)); + { + Random r(seed); + delete clayBandsOffsetNoise; + clayBandsOffsetNoise = new PerlinNoise(&r, 1); + + // Orange sparse + for (int i = 0; i < 64; ) + { + i += r.nextInt(5) + 1; + if (i < 64) clayBands[i] = static_cast(BAND_ORANGE); + } + // Yellow groups + int yg = r.nextInt(4) + 2; + for (int g = 0; g < yg; ++g) { + int t = r.nextInt(3) + 1, s = r.nextInt(64); + for (int k = 0; s + k < 64 && k < t; ++k) + clayBands[s + k] = static_cast(BAND_YELLOW); + } + // Brown groups + int bg = r.nextInt(4) + 2; + for (int g = 0; g < bg; ++g) { + int t = r.nextInt(3) + 2, s = r.nextInt(64); + for (int k = 0; s + k < 64 && k < t; ++k) + clayBands[s + k] = static_cast(BAND_BROWN); + } + // Red groups + int rg = r.nextInt(4) + 2; + for (int g = 0; g < rg; ++g) { + int t = r.nextInt(3) + 1, s = r.nextInt(64); + for (int k = 0; s + k < 64 && k < t; ++k) + clayBands[s + k] = static_cast(BAND_RED); + } + // White stripes + int ws = r.nextInt(3) + 3, cursor = 0; + for (int g = 0; g < ws; ++g) { + cursor += r.nextInt(16) + 4; + if (cursor >= 64) break; + clayBands[cursor] = static_cast(BAND_WHITE); + if (cursor > 1 && r.nextBoolean()) clayBands[cursor - 1] = static_cast(BAND_SILVER); + if (cursor < 63 && r.nextBoolean()) clayBands[cursor + 1] = static_cast(BAND_SILVER); + } + } + + + delete pillarNoise; pillarNoise = nullptr; + delete pillarRoofNoise; pillarRoofNoise = nullptr; + { + Random r(seed); + pillarNoise = new PerlinNoise(&r, 4); // field_150623_aE + pillarRoofNoise = new PerlinNoise(&r, 1); // field_150624_aF + } + } + + + const int seaLevel = level->seaLevel; + const int localX = x & 15; + const int localZ = z & 15; + + + int noiseDepth = (int)(noiseVal / 3.0 + 3.0 + random->nextDouble() * 0.25); + bool flag = (cos(noiseVal / 3.0 * PI) > 0.0); + + int run = -1; + bool flag1 = false; + + for (int y = Level::genDepthMinusOne; y >= 0; --y) + { + int index = (localX * 16 + localZ) * Level::genDepth + y; + + + if (y <= 1 + random->nextInt(2)) + { + chunkBlocks[index] = static_cast(Tile::unbreakable_Id); + continue; + } + + byte cur = chunkBlocks[index]; + + if (cur == 0) + { + run = -1; + } + else if (cur == static_cast(Tile::stone_Id)) + { + if (run == -1) + { + flag1 = false; + + + run = noiseDepth + (y > seaLevel ? (y - seaLevel) : 0); + + + if (y < seaLevel - 1) + { + if (noiseDepth <= 0) + { + chunkBlocks[index] = static_cast(Tile::stone_Id); + } + else + { + chunkBlocks[index] = static_cast(Tile::clayHardened_colored_Id); + chunkData[index] = static_cast(BAND_ORANGE); + } + } + else if (hasTrees && y > 86 + noiseDepth * 2) + { + if (flag) + { + chunkBlocks[index] = static_cast(Tile::grass_Id); + } + else + { + chunkBlocks[index] = static_cast(Tile::dirt_Id); + chunkData[index] = static_cast(DirtTile::COARSE_DIRT); + } + } + else if (y <= seaLevel + 3 + noiseDepth) + { + chunkBlocks[index] = static_cast(Tile::sand_Id); + chunkData[index] = static_cast(SandTile::RED_SAND); // 1 + flag1 = true; + } + else + { + if (y >= 64) + { + if (flag) + { + chunkBlocks[index] = static_cast(Tile::clayHardened_Id); + } + else + { + int band = getBandColor(x, y, z); + if (band == BAND_HARDENED_CLAY) + { + chunkBlocks[index] = static_cast(Tile::clayHardened_Id); + } + else + { + chunkBlocks[index] = static_cast(Tile::clayHardened_colored_Id); + chunkData[index] = static_cast(band); + } + } + } + else + { + chunkBlocks[index] = static_cast(Tile::clayHardened_colored_Id); + chunkData[index] = static_cast(BAND_ORANGE); + } + } + + if (y < seaLevel && chunkBlocks[index] == 0) + { + chunkBlocks[index] = (getTemperature(x, y, z) < 0.15f) + ? static_cast(Tile::ice_Id) + : static_cast(Tile::calmWater_Id); + } + } + else if (run > 0) + { + --run; + + if (flag1) + { + chunkBlocks[index] = static_cast(Tile::clayHardened_colored_Id); + chunkData[index] = static_cast(BAND_ORANGE); + } + else + { + int band = getBandColor(x, y, z); + if (band == BAND_HARDENED_CLAY) + chunkBlocks[index] = static_cast(Tile::clayHardened_Id); + else + { + chunkBlocks[index] = static_cast(Tile::clayHardened_colored_Id); + chunkData[index] = static_cast(band); + } + } + } + } + } +} \ No newline at end of file diff --git a/Minecraft.World/MesaBiome.h b/Minecraft.World/MesaBiome.h new file mode 100644 index 00000000..ded41fed --- /dev/null +++ b/Minecraft.World/MesaBiome.h @@ -0,0 +1,62 @@ +#pragma once +#include "Biome.h" +#include "PerlinNoise.h" +#include "Random.h" +#include + +class MesaBiome : public Biome +{ +public: + + static constexpr int BAND_HARDENED_CLAY = 255; + static constexpr int BAND_WHITE = 0; + static constexpr int BAND_ORANGE = 1; + static constexpr int BAND_YELLOW = 4; + static constexpr int BAND_BROWN = 12; + static constexpr int BAND_RED = 14; + static constexpr int BAND_SILVER = 8; + + + static constexpr int64_t INVALID_SEED = -1LL; + + + MesaBiome(int id, bool mesaPlateau, bool hasTrees); + virtual ~MesaBiome(); + + + + + virtual void decorate(Level* level, Random* random, + int xo, int zo) override; + + virtual Feature* getTreeFeature(Random* random) override; + + virtual void buildSurfaceAtDefault(Level* level, Random* random, + byte* chunkBlocks, byte* chunkData, + int x, int z, double noiseVal) override; + + +private: + + void initBands(int64_t seed); + + + int getBandColor(int x, int y, int z); + + + bool isMesaPlateau; + bool hasTrees; + + + int64_t lastSeed; + + + byte clayBands[64]; + + + PerlinNoise* clayBandsOffsetNoise; + + + PerlinNoise* pillarNoise; + PerlinNoise* pillarRoofNoise; +}; \ No newline at end of file diff --git a/Minecraft.World/MutatedBiome.cpp b/Minecraft.World/MutatedBiome.cpp index 48d6a2a6..08188f9f 100644 --- a/Minecraft.World/MutatedBiome.cpp +++ b/Minecraft.World/MutatedBiome.cpp @@ -59,8 +59,8 @@ int MutatedBiome::getGrassColor() const { return m_baseBiome ? m_baseBiome->getGrassColor() : Biome::getGrassColor(); } -int MutatedBiome::getFoliageColor() const { - return m_baseBiome ? m_baseBiome->getFoliageColor() : Biome::getFoliageColor(); +int MutatedBiome::getFolageColor() const { + return m_baseBiome ? m_baseBiome->getFolageColor() : Biome::getFolageColor(); } float MutatedBiome::getCreatureProbability() const diff --git a/Minecraft.World/MutatedBiome.h b/Minecraft.World/MutatedBiome.h index 0b75008d..12c8c61a 100644 --- a/Minecraft.World/MutatedBiome.h +++ b/Minecraft.World/MutatedBiome.h @@ -11,7 +11,7 @@ public: virtual Feature* getTreeFeature(Random* random) override; virtual void decorate(Level* level, Random* rand, int xo, int zo) override; virtual int getGrassColor() const override; - virtual int getFoliageColor() const override; + virtual int getFolageColor() const override; virtual float getCreatureProbability() const override; virtual bool isSame(const Biome* other) const override; virtual int getTemperatureCategory() const override; @@ -19,8 +19,8 @@ public: virtual int getRandomDoublePlantType(Random* random) override; virtual void buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal) override; - Biome* getBaseBiome() const { return m_baseBiome; } // Rimosso const + Biome* getBaseBiome() const { return m_baseBiome; } protected: - Biome* m_baseBiome; // Rimosso const + Biome* m_baseBiome; }; \ No newline at end of file diff --git a/Minecraft.World/OceanBiome.h b/Minecraft.World/OceanBiome.h index b4a13c59..2f27b6f9 100644 --- a/Minecraft.World/OceanBiome.h +++ b/Minecraft.World/OceanBiome.h @@ -10,7 +10,7 @@ public: friendlies.clear(); friendlies_chicken.clear(); // 4J added since chicken now separated from main friendlies friendlies_wolf.clear(); // 4J added since wolf now separated from main friendlies - topMaterial = Tile::gravel_Id; // blocco superficiale + topMaterial = Tile::gravel_Id; // surfaceblock material = Tile::gravel_Id; } }; diff --git a/Minecraft.World/OceanMonumentFeature.cpp b/Minecraft.World/OceanMonumentFeature.cpp new file mode 100644 index 00000000..dd8d78d4 --- /dev/null +++ b/Minecraft.World/OceanMonumentFeature.cpp @@ -0,0 +1,142 @@ +#include "stdafx.h" +#include "OceanMonumentFeature.h" +#include "OceanMonumentPieces.h" +#include "net.minecraft.world.level.h" +#include "net.minecraft.world.level.biome.h" +#include "Mth.h" +#include "LevelData.h" + +void OceanMonumentFeature::_init() +{ + spacing = 32; + separation = 5; +} + +OceanMonumentFeature::OceanMonumentFeature() : StructureFeature() { _init(); } +OceanMonumentFeature::OceanMonumentFeature(std::unordered_map options) : StructureFeature() { _init(); } +OceanMonumentFeature::~OceanMonumentFeature() {} + +std::wstring OceanMonumentFeature::getFeatureName() { return L"Monument"; } + +void OceanMonumentFeature::prescanNearby(int scanRadiusInGridCells) +{ + if (this->level == nullptr || this->level->getLevelData() == nullptr) return; + + int candidates = 0; + int validated = 0; + int halfSizeChunks = this->level->getLevelData()->getXZSize() / 2; + int halfSizeBlocks = (this->level->getLevelData()->getXZSize() * 16) / 2; + app.DebugPrintf("Ocean Monument pre-scan (HalfSize: %d chunks / %d blocks)\n", halfSizeChunks, halfSizeBlocks); + + for (int gz = -scanRadiusInGridCells; gz <= scanRadiusInGridCells; gz++) + { + for (int gx = -scanRadiusInGridCells; gx <= scanRadiusInGridCells; gx++) + { + candidates++; + int64_t chunkSeed = (int64_t)gx * 341873128712LL + + (int64_t)gz * 132897987541LL + + this->level->getSeed() + + 10387313LL; + Random r(chunkSeed); + + int cx = gx * this->spacing; + int cz = gz * this->spacing; + cx += (r.nextInt(this->spacing - this->separation) + r.nextInt(this->spacing - this->separation)) / 2; + cz += (r.nextInt(this->spacing - this->separation) + r.nextInt(this->spacing - this->separation)) / 2; + + int blockX = cx * 16 + 8; + int blockZ = cz * 16 + 8; + + if (Mth::abs(blockX) > halfSizeBlocks || Mth::abs(blockZ) > halfSizeBlocks) + { + continue; + } + + if (this->isFeatureChunk(cx, cz)) + { + validated++; + } + } + } + + app.DebugPrintf(" Pre-scan done: %d grid slots checked, %d validated monuments found. \n", candidates, validated); +} + +bool OceanMonumentFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) +{ + if (this->level == nullptr || this->level->getBiomeSource() == nullptr) return false; + + int i = x; + int j = z; + + if (x < 0) x -= this->spacing - 1; + if (z < 0) z -= this->spacing - 1; + + int k = x / this->spacing; + int l = z / this->spacing; + + int64_t chunkSeed = (int64_t)k * 341873128712LL + (int64_t)l * 132897987541LL + this->level->getSeed() + 10387313LL; + Random random(chunkSeed); + + k *= this->spacing; + l *= this->spacing; + + k += (random.nextInt(this->spacing - this->separation) + random.nextInt(this->spacing - this->separation)) / 2; + l += (random.nextInt(this->spacing - this->separation) + random.nextInt(this->spacing - this->separation)) / 2; + + if (i == k && j == l) + { + Biome* centerBiome = this->level->getBiomeSource()->getBiome(i * 16 + 8, j * 16 + 8); + + if (centerBiome == Biome::deepOcean) + { + std::vector surrounding; + surrounding.reserve(5); + surrounding.push_back(Biome::ocean); + surrounding.push_back(Biome::deepOcean); + surrounding.push_back(Biome::river); + surrounding.push_back(Biome::frozenOcean); + surrounding.push_back(Biome::frozenRiver); + + if (this->level->getBiomeSource()->containsOnly(i * 16 + 8, j * 16 + 8, 29, surrounding)) + { + app.DebugPrintf("Placed Ocean Monument in valid biome at (%d, %d), (%d, %d)\n", + i, j, i * 16 + 8, j * 16 + 8); + app.AddTerrainFeaturePosition(eTerrainFeature_OceanMonument, i, j); + return true; + } + } + } + + return false; +} + +StructureStart* OceanMonumentFeature::createStructureStart(int x, int z) +{ + if (this->level == nullptr) return nullptr; + return new MonumentStart(level, random, x, z); +} + +OceanMonumentFeature::MonumentStart::MonumentStart() {} + +OceanMonumentFeature::MonumentStart::MonumentStart(Level* level, Random* random, int chunkX, int chunkZ) + : StructureStart(chunkX, chunkZ) +{ + random->setSeed(level->getSeed()); + int64_t i = random->nextLong(); + int64_t j = random->nextLong(); + int64_t k = (int64_t)chunkX * i; + int64_t l = (int64_t)chunkZ * j; + random->setSeed(k ^ l ^ level->getSeed()); + + int startX = chunkX * 16 + 8 - 29; + int startZ = chunkZ * 16 + 8 - 29; + + int facing = random->nextInt(4) + 2; + + OceanMonumentPieces::MonumentBuilding* building = + new OceanMonumentPieces::MonumentBuilding(random, startX, startZ, facing); + pieces.push_back(building); + + calculateBoundingBox(); +} \ No newline at end of file diff --git a/Minecraft.World/OceanMonumentFeature.h b/Minecraft.World/OceanMonumentFeature.h new file mode 100644 index 00000000..8cc965e1 --- /dev/null +++ b/Minecraft.World/OceanMonumentFeature.h @@ -0,0 +1,52 @@ +#pragma once + +#include "StructureFeature.h" +#include "StructureStart.h" +#include +#include +#include + +class Biome; +class Level; +class Random; + +class OceanMonumentFeature : public StructureFeature +{ +public: + // static void staticCtor(); // Removed, merged into _init + +private: + int spacing; + int separation; + + void _init(); + +public: + OceanMonumentFeature(); + OceanMonumentFeature(std::unordered_map options); + ~OceanMonumentFeature(); + + virtual std::wstring getFeatureName() override; + + void setLevel(Level* lvl) { this->level = lvl; } + + void prescanNearby(int scanRadiusInGridCells = 8); + +protected: + virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false) override; + virtual StructureStart* createStructureStart(int x, int z) override; + +public: + class MonumentStart : public StructureStart + { + public: + MonumentStart(); + MonumentStart(Level* level, Random* random, int chunkX, int chunkZ); + + + static StructureStart* Create() { return new MonumentStart(); } + virtual EStructureStart GetType() override { return eStructureStart_Monument; } + + + }; +}; \ No newline at end of file diff --git a/Minecraft.World/OceanMonumentPieces.cpp b/Minecraft.World/OceanMonumentPieces.cpp new file mode 100644 index 00000000..d861b519 --- /dev/null +++ b/Minecraft.World/OceanMonumentPieces.cpp @@ -0,0 +1,1660 @@ +#include "stdafx.h" +#include "OceanMonumentPieces.h" +#include "OceanMonumentFeature.h" +#include "net.minecraft.world.level.h" +#include "net.minecraft.world.level.tile.h" +#include "net.minecraft.world.level.levelgen.structure.h" +#include "Facing.h" +#include +#include +#include +#include "Squid.h" + + + +// DOWN=0, UP=1, NORTH=2, SOUTH=3, WEST=4, EAST=5 + +#define F_DOWN 0 +#define F_UP 1 +#define F_NORTH 2 +#define F_SOUTH 3 +#define F_WEST 4 +#define F_EAST 5 + + +// func_175820_a(x, y, z) = y*25 + z*5 + x + +const int OceanMonumentPieces::Piece::ENTRY_INDEX = 2; // roomIndex(2,0,0) +const int OceanMonumentPieces::Piece::CORE_INDEX = 52; // roomIndex(2,2,0) +const int OceanMonumentPieces::Piece::WING1_INDEX = 25; // roomIndex(0,1,0) +const int OceanMonumentPieces::Piece::WING2_INDEX = 29; // roomIndex(4,1,0) + + +void OceanMonumentPieces::loadStatic() +{ + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentBuilding, MonumentBuilding::Create, L"OMB"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentCore, CoreRoom::Create, L"OMCR"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentSimple, SimpleRoom::Create, L"OMSimple"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentSimpleTop, SimpleTopRoom::Create, L"OMSimpleT"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentDoubleX, DoubleXRoom::Create, L"OMDXR"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentDoubleXY, DoubleXYRoom::Create, L"OMDXYR"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentDoubleY, DoubleYRoom::Create, L"OMDYR"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentDoubleYZ, DoubleYZRoom::Create, L"OMDYZR"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentDoubleZ, DoubleZRoom::Create, L"OMDZR"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentEntry, EntryRoom::Create, L"OMEntry"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentPenthouse, Penthouse::Create, L"OMPenthouse"); + StructureFeatureIO::setPieceId(eStructurePiece_OceanMonumentWing, WingRoom::Create, L"OMWR"); +} + + +int OceanMonumentPieces::blockPrismarine() { return PrismarineTile::TYPE_DEFAULT; } +int OceanMonumentPieces::blockPrismarineBricks() { return PrismarineTile::TYPE_BRICKS; } // meta BRICKS +int OceanMonumentPieces::blockDarkPrismarine() { return PrismarineTile::TYPE_DARK; } // meta DARK +int OceanMonumentPieces::blockWater() { return Tile::water_Id; } +int OceanMonumentPieces::blockSeaLantern() { return Tile::seaLantern_Id; } +int OceanMonumentPieces::blockGoldBlock() { return Tile::goldBlock_Id; } +int OceanMonumentPieces::blockSponge() { return Tile::sponge_Id; } +int OceanMonumentPieces::blockAir() { return 0; } + + +OceanMonumentPieces::Piece::Piece() : StructurePiece(0), roomDef(nullptr) {} + +OceanMonumentPieces::Piece::Piece(int type) : StructurePiece(type), roomDef(nullptr) {} + + +OceanMonumentPieces::Piece::Piece(int facing, BoundingBox* box) + : StructurePiece(1), roomDef(nullptr) +{ + + orientation = Direction::FACING_DIRECTION[facing]; + boundingBox = box; +} + + +OceanMonumentPieces::Piece::Piece(int type, int facing, RoomDefinition* room, int sizeX, int sizeY, int sizeZ) + : StructurePiece(type), roomDef(room) +{ + + orientation = Direction::FACING_DIRECTION[facing]; + + if (room == nullptr) return; + + int i = room->index; + int j = i % 5; + int k = (i / 5) % 5; + int l = i / 25; + + + if (facing != Facing::NORTH && facing != Facing::SOUTH) + boundingBox = new BoundingBox(0, 0, 0, sizeZ * 8 - 1, sizeY * 4 - 1, sizeX * 8 - 1); + else + boundingBox = new BoundingBox(0, 0, 0, sizeX * 8 - 1, sizeY * 4 - 1, sizeZ * 8 - 1); + + switch (facing) + { + case Facing::NORTH: + boundingBox->move(j * 8, l * 4, -(k + sizeZ) * 8 + 1); + break; + case Facing::SOUTH: + boundingBox->move(j * 8, l * 4, k * 8); + break; + case Facing::WEST: + boundingBox->move(-(k + sizeZ) * 8 + 1, l * 4, j * 8); + break; + default: // EAST + boundingBox->move(k * 8, l * 4, j * 8); + break; + } +} + +void OceanMonumentPieces::Piece::addAdditonalSaveData(CompoundTag* tag) {} +void OceanMonumentPieces::Piece::readAdditonalSaveData(CompoundTag* tag) {} + + +void OceanMonumentPieces::Piece::fillWithAirOrWater(Level* level, BoundingBox* bb, + int x0, int y0, int z0, int x1, int y1, int z1, bool onlySolid) +{ + for (int y = y0; y <= y1; ++y) + for (int x = x0; x <= x1; ++x) + for (int z = z0; z <= z1; ++z) + { + if (!onlySolid || level->getTile(getWorldX(x, z), getWorldY(y), getWorldZ(x, z)) != 0) + { + if (getWorldY(y) >= level->getSeaLevel()) + placeBlock(level, blockAir(), 0, x, y, z, bb); + else + placeBlock(level, blockWater(), 0, x, y, z, bb); + } + } +} + + +void OceanMonumentPieces::Piece::generateFloor(Level* level, BoundingBox* bb, int offX, int offZ, bool hasOpening) +{ + if (hasOpening) + { + generateBox(level, bb, offX + 0, 0, offZ + 0, offX + 2, 0, offZ + 7, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, bb, offX + 5, 0, offZ + 0, offX + 7, 0, offZ + 7, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, bb, offX + 3, 0, offZ + 0, offX + 4, 0, offZ + 1, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, bb, offX + 3, 0, offZ + 5, offX + 4, 0, offZ + 7, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, bb, offX + 3, 0, offZ + 2, offX + 4, 0, offZ + 2, Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, bb, offX + 3, 0, offZ + 5, offX + 4, 0, offZ + 5, Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, bb, offX + 2, 0, offZ + 3, offX + 2, 0, offZ + 4, Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, bb, offX + 5, 0, offZ + 3, offX + 5, 0, offZ + 4, Tile::prismarine_Id, blockPrismarineBricks(), false); + } + else + { + generateBox(level, bb, offX + 0, 0, offZ + 0, offX + 7, 0, offZ + 7, Tile::prismarine_Id, blockPrismarine(), false); + } +} + + +void OceanMonumentPieces::Piece::fillWaterWith(Level* level, BoundingBox* bb, + int x0, int y0, int z0, int x1, int y1, int z1, int block) +{ + for (int y = y0; y <= y1; ++y) + for (int x = x0; x <= x1; ++x) + for (int z = z0; z <= z1; ++z) + { + if (level->getTile(getWorldX(x, z), getWorldY(y), getWorldZ(x, z)) == blockWater()) + placeBlock(level, block, 0, x, y, z, bb); + } +} + + +bool OceanMonumentPieces::Piece::intersectsXZ(BoundingBox* chunkBB, int x0, int z0, int x1, int z1) +{ + int wx0 = getWorldX(x0, z0); + int wz0 = getWorldZ(x0, z0); + int wx1 = getWorldX(x1, z1); + int wz1 = getWorldZ(x1, z1); + return chunkBB->intersects( + (std::min)(wx0, wx1), (std::min)(wz0, wz1), + (std::max)(wx0, wx1), (std::max)(wz0, wz1)); +} + + +bool OceanMonumentPieces::Piece::spawnElderGuardian(Level* level, BoundingBox* bb, int x, int y, int z) +{ + + int wx = getWorldX(x, z); + int wy = getWorldY(y); + int wz = getWorldZ(x, z); + if (bb->isInside(wx, wy, wz)) + { + Squid *guardian = new Squid(level); + //guardian->setElder(true); + guardian->heal(guardian->getMaxHealth()); + /*entityguardian.setLocationAndAngles((double)i + 0.5D, (double)j, (double)k + 0.5D, 0.0F, 0.0F); + entityguardian.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entityguardian)), (IEntityLivingData)null); + worldIn.spawnEntityInWorld(entityguardian);*/ + return true; + } + return false; +} + + +OceanMonumentPieces::MonumentBuilding::MonumentBuilding() + : entryRoom(nullptr), coreRoom(nullptr) {} + +OceanMonumentPieces::MonumentBuilding::MonumentBuilding(Random* random, int x, int z, int facing) + : Piece(0), entryRoom(nullptr), coreRoom(nullptr) +{ + + this->orientation = Direction::FACING_DIRECTION[facing]; + this->boundingBox = new BoundingBox(x, 39, z, x + 57, 61, z + 57); + + + std::vector roomList = buildRoomGrid(random); + + + entryRoom->claimed = true; + subPieces.push_back(new EntryRoom(facing, entryRoom)); + subPieces.push_back(new CoreRoom(facing, coreRoom, random)); + + + struct XYFit : RoomFitHelper { + bool canFit(RoomDefinition* r) override { + return r->hasOpening[F_EAST] && !r->neighbors[F_EAST]->claimed && + r->hasOpening[F_UP] && !r->neighbors[F_UP]->claimed && + r->neighbors[F_EAST]->hasOpening[F_UP] && + !r->neighbors[F_EAST]->neighbors[F_UP]->claimed; + } + Piece* createPiece(int facing, RoomDefinition* r, Random* rng) override { + r->claimed = true; + r->neighbors[F_EAST]->claimed = true; + r->neighbors[F_UP]->claimed = true; + r->neighbors[F_EAST]->neighbors[F_UP]->claimed = true; + return new DoubleXYRoom(facing, r, rng); + } + }; + struct YZFit : RoomFitHelper { + bool canFit(RoomDefinition* r) override { + return r->hasOpening[F_NORTH] && !r->neighbors[F_NORTH]->claimed && + r->hasOpening[F_UP] && !r->neighbors[F_UP]->claimed && + r->neighbors[F_NORTH]->hasOpening[F_UP] && + !r->neighbors[F_NORTH]->neighbors[F_UP]->claimed; + } + Piece* createPiece(int facing, RoomDefinition* r, Random* rng) override { + r->claimed = true; + r->neighbors[F_NORTH]->claimed = true; + r->neighbors[F_UP]->claimed = true; + r->neighbors[F_NORTH]->neighbors[F_UP]->claimed = true; + return new DoubleYZRoom(facing, r, rng); + } + }; + struct ZFit : RoomFitHelper { + bool canFit(RoomDefinition* r) override { + return r->hasOpening[F_NORTH] && !r->neighbors[F_NORTH]->claimed; + } + Piece* createPiece(int facing, RoomDefinition* r, Random* rng) override { + RoomDefinition* base = r; + if (!r->hasOpening[F_NORTH] || r->neighbors[F_NORTH]->claimed) + base = r->neighbors[F_SOUTH]; + base->claimed = true; + base->neighbors[F_NORTH]->claimed = true; + return new DoubleZRoom(facing, base, rng); + } + }; + struct XFit : RoomFitHelper { + bool canFit(RoomDefinition* r) override { + return r->hasOpening[F_EAST] && !r->neighbors[F_EAST]->claimed; + } + Piece* createPiece(int facing, RoomDefinition* r, Random* rng) override { + r->claimed = true; + r->neighbors[F_EAST]->claimed = true; + return new DoubleXRoom(facing, r, rng); + } + }; + struct YFit : RoomFitHelper { + bool canFit(RoomDefinition* r) override { + return r->hasOpening[F_UP] && !r->neighbors[F_UP]->claimed; + } + Piece* createPiece(int facing, RoomDefinition* r, Random* rng) override { + r->claimed = true; + r->neighbors[F_UP]->claimed = true; + return new DoubleYRoom(facing, r, rng); + } + }; + struct SimpleTopFit : RoomFitHelper { + bool canFit(RoomDefinition* r) override { + return !r->hasOpening[F_WEST] && !r->hasOpening[F_EAST] && + !r->hasOpening[F_NORTH] && !r->hasOpening[F_SOUTH] && + !r->hasOpening[F_UP]; + } + Piece* createPiece(int facing, RoomDefinition* r, Random* rng) override { + r->claimed = true; + return new SimpleTopRoom(facing, r, rng); + } + }; + struct SimpleFit : RoomFitHelper { + bool canFit(RoomDefinition*) override { return true; } + Piece* createPiece(int facing, RoomDefinition* r, Random* rng) override { + r->claimed = true; + return new SimpleRoom(facing, r, rng); + } + }; + + std::vector helpers = { + new XYFit(), new YZFit(), new ZFit(), new XFit(), new YFit(), + new SimpleTopFit(), new SimpleFit() + }; + + + for (RoomDefinition* room : roomList) + { + if (!room->claimed && !room->isSpecial()) + { + for (RoomFitHelper* h : helpers) + { + if (h->canFit(room)) + { + subPieces.push_back(h->createPiece(facing, room, random)); + break; + } + } + } + } + + for (RoomFitHelper* h : helpers) delete h; + + + int minY = boundingBox->y0; + int baseX = getWorldX(9, 22); + int baseZ = getWorldZ(9, 22); + + for (Piece* p : subPieces) + p->getBoundingBox()->move(baseX, minY, baseZ); + + + BoundingBox* wing1BB = new BoundingBox( + getWorldX(1, 1), getWorldY(1), getWorldZ(1, 1), + getWorldX(23, 21), getWorldY(8), getWorldZ(23, 21)); + BoundingBox* wing2BB = new BoundingBox( + getWorldX(34, 1), getWorldY(1), getWorldZ(34, 1), + getWorldX(56, 21), getWorldY(8), getWorldZ(56, 21)); + BoundingBox* penthouseBB = new BoundingBox( + getWorldX(22, 22), getWorldY(13), getWorldZ(22, 22), + getWorldX(35, 35), getWorldY(17), getWorldZ(35, 35)); + + int seed = random->nextInt(); + subPieces.push_back(new WingRoom(facing, wing1BB, seed++)); + subPieces.push_back(new WingRoom(facing, wing2BB, seed++)); + subPieces.push_back(new Penthouse(facing, penthouseBB)); +} + +OceanMonumentPieces::MonumentBuilding::~MonumentBuilding() +{ + for (Piece* p : subPieces) delete p; + +} + + +std::vector OceanMonumentPieces::MonumentBuilding::buildRoomGrid(Random* random) +{ + RoomDefinition* grid[75] = {}; + + + for (int x = 0; x < 5; ++x) + for (int z = 0; z < 4; ++z) + { + int idx = Piece::roomIndex(x, 0, z); + grid[idx] = new RoomDefinition(idx); + } + + + for (int x = 0; x < 5; ++x) + for (int z = 0; z < 4; ++z) + { + int idx = Piece::roomIndex(x, 1, z); + grid[idx] = new RoomDefinition(idx); + } + + + for (int x = 1; x < 4; ++x) + for (int z = 0; z < 2; ++z) + { + int idx = Piece::roomIndex(x, 2, z); + grid[idx] = new RoomDefinition(idx); + } + + + entryRoom = grid[ENTRY_INDEX]; + + + for (int x = 0; x < 5; ++x) + for (int y = 0; y < 3; ++y) + for (int z = 0; z < 5; ++z) + { + int idx = Piece::roomIndex(x, y, z); + if (grid[idx] == nullptr) continue; + + + static const int dx[6] = { 0, 0, 0, 0,-1, 1 }; + static const int dy[6] = {-1, 1, 0, 0, 0, 0 }; + static const int dz[6] = { 0, 0,-1, 1, 0, 0 }; + static const int oppFacing[6] = { 1, 0, 3, 2, 5, 4 }; + + for (int f = 0; f < 6; ++f) + { + int nx = x + dx[f]; + int ny = y + dy[f]; + int nz = z + dz[f]; + if (nx < 0 || nx >= 5 || ny < 0 || ny >= 3 || nz < 0 || nz >= 5) continue; + int nidx = Piece::roomIndex(nx, ny, nz); + if (grid[nidx] == nullptr) continue; + + + if (nidx <= idx) continue; + + if (nz != z) + { + + int opp = (f % 2 == 0) ? f + 1 : f - 1; + grid[idx]->connectTo(opp, grid[nidx]); + } + else + { + grid[idx]->connectTo(f, grid[nidx]); + } + } + } + + + RoomDefinition* specialUp = new RoomDefinition(1003); + RoomDefinition* specialWing1 = new RoomDefinition(1001); + RoomDefinition* specialWing2 = new RoomDefinition(1002); + grid[CORE_INDEX ]->connectTo(F_UP, specialUp); + grid[WING1_INDEX]->connectTo(F_SOUTH, specialWing1); + grid[WING2_INDEX]->connectTo(F_SOUTH, specialWing2); + specialUp->claimed = true; + specialWing1->claimed = true; + specialWing2->claimed = true; + + entryRoom->isEntrance = true; + + + coreRoom = grid[Piece::roomIndex(random->nextInt(4), 0, 2)]; + coreRoom->claimed = true; + coreRoom->neighbors[F_EAST]->claimed = true; + coreRoom->neighbors[F_NORTH]->claimed = true; + coreRoom->neighbors[F_EAST]->neighbors[F_NORTH]->claimed = true; + coreRoom->neighbors[F_UP]->claimed = true; + coreRoom->neighbors[F_EAST]->neighbors[F_UP]->claimed = true; + coreRoom->neighbors[F_NORTH]->neighbors[F_UP]->claimed = true; + coreRoom->neighbors[F_EAST]->neighbors[F_NORTH]->neighbors[F_UP]->claimed = true; + + + std::vector list; + for (int i = 0; i < 75; ++i) + { + if (grid[i] != nullptr) + { + grid[i]->initOpenings(); + list.push_back(grid[i]); + } + } + specialUp->initOpenings(); + + + std::shuffle(list.begin(), list.end(), std::default_random_engine(random->nextLong())); + + + int tagCounter = 1; + for (RoomDefinition* room : list) + { + int removedCount = 0; + int attempts = 0; + while (removedCount < 2 && attempts < 5) + { + ++attempts; + int f = random->nextInt(6); + if (!room->hasOpening[f]) continue; + + int opp = (f % 2 == 0) ? f + 1 : f - 1; + room->hasOpening[f] = false; + room->neighbors[f]->hasOpening[opp] = false; + + if (room->isReachable(tagCounter++) && room->neighbors[f]->isReachable(tagCounter++)) + ++removedCount; + else + { + + room->hasOpening[f] = true; + room->neighbors[f]->hasOpening[opp] = true; + } + } + } + + list.push_back(specialUp); + list.push_back(specialWing1); + list.push_back(specialWing2); + return list; +} + +bool OceanMonumentPieces::MonumentBuilding::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + int seaLevel = (std::max)(level->getSeaLevel(), 64); + int fillHeight = seaLevel - boundingBox->y0; + + + fillWithAirOrWater(level, chunkBB, 0, 0, 0, 58, fillHeight, 58, false); + + + buildWing(false, 0, level, random, chunkBB); + buildWing(true, 33, level, random, chunkBB); + + buildEntrance(level, random, chunkBB); + buildTopSection(level, random, chunkBB); + buildCorridorCenter(level, random, chunkBB); + buildSideCorridor(level, random, chunkBB); + buildInnerCorridor(level, random, chunkBB); + buildUpperSection(level, random, chunkBB); + + + for (int j = 0; j < 7; ++j) + { + int k = 0; + while (k < 7) + { + if (k == 0 && j == 3) k = 6; + + int lx = j * 9; + int lz = k * 9; + for (int jj = 0; jj < 4; ++jj) + for (int kk = 0; kk < 4; ++kk) + { + placeBlock(level, Tile::prismarine_Id,blockPrismarineBricks(), lx+jj, 0, lz+kk, chunkBB); + fillColumnDown(level,Tile::prismarine_Id, blockPrismarineBricks(), lx+jj, -1, lz+kk, chunkBB); + } + + if (j != 0 && j != 6) k += 6; + else ++k; + } + } + + + for (int s = 0; s < 5; ++s) + { + fillWithAirOrWater(level, chunkBB, -1-s, 0+s*2, -1-s, -1-s, 23, 58+s, false); + fillWithAirOrWater(level, chunkBB, 58+s, 0+s*2, -1-s, 58+s, 23, 58+s, false); + fillWithAirOrWater(level, chunkBB, 0-s, 0+s*2, -1-s, 57+s, 23, -1-s, false); + fillWithAirOrWater(level, chunkBB, 0-s, 0+s*2, 58+s, 57+s, 23, 58+s, false); + } + + + for (Piece* p : subPieces) + { + if (p->getBoundingBox()->intersects(chunkBB)) + p->postProcess(level, random, chunkBB); + } + + return true; +} + +// func_175840_a +void OceanMonumentPieces::MonumentBuilding::buildWing(bool isRight, int offX, Level* level, Random* random, BoundingBox* chunkBB) +{ + if (!intersectsXZ(chunkBB, offX, 0, offX + 23, 20)) return; + + generateBox(level, chunkBB, offX+0, 0, 0, offX+24, 0, 20, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, offX+0, 1, 0, offX+24, 10, 20, false); + + for (int j = 0; j < 4; ++j) + { + generateBox(level, chunkBB, offX+j, j+1, j, offX+j, j+1, 20, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, offX+j+7, j+5, j+7, offX+j+7, j+5, 20, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, offX+17-j, j+5, j+7, offX+17-j, j+5, 20, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, offX+24-j, j+1, j, offX+24-j, j+1, 20, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, offX+j+1, j+1, j, offX+23-j, j+1, j, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, offX+j+8, j+5, j+7, offX+16-j, j+5, j+7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } + + generateBox(level, chunkBB, offX+4, 4, 4, offX+6, 4, 20, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, offX+7, 4, 4, offX+17, 4, 6, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, offX+18, 4, 4, offX+20, 4, 20, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, offX+11, 8, 11, offX+13, 8, 20, Tile::prismarine_Id, blockPrismarine(), false); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), offX + 12, 9, 12, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), offX + 12, 9, 15, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), offX + 12, 9, 18, chunkBB); + + int j1 = isRight ? offX+19 : offX+5; + int k = isRight ? offX+5 : offX+19; + + for (int l = 20; l >= 5; l -= 3) + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), j1, 5, l, chunkBB); + for (int k1 = 19; k1 >= 7; k1 -= 3) + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), k, 5, k1, chunkBB); + for (int l1 = 0; l1 < 4; ++l1) + { + int i1 = isRight ? offX + (24 - (17 - l1*3)) : offX + 17 - l1*3; + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 5, 5, chunkBB); + } + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), k, 5, 5, chunkBB); + + generateBox(level, chunkBB, offX+11, 1, 12, offX+13, 7, 12, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, offX+12, 1, 11, offX+12, 7, 13, Tile::prismarine_Id, blockPrismarine(), false); +} + +// func_175839_b +void OceanMonumentPieces::MonumentBuilding::buildEntrance(Level* level, Random* random, BoundingBox* chunkBB) +{ + if (!intersectsXZ(chunkBB, 22, 5, 35, 17)) return; + + fillWithAirOrWater(level, chunkBB, 25, 0, 0, 32, 8, 20, false); + for (int i = 0; i < 4; ++i) + { + generateBox(level, chunkBB, 24, 2, 5+i*4, 24, 4, 5+i*4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 22, 4, 5+i*4, 23, 4, 5+i*4, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 25, 5, 5 + i * 4, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 26, 6, 5 + i * 4, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 26, 5, 5+i*4, chunkBB); + generateBox(level, chunkBB, 33, 2, 5+i*4, 33, 4, 5+i*4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 34, 4, 5+i*4, 35, 4, 5+i*4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 32, 5, 5 + i * 4, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 31, 6, 5 + i * 4, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 31, 5, 5+i*4, chunkBB); + generateBox(level, chunkBB, 27, 6, 5+i*4, 30, 6, 5+i*4, Tile::prismarine_Id, blockPrismarine(), false); + } +} + +// func_175837_c +void OceanMonumentPieces::MonumentBuilding::buildTopSection(Level* level, Random* random, BoundingBox* chunkBB) +{ + if (!intersectsXZ(chunkBB, 15, 20, 42, 21)) return; + + generateBox(level, chunkBB, 15, 0, 21, 42, 0, 21, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 26, 1, 21, 31, 3, 21, false); + generateBox(level, chunkBB, 21, 12, 21, 36, 12, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 17, 11, 21, 40, 11, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 16, 10, 21, 41, 10, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 15, 7, 21, 42, 9, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 16, 6, 21, 41, 6, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 17, 5, 21, 40, 5, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 21, 4, 21, 36, 4, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 22, 3, 21, 26, 3, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 31, 3, 21, 35, 3, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 23, 2, 21, 25, 2, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 32, 2, 21, 34, 2, 21, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 28, 4, 20, 29, 4, 21, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 27, 3, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 26, 2, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 31, 2, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 25, 1, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 32, 1, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 30, 3, 21, chunkBB); + + for (int i = 0; i < 7; ++i) { + placeBlock(level, Tile::prismarine_Id,blockDarkPrismarine(), 28-i, 6+i, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id,blockDarkPrismarine(), 29+i, 6+i, 21, chunkBB); + } + for (int j = 0; j < 4; ++j) { + placeBlock(level, Tile::prismarine_Id, blockDarkPrismarine(), 28-j, 9+j, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockDarkPrismarine(), 29+j, 9+j, 21, chunkBB); + } + placeBlock(level, Tile::prismarine_Id, blockDarkPrismarine(), 28, 12, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockDarkPrismarine(), 29, 12, 21, chunkBB); + + for (int k = 0; k < 3; ++k) { + placeBlock(level, Tile::prismarine_Id, blockDarkPrismarine(), 22-k*2, 8, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockDarkPrismarine(), 22-k*2, 9, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockDarkPrismarine(), 35+k*2, 8, 21, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockDarkPrismarine(), 35+k*2, 9, 21, chunkBB); + } + + fillWithAirOrWater(level, chunkBB, 15, 13, 21, 42, 15, 21, false); + fillWithAirOrWater(level, chunkBB, 15, 1, 21, 15, 6, 21, false); + fillWithAirOrWater(level, chunkBB, 16, 1, 21, 16, 5, 21, false); + fillWithAirOrWater(level, chunkBB, 17, 1, 21, 20, 4, 21, false); + fillWithAirOrWater(level, chunkBB, 21, 1, 21, 21, 3, 21, false); + fillWithAirOrWater(level, chunkBB, 22, 1, 21, 22, 2, 21, false); + fillWithAirOrWater(level, chunkBB, 23, 1, 21, 24, 1, 21, false); + fillWithAirOrWater(level, chunkBB, 42, 1, 21, 42, 6, 21, false); + fillWithAirOrWater(level, chunkBB, 41, 1, 21, 41, 5, 21, false); + fillWithAirOrWater(level, chunkBB, 37, 1, 21, 40, 4, 21, false); + fillWithAirOrWater(level, chunkBB, 36, 1, 21, 36, 3, 21, false); + fillWithAirOrWater(level, chunkBB, 33, 1, 21, 34, 1, 21, false); + fillWithAirOrWater(level, chunkBB, 35, 1, 21, 35, 2, 21, false); +} + +// func_175841_d +void OceanMonumentPieces::MonumentBuilding::buildCorridorCenter(Level* level, Random* random, BoundingBox* chunkBB) +{ + if (!intersectsXZ(chunkBB, 21, 21, 36, 36)) return; + + generateBox(level, chunkBB, 21, 0, 22, 36, 0, 36, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 21, 1, 22, 36, 23, 36, false); + + for (int i = 0; i < 4; ++i) { + generateBox(level, chunkBB, 21+i, 13+i, 21+i, 36-i, 13+i, 21+i, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 21+i, 13+i, 36-i, 36-i, 13+i, 36-i, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 21+i, 13+i, 22+i, 21+i, 13+i, 35-i, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 36-i, 13+i, 22+i, 36-i, 13+i, 35-i, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } + + generateBox(level, chunkBB, 25, 16, 25, 32, 16, 32, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 25, 17, 25, 25, 19, 25, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 32, 17, 25, 32, 19, 25, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 25, 17, 32, 25, 19, 32, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 32, 17, 32, 32, 19, 32, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 26, 20, 26, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 27, 21, 27, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 27, 20, 27, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 26, 20, 31, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 27, 21, 30, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 27, 20, 30, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 31, 20, 31, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 30, 21, 30, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 30, 20, 30, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 31, 20, 26, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 30, 21, 27, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 30, 20, 27, chunkBB); + generateBox(level, chunkBB, 28, 21, 27, 29, 21, 27, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 27, 21, 28, 27, 21, 29, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 28, 21, 30, 29, 21, 30, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 30, 21, 28, 30, 21, 29, Tile::prismarine_Id, blockPrismarine(), false); +} + +// func_175835_e +void OceanMonumentPieces::MonumentBuilding::buildSideCorridor(Level* level, Random* random, BoundingBox* chunkBB) +{ + if (intersectsXZ(chunkBB, 0, 21, 6, 58)) + { + generateBox(level, chunkBB, 0, 0, 21, 6, 0, 57, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 0, 1, 21, 6, 7, 57, false); + generateBox(level, chunkBB, 4, 4, 21, 6, 4, 53, Tile::prismarine_Id, blockPrismarine(), false); + for (int i = 0; i < 4; ++i) + generateBox(level, chunkBB, i, i+1, 21, i, i+1, 57-i, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false); + for (int j = 23; j < 53; j += 3) + placeBlock(level,Tile::prismarine_Id, blockPrismarineBricks(), 5, 5, j, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 5, 5, 52, chunkBB); + generateBox(level, chunkBB, 4, 1, 52, 6, 3, 52, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 5, 1, 51, 5, 3, 53, Tile::prismarine_Id, blockPrismarine(), false); + } + if (intersectsXZ(chunkBB, 51, 21, 58, 58)) + { + generateBox(level, chunkBB, 51, 0, 21, 57, 0, 57, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 51, 1, 21, 57, 7, 57, false); + generateBox(level, chunkBB, 51, 4, 21, 53, 4, 53, Tile::prismarine_Id, blockPrismarine(), false); + for (int l = 0; l < 4; ++l) + generateBox(level, chunkBB, 57-l, l+1, 21, 57-l, l+1, 57-l, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false); + for (int i1 = 23; i1 < 53; i1 += 3) + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 52, 5, i1, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 52, 5, 52, chunkBB); + generateBox(level, chunkBB, 51, 1, 52, 53, 3, 52, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 52, 1, 51, 52, 3, 53, Tile::prismarine_Id, blockPrismarine(), false); + } + if (intersectsXZ(chunkBB, 0, 51, 57, 57)) + { + generateBox(level, chunkBB, 7, 0, 51, 50, 0, 57, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 7, 1, 51, 50, 10, 57, false); + for (int j1 = 0; j1 < 4; ++j1) + generateBox(level, chunkBB, j1+1, j1+1, 57-j1, 56-j1, j1+1, 57-j1, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } +} + +// func_175842_f +void OceanMonumentPieces::MonumentBuilding::buildInnerCorridor(Level* level, Random* random, BoundingBox* chunkBB) +{ + if (intersectsXZ(chunkBB, 7, 21, 13, 54)) + { + generateBox(level, chunkBB, 7, 0, 21, 13, 0, 50, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 7, 1, 21, 13, 10, 50, false); + generateBox(level, chunkBB, 11, 8, 21, 13, 8, 53, Tile::prismarine_Id, blockPrismarine(), false); + for (int i = 0; i < 4; ++i) + generateBox(level, chunkBB, i+7, i+5, 21, i+7, i+5, 54, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + for (int j = 21; j <= 45; j += 3) + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 12, 9, j, chunkBB); + } + if (intersectsXZ(chunkBB, 44, 21, 50, 54)) + { + generateBox(level, chunkBB, 44, 0, 21, 50, 0, 50, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 44, 1, 21, 50, 10, 50, false); + generateBox(level, chunkBB, 44, 8, 21, 46, 8, 53, Tile::prismarine_Id, blockPrismarine(), false); + for (int k = 0; k < 4; ++k) + generateBox(level, chunkBB, 50-k, k+5, 21, 50-k, k+5, 54, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + for (int l = 21; l <= 45; l += 3) + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 45, 9, l, chunkBB); + } + if (intersectsXZ(chunkBB, 8, 44, 49, 54)) + { + generateBox(level, chunkBB, 14, 0, 44, 43, 0, 50, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 14, 1, 44, 43, 10, 50, false); + for (int i1 = 12; i1 <= 45; i1 += 3) + { + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 9, 45, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 9, 52, chunkBB); + if (i1==12||i1==18||i1==24||i1==33||i1==39||i1==45) + { + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 9, 47, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 9, 50, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 10, 45, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 10, 46, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 10, 51, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 10, 52, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 11, 47, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 11, 50, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 12, 48, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), i1, 12, 49, chunkBB); + + } + } + for (int j1 = 0; j1 < 3; ++j1) + generateBox(level, chunkBB, 7+j1, 5+j1, 54, 50-j1, 5+j1, 54, Tile::prismarine_Id, blockPrismarine(), false);//fixed + generateBox(level, chunkBB, 10, 8, 54, 47, 8, 54, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false);//fixed + generateBox(level, chunkBB, 14, 8, 44, 43, 8, 53, Tile::prismarine_Id, blockPrismarine(), false); + } +} + +// func_175838_g +void OceanMonumentPieces::MonumentBuilding::buildUpperSection(Level* level, Random* random, BoundingBox* chunkBB) +{ + if (intersectsXZ(chunkBB, 14, 21, 20, 43)) + { + generateBox(level, chunkBB, 14, 0, 21, 20, 0, 43, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 14, 1, 22, 20, 14, 43, false); + generateBox(level, chunkBB, 18, 12, 22, 20, 12, 39, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 18, 12, 21, 20, 12, 21, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + for (int i = 0; i < 4; ++i) + generateBox(level, chunkBB, i+14, i+9, 21, i+14, i+9, 43-i, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + for (int j = 23; j <= 39; j += 3) + placeBlock(level,Tile::prismarine_Id, blockPrismarineBricks(), 19, 13, j, chunkBB); + } + if (intersectsXZ(chunkBB, 37, 21, 43, 43)) + { + generateBox(level, chunkBB, 37, 0, 21, 43, 0, 43, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 37, 1, 22, 43, 14, 43, false); + generateBox(level, chunkBB, 37, 12, 22, 39, 12, 39, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 37, 12, 21, 39, 12, 21, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + for (int k = 0; k < 4; ++k) + generateBox(level, chunkBB, 43-k, k+9, 21, 43-k, k+9, 43-k, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(), false); + for (int l = 23; l <= 39; l += 3) + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 38, 13, l, chunkBB); + } + if (intersectsXZ(chunkBB, 15, 37, 42, 43)) + { + generateBox(level, chunkBB, 21, 0, 37, 36, 0, 43, Tile::prismarine_Id, blockPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 21, 1, 37, 36, 14, 43, false); + generateBox(level, chunkBB, 21, 12, 37, 36, 12, 39, Tile::prismarine_Id, blockPrismarine(), false); + for (int i1 = 0; i1 < 4; ++i1) + generateBox(level, chunkBB, 15+i1, i1+9, 43-i1, 42-i1, i1+9, 43-i1, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + for (int j1 = 21; j1 <= 36; j1 += 3) + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), j1, 13, 38, chunkBB); + } +} + + +OceanMonumentPieces::CoreRoom::CoreRoom() {} +OceanMonumentPieces::CoreRoom::CoreRoom(int facing, RoomDefinition* room, Random* random) + : Piece(1, facing, room, 2, 2, 2) {} + +bool OceanMonumentPieces::CoreRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + + generateBox(level, chunkBB, 1, 8, 0, 14, 8, 14, Tile::prismarine_Id, blockPrismarine(), false); + + // Pareti y=7 + int i = 7; + generateBox(level, chunkBB, 0, i, 0, 0, i, 15, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 15, i, 0, 15, i, 15, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, i, 0, 15, i, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, i, 15, 14, i, 15, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + + for (i = 1; i <= 6; ++i) + { + + int meta = (i == 2 || i == 6) ? blockPrismarine() : blockPrismarineBricks(); + + for (int j = 0; j <= 15; j += 15) + { + + generateBox(level, chunkBB, j, i, 0, j, i, 1, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta, false); + generateBox(level, chunkBB, j, i, 6, j, i, 9, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta,false); + generateBox(level, chunkBB, j, i,14, j, i,15, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta,false); + } + generateBox(level, chunkBB, 1, i, 0, 1, i, 0, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta,false); + generateBox(level, chunkBB, 6, i, 0, 9, i, 0, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta,false); + generateBox(level, chunkBB, 14, i, 0, 14, i, 0, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta,false); + generateBox(level, chunkBB, 1, i, 15, 14, i, 15, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta,false); + } + + + generateBox(level, chunkBB, 6, 3, 6, 9, 6, 9, Tile::prismarine_Id, blockDarkPrismarine(), Tile::prismarine_Id, blockDarkPrismarine(), false); + + generateBox(level, chunkBB, 7, 4, 7, 8, 5, 8, blockGoldBlock(), 0, false); + + for (i = 3; i <= 6; i += 3) + { + for (int k = 6; k <= 9; k += 3) + { + placeBlock(level, blockSeaLantern(), 0, k, i, 6, chunkBB); + placeBlock(level, blockSeaLantern(), 0, k, i, 9, chunkBB); + } + } + + + generateBox(level, chunkBB, 5, 1, 6, 5, 2, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 1, 9, 5, 2, 9, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 10, 1, 6, 10, 2, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 10, 1, 9, 10, 2, 9, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 6, 1, 5, 6, 2, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 9, 1, 5, 9, 2, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 6, 1, 10, 6, 2, 10, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 9, 1, 10, 9, 2, 10, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 2, 5, 5, 6, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 2, 10, 5, 6, 10, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 10, 2, 5, 10, 6, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 10, 2, 10, 10, 6, 10, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 7, 1, 5, 7, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 10, 7, 1, 10, 7, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 7, 9, 5, 7, 14, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 10, 7, 9, 10, 7, 14, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 7, 5, 6, 7, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 7, 10, 6, 7, 10, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 9, 7, 5, 14, 7, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 9, 7, 10, 14, 7, 10, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 2, 1, 2, 2, 1, 3, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 3, 1, 2, 3, 1, 2, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 13, 1, 2, 13, 1, 3, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 12, 1, 2, 12, 1, 2, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 2, 1, 12, 2, 1, 13, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 3, 1, 13, 3, 1, 13, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 13, 1, 12, 13, 1, 13, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 12, 1, 13, 12, 1, 13, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + + return true; +} + + +OceanMonumentPieces::SimpleRoom::SimpleRoom() : variant(0) {} +OceanMonumentPieces::SimpleRoom::SimpleRoom(int facing, RoomDefinition* room, Random* random) + : Piece(1, facing, room, 1, 1, 1) +{ + variant = random->nextInt(3); +} + +bool OceanMonumentPieces::SimpleRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + if (roomDef->index / 25 > 0) + generateFloor(level, chunkBB, 0, 0, roomDef->hasOpening[F_DOWN]); + + if (roomDef->neighbors[F_UP] == nullptr) + fillWaterWith(level, chunkBB, 1, 4, 1, 6, 4, 6, Tile::prismarine_Id); + + bool placeChest = variant != 0 && random->nextBoolean() && + !roomDef->hasOpening[F_DOWN] && !roomDef->hasOpening[F_UP] && + roomDef->countOpenings() > 1; + + if (variant == 0) + { + + generateBox(level, chunkBB, 0, 1, 0, 2, 1, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 3, 0, 2, 3, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 2, 0, 0, 2, 2, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 1, 2, 0, 2, 2, 0, Tile::prismarine_Id, blockPrismarine(), false); + placeBlock(level, blockSeaLantern(), 0, 1, 2, 1, chunkBB); + generateBox(level, chunkBB, 5, 1, 0, 7, 1, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 5, 3, 0, 7, 3, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 7, 2, 0, 7, 2, 2, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 5, 2, 0, 6, 2, 0, Tile::prismarine_Id, blockPrismarine(), false); + placeBlock(level, blockSeaLantern(), 0, 6, 2, 1, chunkBB); + generateBox(level, chunkBB, 0, 1, 5, 2, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 3, 5, 2, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 2, 5, 0, 2, 7, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 1, 2, 7, 2, 2, 7, Tile::prismarine_Id, blockPrismarine(), false); + placeBlock(level, blockSeaLantern(), 0, 1, 2, 6, chunkBB); + generateBox(level, chunkBB, 5, 1, 5, 7, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 5, 3, 5, 7, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 7, 2, 5, 7, 2, 7, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 5, 2, 7, 6, 2, 7, Tile::prismarine_Id, blockPrismarine(), false); + placeBlock(level, blockSeaLantern(), 0, 6, 2, 6, chunkBB); + + if (roomDef->hasOpening[F_SOUTH]) { generateBox(level, chunkBB, 3, 3, 0, 4, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); } + else { + generateBox(level, chunkBB, 3, 3, 0, 4, 3, 1, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 3, 2, 0, 4, 2, 0, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 3, 1, 0, 4, 1, 1, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } + if (roomDef->hasOpening[F_NORTH]) { generateBox(level, chunkBB, 3, 3, 7, 4, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); } + else { + generateBox(level, chunkBB, 3, 3, 6, 4, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 3, 2, 7, 4, 2, 7, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 3, 1, 6, 4, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } + if (roomDef->hasOpening[F_WEST]) { generateBox(level, chunkBB, 0, 3, 3, 0, 3, 4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); } + else { + generateBox(level, chunkBB, 0, 3, 3, 1, 3, 4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 2, 3, 0, 2, 4, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 0, 1, 3, 1, 1, 4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } + if (roomDef->hasOpening[F_EAST]) { generateBox(level, chunkBB, 7, 3, 3, 7, 3, 4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); } + else { + generateBox(level, chunkBB, 6, 3, 3, 7, 3, 4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 7, 2, 3, 7, 2, 4, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 6, 1, 3, 7, 1, 4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } + } + else if (variant == 1) + { + generateBox(level, chunkBB, 2, 1, 2, 2, 3, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 2, 1, 5, 2, 3, 5, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 5, 1, 5, 5, 3, 5, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 5, 1, 2, 5, 3, 2, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + placeBlock(level, blockSeaLantern(), 0, 2, 2, 2, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 2, 2, 5, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 5, 2, 5, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 5, 2, 2, chunkBB); + generateBox(level, chunkBB, 0, 1, 0, 1, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 1, 1, 0, 3, 1, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 0, 1, 7, 1, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 1, 6, 0, 3, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 6, 1, 7, 7, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 7, 1, 6, 7, 3, 6, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 6, 1, 0, 7, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 7, 1, 1, 7, 3, 1, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + + placeBlock(level, Tile::prismarine_Id, blockPrismarine(), 1, 2, 0, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarine(), 0, 2, 1, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarine(), 1, 2, 7, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarine(), 0, 2, 6, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarine(), 6, 2, 7, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarine(), 7, 2, 6, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarine(), 6, 2, 0, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarine(), 7, 2, 1, chunkBB); + + if (!roomDef->hasOpening[F_SOUTH]) { generateBox(level, chunkBB, 1, 3, 0, 6, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); generateBox(level, chunkBB, 1, 2, 0, 6, 2, 0, Tile::prismarine_Id, blockPrismarine(), false); generateBox(level, chunkBB, 1, 1, 0, 6, 1, 0, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); } + if (!roomDef->hasOpening[F_NORTH]) { generateBox(level, chunkBB, 1, 3, 7, 6, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 1, 2, 7, 6, 2, 7, Tile::prismarine_Id, blockPrismarine(), false); generateBox(level, chunkBB, 1, 1, 7, 6, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); } + if (!roomDef->hasOpening[F_WEST]) { generateBox(level, chunkBB, 0, 3, 1, 0, 3, 6, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 0, 2, 1, 0, 2, 6, Tile::prismarine_Id, blockPrismarine(), false); generateBox(level, chunkBB, 0, 1, 1, 0, 1, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); } + if (!roomDef->hasOpening[F_EAST]) { generateBox(level, chunkBB, 7, 3, 1, 7, 3, 6, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); generateBox(level, chunkBB, 7, 2, 1, 7, 2, 6, Tile::prismarine_Id, blockPrismarine(), false); generateBox(level, chunkBB, 7, 1, 1, 7, 1, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); } + } + else // variant == 2 + { + generateBox(level, chunkBB, 0, 1, 0, 0, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 7, 1, 0, 7, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 0, 6, 1, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 7, 6, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 2, 0, 0, 2, 7, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 7, 2, 0, 7, 2, 7, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 1, 2, 0, 6, 2, 0, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 1, 2, 7, 6, 2, 7, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 0, 3, 0, 0, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 7, 3, 0, 7, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 3, 0, 6, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 3, 7, 6, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 0, 1, 3, 0, 2, 4, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 7, 1, 3, 7, 2, 4, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 3, 1, 0, 4, 2, 0, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 3, 1, 7, 4, 2, 7, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + if (roomDef->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 0, 4, 2, 0, false); + if (roomDef->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 7, 4, 2, 7, false); + if (roomDef->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 1, 3, 0, 2, 4, false); + if (roomDef->hasOpening[F_EAST]) fillWithAirOrWater(level, chunkBB, 7, 1, 3, 7, 2, 4, false); + } + + if (placeChest) + { + generateBox(level, chunkBB, 3, 1, 3, 4, 1, 4, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 3, 2, 3, 4, 2, 4, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 3, 3, 3, 4, 3, 4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } + return true; +} + + +OceanMonumentPieces::SimpleTopRoom::SimpleTopRoom() {} +OceanMonumentPieces::SimpleTopRoom::SimpleTopRoom(int facing, RoomDefinition* room, Random* random) + : Piece(1, facing, room, 1, 1, 1) {} + +bool OceanMonumentPieces::SimpleTopRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + if (roomDef->index / 25 > 0) + generateFloor(level, chunkBB, 0, 0, roomDef->hasOpening[F_DOWN]); + + if (roomDef->neighbors[F_UP] == nullptr) + generateBox(level, chunkBB, 1, 4, 1, 6, 4, 6, Tile::prismarine_Id, blockPrismarine(), false); + + + for (int i = 1; i <= 6; ++i) + for (int j = 1; j <= 6; ++j) + { + if (random->nextInt(3) != 0) + { + int k = 2 + (random->nextInt(4) == 0 ? 0 : 1); + generateBox(level, chunkBB, i, k, j, i, 3, j, Tile::sponge_Id, 1, false); + } + } + + generateBox(level, chunkBB, 0, 1, 0, 0, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 7, 1, 0, 7, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 0, 6, 1, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 7, 6, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 2, 0, 0, 2, 7, Tile::prismarine_Id, blockDarkPrismarine(), Tile::prismarine_Id, blockDarkPrismarine(),false); + generateBox(level, chunkBB, 7, 2, 0, 7, 2, 7, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 1, 2, 0, 6, 2, 0, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 1, 2, 7, 6, 2, 7, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 0, 3, 0, 0, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 7, 3, 0, 7, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 3, 0, 6, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 3, 7, 6, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 0, 1, 3, 0, 2, 4, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 7, 1, 3, 7, 2, 4, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 3, 1, 0, 4, 2, 0, Tile::prismarine_Id, blockDarkPrismarine(), Tile::prismarine_Id, blockDarkPrismarine(),false); + generateBox(level, chunkBB, 3, 1, 7, 4, 2, 7, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + if (roomDef->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 0, 4, 2, 0, false); + + return true; +} + + +// DoubleXRoom + +OceanMonumentPieces::DoubleXRoom::DoubleXRoom() {} +OceanMonumentPieces::DoubleXRoom::DoubleXRoom(int facing, RoomDefinition* room, Random* random) + : Piece(1, facing, room, 2, 1, 1) {} + +bool OceanMonumentPieces::DoubleXRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + RoomDefinition* eastRoom = roomDef->neighbors[F_EAST]; + RoomDefinition* thisRoom = roomDef; + + if (roomDef->index / 25 > 0) + { + generateFloor(level, chunkBB, 8, 0, eastRoom->hasOpening[F_DOWN]); + generateFloor(level, chunkBB, 0, 0, thisRoom->hasOpening[F_DOWN]); + } + + + if (thisRoom->neighbors[F_UP] == nullptr) + fillWaterWith(level, chunkBB, 1, 4, 1, 7, 4, 6, Tile::prismarine_Id); + if (eastRoom->neighbors[F_UP] == nullptr) + fillWaterWith(level, chunkBB, 8, 4, 1, 14, 4, 6, Tile::prismarine_Id); + + + generateBox(level, chunkBB, 0, 3, 0, 0, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 15, 3, 0, 15, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 3, 0, 15, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 3, 7, 14, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + + generateBox(level, chunkBB, 0, 2, 0, 0, 2, 7, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 15, 2, 0, 15, 2, 7, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 1, 2, 0, 15, 2, 0, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 1, 2, 7, 14, 2, 7, Tile::prismarine_Id, blockPrismarine(), false); + + generateBox(level, chunkBB, 0, 1, 0, 0, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 15, 1, 0, 15, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 1, 0, 15, 1, 0, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 1, 7, 14, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + + generateBox(level, chunkBB, 5, 1, 0, 10, 1, 4, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 6, 2, 0, 9, 2, 3, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 5, 3, 0, 10, 3, 4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + + + placeBlock(level, blockSeaLantern(), 0, 6, 2, 3, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 9, 2, 3, chunkBB); + + if (thisRoom->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 0, 4, 2, 0, false); + if (thisRoom->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 7, 4, 2, 7, false); + if (thisRoom->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 1, 3, 0, 2, 4, false); + if (eastRoom->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 11, 1, 0, 12, 2, 0, false); + if (eastRoom->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 11, 1, 7, 12, 2, 7, false); + if (eastRoom->hasOpening[F_EAST]) fillWithAirOrWater(level, chunkBB, 15, 1, 3, 15, 2, 4, false); + + return true; +} + + +// DoubleXYRoom + +OceanMonumentPieces::DoubleXYRoom::DoubleXYRoom() {} +OceanMonumentPieces::DoubleXYRoom::DoubleXYRoom(int facing, RoomDefinition* room, Random* random) + : Piece(1, facing, room, 2, 2, 1) {} + +bool OceanMonumentPieces::DoubleXYRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + RoomDefinition* r0 = roomDef; + RoomDefinition* r1 = roomDef->neighbors[F_EAST]; + RoomDefinition* r2 = r0->neighbors[F_UP]; + RoomDefinition* r3 = r1->neighbors[F_UP]; + + if (roomDef->index / 25 > 0) + { + generateFloor(level, chunkBB, 8, 0, r1->hasOpening[F_DOWN]); + generateFloor(level, chunkBB, 0, 0, r0->hasOpening[F_DOWN]); + } + + + if (r2->neighbors[F_UP] == nullptr) fillWaterWith(level, chunkBB, 1, 8, 1, 7, 8, 6, Tile::prismarine_Id); + if (r3->neighbors[F_UP] == nullptr) fillWaterWith(level, chunkBB, 8, 8, 1, 14, 8, 6, Tile::prismarine_Id); + + for (int i = 1; i <= 7; ++i) + { + + int meta = (i == 2 || i == 6) ? blockPrismarine() : blockPrismarineBricks(); + generateBox(level, chunkBB, 0, i, 0, 0, i, 7, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta,false); + generateBox(level, chunkBB, 15, i, 0, 15, i, 7, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta,false); + generateBox(level, chunkBB, 1, i, 0, 15, i, 0, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta,false); + generateBox(level, chunkBB, 1, i, 7, 14, i, 7, Tile::prismarine_Id, meta, Tile::prismarine_Id, meta,false); + } + + + generateBox(level, chunkBB, 2, 1, 3, 2, 7, 4, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 3, 1, 2, 4, 7, 2, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 3, 1, 5, 4, 7, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 13, 1, 3, 13, 7, 4, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 11, 1, 2, 12, 7, 2, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 11, 1, 5, 12, 7, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 1, 3, 5, 3, 4, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 10, 1, 3, 10, 3, 4, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 7, 2, 10, 7, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 5, 2, 5, 7, 2, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 10, 5, 2, 10, 7, 2, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 5, 5, 5, 7, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 10, 5, 5, 10, 7, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + + + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 6, 6, 2, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 9, 6, 2, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 6, 6, 5, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 9, 6, 5, chunkBB); + + generateBox(level, chunkBB, 5, 4, 3, 6, 4, 4, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 9, 4, 3, 10, 4, 4, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + + + placeBlock(level, blockSeaLantern(), 0, 5, 4, 2, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 5, 4, 5, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 10, 4, 2, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 10, 4, 5, chunkBB); + + if (r0->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 0, 4, 2, 0, false); + if (r0->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 7, 4, 2, 7, false); + if (r0->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 1, 3, 0, 2, 4, false); + if (r1->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 11, 1, 0, 12, 2, 0, false); + if (r1->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 11, 1, 7, 12, 2, 7, false); + if (r1->hasOpening[F_EAST]) fillWithAirOrWater(level, chunkBB, 15, 1, 3, 15, 2, 4, false); + if (r2->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 3, 5, 0, 4, 6, 0, false); + if (r2->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 3, 5, 7, 4, 6, 7, false); + if (r2->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 5, 3, 0, 6, 4, false); + if (r3->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 11, 5, 0, 12, 6, 0, false); + if (r3->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 11, 5, 7, 12, 6, 7, false); + if (r3->hasOpening[F_EAST]) fillWithAirOrWater(level, chunkBB, 15, 5, 3, 15, 6, 4, false); + + return true; +} + + +// DoubleYRoom + +OceanMonumentPieces::DoubleYRoom::DoubleYRoom() {} +OceanMonumentPieces::DoubleYRoom::DoubleYRoom(int facing, RoomDefinition* room, Random* random) + : Piece(1, facing, room, 1, 2, 1) {} + +bool OceanMonumentPieces::DoubleYRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + if (roomDef->index / 25 > 0) + generateFloor(level, chunkBB, 0, 0, roomDef->hasOpening[F_DOWN]); + + RoomDefinition* upRoom = roomDef->neighbors[F_UP]; + + if (upRoom->neighbors[F_UP] == nullptr) + fillWaterWith(level, chunkBB, 1, 8, 1, 6, 8, 6, Tile::prismarine_Id); + + + generateBox(level, chunkBB, 0, 4, 0, 0, 4, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 7, 4, 0, 7, 4, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 4, 0, 6, 4, 0, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 4, 7, 6, 4, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 2, 4, 1, 2, 4, 2, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 4, 2, 1, 4, 2, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 4, 1, 5, 4, 2, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 6, 4, 2, 6, 4, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 2, 4, 5, 2, 4, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 1, 4, 5, 1, 4, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 4, 5, 5, 4, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 6, 4, 5, 6, 4, 5, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + + RoomDefinition* cur = roomDef; + for (int i = 1; i <= 5; i += 4) + { + int j = 0; + if (cur->hasOpening[F_SOUTH]) { + generateBox(level, chunkBB, 2, i, j, 2, i+2, j, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 5, i, j, 5, i+2, j, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 3, i+2, j, 4, i+2, j, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } else { + generateBox(level, chunkBB, 0, i, j, 7, i+2, j, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, i+1, j, 7, i+1, j, Tile::prismarine_Id, blockPrismarine(), false); + } + + j = 7; + if (cur->hasOpening[F_NORTH]) { + generateBox(level, chunkBB, 2, i, j, 2, i+2, j, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 5, i, j, 5, i+2, j, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 3, i+2, j, 4, i+2, j, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } else { + generateBox(level, chunkBB, 0, i, j, 7, i+2, j, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, i+1, j, 7, i+1, j, Tile::prismarine_Id, blockPrismarine(), false); + } + + int k = 0; + if (cur->hasOpening[F_WEST]) { + generateBox(level, chunkBB, k, i, 2, k, i+2, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, k, i, 5, k, i+2, 5, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, k, i+2, 3, k, i+2, 4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } else { + generateBox(level, chunkBB, k, i, 0, k, i+2, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, k, i+1, 0, k, i+1, 7, Tile::prismarine_Id, blockPrismarine(), false); + } + + k = 7; + if (cur->hasOpening[F_EAST]) { + generateBox(level, chunkBB, k, i, 2, k, i+2, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, k, i, 5, k, i+2, 5, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, k, i+2, 3, k, i+2, 4, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } else { + generateBox(level, chunkBB, k, i, 0, k, i+2, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, k, i+1, 0, k, i+1, 7, Tile::prismarine_Id, blockPrismarine(), false); + } + + cur = upRoom; + } + return true; +} + + +// DoubleYZRoom + +OceanMonumentPieces::DoubleYZRoom::DoubleYZRoom() {} +OceanMonumentPieces::DoubleYZRoom::DoubleYZRoom(int facing, RoomDefinition* room, Random* random) + : Piece(1, facing, room, 1, 2, 2) {} + +bool OceanMonumentPieces::DoubleYZRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + RoomDefinition* r0 = roomDef; + RoomDefinition* r1 = roomDef->neighbors[F_NORTH]; + RoomDefinition* r2 = r1->neighbors[F_UP]; + RoomDefinition* r3 = r0->neighbors[F_UP]; + + if (roomDef->index / 25 > 0) + { + generateFloor(level, chunkBB, 0, 8, r1->hasOpening[F_DOWN]); + generateFloor(level, chunkBB, 0, 0, r0->hasOpening[F_DOWN]); + } + + + if (r3->neighbors[F_UP] == nullptr) fillWaterWith(level, chunkBB, 1, 8, 1, 6, 8, 7, Tile::prismarine_Id); + if (r2->neighbors[F_UP] == nullptr) fillWaterWith(level, chunkBB, 1, 8, 8, 6, 8, 14, Tile::prismarine_Id); + + for (int i = 1; i <= 7; ++i) + { + + int meta = (i == 2 || i == 6) ? blockPrismarine() : blockPrismarineBricks(); + generateBox(level, chunkBB, 0, i, 0, 0, i, 15, Tile::prismarine_Id, meta,Tile::prismarine_Id, meta, false); + generateBox(level, chunkBB, 7, i, 0, 7, i, 15, Tile::prismarine_Id, meta,Tile::prismarine_Id, meta, false); + generateBox(level, chunkBB, 1, i, 0, 6, i, 0, Tile::prismarine_Id, meta,Tile::prismarine_Id, meta, false); + generateBox(level, chunkBB, 1, i, 15, 6, i, 15, Tile::prismarine_Id, meta,Tile::prismarine_Id, meta, false); + } + + for (int j = 1; j <= 7; ++j) + { + + int id = (j == 2 || j == 6) ? blockSeaLantern() : Tile::prismarine_Id; + int meta = (j == 2 || j == 6) ? 0 : blockDarkPrismarine(); + + generateBox(level, chunkBB, 3, j, 7, 4, j, 8, id, meta,id, meta, false); + } + + if (r0->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 0, 4, 2, 0, false); + if (r0->hasOpening[F_EAST]) fillWithAirOrWater(level, chunkBB, 7, 1, 3, 7, 2, 4, false); + if (r0->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 1, 3, 0, 2, 4, false); + if (r1->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 15, 4, 2, 15, false); + if (r1->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 1, 11, 0, 2, 12, false); + if (r1->hasOpening[F_EAST]) fillWithAirOrWater(level, chunkBB, 7, 1, 11, 7, 2, 12, false); + if (r3->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 3, 5, 0, 4, 6, 0, false); + + // Corretti tutti i generateBox per usare Tile::prismarine_Id + blockPrismarineBricks() + if (r3->hasOpening[F_EAST]) { + fillWithAirOrWater(level, chunkBB, 7, 5, 3, 7, 6, 4, false); + generateBox(level, chunkBB, 5, 4, 2, 6, 4, 5, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 6, 1, 2, 6, 3, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 6, 1, 5, 6, 3, 5, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } + if (r3->hasOpening[F_WEST]) { + fillWithAirOrWater(level, chunkBB, 0, 5, 3, 0, 6, 4, false); + generateBox(level, chunkBB, 1, 4, 2, 2, 4, 5, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 2, 1, 3, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 5, 1, 3, 5, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } + if (r2->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 3, 5, 15, 4, 6, 15, false); + if (r2->hasOpening[F_WEST]) { + fillWithAirOrWater(level, chunkBB, 0, 5, 11, 0, 6, 12, false); + generateBox(level, chunkBB, 1, 4, 10, 2, 4, 13, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 10, 1, 3, 10, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 13, 1, 3, 13, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + } + if (r2->hasOpening[F_EAST]) { + fillWithAirOrWater(level, chunkBB, 7, 5, 11, 7, 6, 12, false); + generateBox(level, chunkBB, 5, 4, 10, 6, 4, 13, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 6, 1, 10, 6, 3, 10, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 6, 1, 13, 6, 3, 13, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + } + return true; +} + + +// DoubleZRoom + +OceanMonumentPieces::DoubleZRoom::DoubleZRoom() {} +OceanMonumentPieces::DoubleZRoom::DoubleZRoom(int facing, RoomDefinition* room, Random* random) + : Piece(1, facing, room, 1, 1, 2) {} + +bool OceanMonumentPieces::DoubleZRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + RoomDefinition* r0 = roomDef; + RoomDefinition* r1 = roomDef->neighbors[F_NORTH]; + + if (roomDef->index / 25 > 0) + { + generateFloor(level, chunkBB, 0, 8, r1->hasOpening[F_DOWN]); + generateFloor(level, chunkBB, 0, 0, r0->hasOpening[F_DOWN]); + } + + // Corretto fillWaterWith + if (r0->neighbors[F_UP] == nullptr) fillWaterWith(level, chunkBB, 1, 4, 1, 6, 4, 7, Tile::prismarine_Id); + if (r1->neighbors[F_UP] == nullptr) fillWaterWith(level, chunkBB, 1, 4, 8, 6, 4, 14, Tile::prismarine_Id); + + // Corretti i generateBox (ID, Metadato) + generateBox(level, chunkBB, 0, 3, 0, 0, 3, 15, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 7, 3, 0, 7, 3, 15, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 3, 0, 7, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 3, 15, 6, 3, 15, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 2, 0, 0, 2, 15, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 7, 2, 0, 7, 2, 15, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 1, 2, 0, 7, 2, 0, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 1, 2, 15, 6, 2, 15, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 0, 1, 0, 0, 1, 15, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 7, 1, 0, 7, 1, 15, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 0, 7, 1, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 15, 6, 1, 15, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 1, 1, 1, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 6, 1, 1, 6, 1, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 3, 1, 1, 3, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 6, 3, 1, 6, 3, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 13, 1, 1, 14, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 6, 1, 13, 6, 1, 14, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 3, 13, 1, 3, 14, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 6, 3, 13, 6, 3, 14, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 2, 1, 6, 2, 3, 6, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 5, 1, 6, 5, 3, 6, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 2, 1, 9, 2, 3, 9, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 5, 1, 9, 5, 3, 9, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 3, 2, 6, 4, 2, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 3, 2, 9, 4, 2, 9, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 2, 2, 7, 2, 2, 8, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 5, 2, 7, 5, 2, 8, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + + // Lanterne a posto + placeBlock(level, blockSeaLantern(), 0, 2, 2, 5, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 5, 2, 5, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 2, 2, 10, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 5, 2, 10, chunkBB); + + // Corretti i placeBlock dei mattoni + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 2, 3, 5, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 5, 3, 5, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 2, 3, 10, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 5, 3, 10, chunkBB); + + if (r0->hasOpening[F_SOUTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 0, 4, 2, 0, false); + if (r0->hasOpening[F_EAST]) fillWithAirOrWater(level, chunkBB, 7, 1, 3, 7, 2, 4, false); + if (r0->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 1, 3, 0, 2, 4, false); + if (r1->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 15, 4, 2, 15, false); + if (r1->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 1, 11, 0, 2, 12, false); + if (r1->hasOpening[F_EAST]) fillWithAirOrWater(level, chunkBB, 7, 1, 11, 7, 2, 12, false); + return true; +} + +// EntryRoom + +OceanMonumentPieces::EntryRoom::EntryRoom() {} +OceanMonumentPieces::EntryRoom::EntryRoom(int facing, RoomDefinition* room) + : Piece(1, facing, room, 1, 1, 1) {} + +bool OceanMonumentPieces::EntryRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + generateBox(level, chunkBB, 0, 1, 0, 2, 1, 2, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 5, 3, 0, 7, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 6, 2, 0, 7, 2, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 2, 0, 1, 2, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 1, 0, 0, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 7, 1, 0, 7, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, 1, 7, 7, 3, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 1, 0, 2, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 5, 1, 0, 6, 3, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + + if (roomDef->hasOpening[F_NORTH]) fillWithAirOrWater(level, chunkBB, 3, 1, 7, 4, 2, 7, false); + if (roomDef->hasOpening[F_WEST]) fillWithAirOrWater(level, chunkBB, 0, 1, 3, 1, 2, 4, false); + if (roomDef->hasOpening[F_EAST]) fillWithAirOrWater(level, chunkBB, 6, 1, 3, 7, 2, 4, false); + return true; +} + +// Penthouse + +OceanMonumentPieces::Penthouse::Penthouse() {} +OceanMonumentPieces::Penthouse::Penthouse(int facing, BoundingBox* box) + : Piece(facing, new BoundingBox(*box)) {} + +bool OceanMonumentPieces::Penthouse::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + generateBox(level, chunkBB, 2, -1, 2, 11, -1, 11, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 0, -1, 0, 1, -1, 11, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 12, -1, 0, 13, -1, 11, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 2, -1, 0, 11, -1, 1, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 2, -1, 12, 11, -1, 13, Tile::prismarine_Id, blockPrismarine(), false); + generateBox(level, chunkBB, 0, 0, 0, 0, 0, 13, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 13, 0, 0, 13, 0, 13, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 0, 0, 12, 0, 0, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 1, 0, 13, 12, 0, 13, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + + for (int i = 2; i <= 11; i += 3) + { + placeBlock(level, blockSeaLantern(), 0, 0, 0, i, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 13, 0, i, chunkBB); + placeBlock(level, blockSeaLantern(), 0, i, 0, 0, chunkBB); + } + + generateBox(level, chunkBB, 2, 0, 3, 4, 0, 9, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 9, 0, 3, 11, 0, 9, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 4, 0, 9, 9, 0, 11, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + + + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 5, 0, 8, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 8, 0, 8, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 10, 0,10, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 3, 0,10, chunkBB); + + generateBox(level, chunkBB, 3, 0, 3, 3, 0, 7, Tile::prismarine_Id, blockDarkPrismarine(), Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 10, 0, 3, 10, 0, 7, Tile::prismarine_Id, blockDarkPrismarine(), Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 6, 0, 10, 7, 0, 10, Tile::prismarine_Id, blockDarkPrismarine(), Tile::prismarine_Id, blockDarkPrismarine(), false); + + int col = 3; + for (int j = 0; j < 2; ++j) + { + for (int k = 2; k <= 8; k += 3) + generateBox(level, chunkBB, col, 0, k, col, 2, k, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + col = 10; + } + generateBox(level, chunkBB, 5, 0, 10, 5, 2, 10, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 8, 0, 10, 8, 2, 10, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 6, -1, 7, 7, -1, 8, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + fillWithAirOrWater(level, chunkBB, 6, -1, 3, 7, -1, 4, false); + spawnElderGuardian(level, chunkBB, 6, 1, 6); + return true; +} + + +// WingRoom + +OceanMonumentPieces::WingRoom::WingRoom() : wingType(0) {} +OceanMonumentPieces::WingRoom::WingRoom(int facing, BoundingBox* box, int seed) + : Piece(facing, new BoundingBox(*box)) +{ + wingType = seed & 1; // field_175834_o = p_i45585_3_ & 1 +} + +bool OceanMonumentPieces::WingRoom::postProcess(Level* level, Random* random, BoundingBox* chunkBB) +{ + if (wingType == 0) + { + for (int i = 0; i < 4; ++i) + generateBox(level, chunkBB, 10-i, 3-i, 20-i, 12+i, 3-i, 20, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + + generateBox(level, chunkBB, 7, 0, 6, 15, 0, 16, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 6, 0, 6, 6, 3, 20, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 16, 0, 6, 16, 3, 20, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 7, 1, 7, 7, 1, 20, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 15, 1, 7, 15, 1, 20, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 7, 1, 6, 9, 3, 6, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 13, 1, 6, 15, 3, 6, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 8, 1, 7, 9, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 13, 1, 7, 14, 1, 7, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 9, 0, 5, 13, 0, 5, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 10, 0, 7, 12, 0, 7, Tile::prismarine_Id, blockDarkPrismarine(),Tile::prismarine_Id, blockDarkPrismarine(), false); + generateBox(level, chunkBB, 8, 0, 10, 8, 0, 12, Tile::prismarine_Id, blockDarkPrismarine(), Tile::prismarine_Id, blockDarkPrismarine(),false); + generateBox(level, chunkBB, 14, 0, 10, 14, 0, 12, Tile::prismarine_Id, blockDarkPrismarine(), Tile::prismarine_Id, blockDarkPrismarine(),false); + + for (int i1 = 18; i1 >= 7; i1 -= 3) + { + placeBlock(level, blockSeaLantern(), 0, 6, 3, i1, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 16, 3, i1, chunkBB); + } + placeBlock(level, blockSeaLantern(), 0, 10, 0, 10, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 12, 0, 10, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 10, 0, 12, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 12, 0, 12, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 8, 3, 6, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 14, 3, 6, chunkBB); + + + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 4, 2, 4, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 4, 1, 4, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 4, 0, 4, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 18, 2, 4, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 18, 1, 4, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 18, 0, 4, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 4, 2, 18, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 4, 1, 18, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 4, 0, 18, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 18, 2, 18, chunkBB); + placeBlock(level, blockSeaLantern(), 0, 18, 1, 18, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 18, 0, 18, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 9, 7, 20, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), 13, 7, 20, chunkBB); + + generateBox(level, chunkBB, 6, 0, 21, 7, 4, 21, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 15, 0, 21, 16, 4, 21, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + spawnElderGuardian(level, chunkBB, 11, 2, 16); + } + else // wingType == 1 + { + generateBox(level, chunkBB, 9, 3, 18, 13, 3, 20, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 9, 0, 18, 9, 2, 18, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, 13, 0, 18, 13, 2, 18, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + + int j1 = 9; + for (int l = 0; l < 2; ++l) + { + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), j1, 6, 20, chunkBB); + placeBlock(level, blockSeaLantern(), 0, j1, 5, 20, chunkBB); + placeBlock(level, Tile::prismarine_Id, blockPrismarineBricks(), j1, 4, 20, chunkBB); + j1 = 13; + } + + generateBox(level, chunkBB, 7, 3, 7, 15, 3, 14, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + j1 = 10; + for (int k1 = 0; k1 < 2; ++k1) + { + generateBox(level, chunkBB, j1, 0, 10, j1, 6, 10, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + generateBox(level, chunkBB, j1, 0, 12, j1, 6, 12, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + placeBlock(level, blockSeaLantern(), 0, j1, 0, 10, chunkBB); + placeBlock(level, blockSeaLantern(), 0, j1, 0, 12, chunkBB); + placeBlock(level, blockSeaLantern(), 0, j1, 4, 10, chunkBB); + placeBlock(level, blockSeaLantern(), 0, j1, 4, 12, chunkBB); + j1 = 12; + } + + j1 = 8; + for (int l1 = 0; l1 < 2; ++l1) + { + generateBox(level, chunkBB, j1, 0, 7, j1, 2, 7, Tile::prismarine_Id, blockPrismarineBricks(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, j1, 0, 14, j1, 2, 14, Tile::prismarine_Id, blockPrismarineBricks(),Tile::prismarine_Id, blockPrismarineBricks(), false); + j1 = 14; + } + + generateBox(level, chunkBB, 8, 3, 8, 8, 3, 13, Tile::prismarine_Id, blockDarkPrismarine(), Tile::prismarine_Id, blockPrismarineBricks(),false); + generateBox(level, chunkBB, 14, 3, 8, 14, 3, 13, Tile::prismarine_Id, blockDarkPrismarine(), Tile::prismarine_Id, blockPrismarineBricks(),false); + spawnElderGuardian(level, chunkBB, 11, 5, 13); + } + return true; +} \ No newline at end of file diff --git a/Minecraft.World/OceanMonumentPieces.h b/Minecraft.World/OceanMonumentPieces.h new file mode 100644 index 00000000..9ebe9877 --- /dev/null +++ b/Minecraft.World/OceanMonumentPieces.h @@ -0,0 +1,287 @@ +#pragma once +#include "StructurePiece.h" +#include +#include + +class OceanMonumentPieces +{ +public: + static void loadStatic(); + + + // field_175967_a = index + // field_175965_b = neighbors[6] + // field_175966_c = hasOpening[6] + // field_175963_d = claimed + // field_175964_e = isEntrance + // field_175962_f = visitedTag + + struct RoomDefinition + { + int index; // field_175967_a + RoomDefinition* neighbors[6]; // field_175965_b + bool hasOpening[6]; // field_175966_c + bool claimed; // field_175963_d + bool isEntrance; // field_175964_e + int visitedTag; // field_175962_f + + RoomDefinition(int idx) : index(idx), claimed(false), isEntrance(false), visitedTag(0) + { + memset(hasOpening, 0, sizeof(hasOpening)); + memset(neighbors, 0, sizeof(neighbors)); + } + + // func_175957_a + void connectTo(int facing, RoomDefinition* other) + { + this->neighbors[facing] = other; + + int opposite = (facing % 2 == 0) ? facing + 1 : facing - 1; + other->neighbors[opposite] = this; + } + + // func_175958_a + void initOpenings() + { + for (int i = 0; i < 6; ++i) + hasOpening[i] = (neighbors[i] != nullptr); + } + + // func_175959_a + bool isReachable(int tag) + { + if (isEntrance) return true; + visitedTag = tag; + for (int i = 0; i < 6; ++i) + { + if (neighbors[i] != nullptr && hasOpening[i] && + neighbors[i]->visitedTag != tag && + neighbors[i]->isReachable(tag)) + return true; + } + return false; + } + + // func_175961_b + bool isSpecial() const { return index >= 75; } + + // func_175960_c + int countOpenings() const + { + int c = 0; + for (int i = 0; i < 6; ++i) + if (hasOpening[i]) ++c; + return c; + } + + private: + static int oppositeFacing(int f) + { + // DOWN=0 UP=1 NORTH=2 SOUTH=3 WEST=4 EAST=5 + static const int opp[6] = { 1, 0, 3, 2, 5, 4 }; + return opp[f]; + } + }; + + + static int blockPrismarine(); + static int blockPrismarineBricks(); + static int blockDarkPrismarine(); + static int blockWater(); + static int blockSeaLantern(); + static int blockGoldBlock(); + static int blockSponge(); + static int blockAir(); + + + class Piece : public StructurePiece + { + protected: + RoomDefinition* roomDef; // field_175830_k + + // func_175820_a(x, y, z) = y*25 + z*5 + x + static int roomIndex(int x, int y, int z) { return y * 25 + z * 5 + x; } + + static const int ENTRY_INDEX; // field_175823_g = roomIndex(2,0,0) + static const int CORE_INDEX; // field_175831_h = roomIndex(2,2,0) + static const int WING1_INDEX; // field_175832_i = roomIndex(0,1,0) + static const int WING2_INDEX; // field_175829_j = roomIndex(4,1,0) + + Piece(); + Piece(int type); + Piece(int facing, BoundingBox* box); + Piece(int type, int facing, RoomDefinition* room, int sizeX, int sizeY, int sizeZ); + + // func_181655_a + void fillWithAirOrWater(Level* level, BoundingBox* bb, int x0, int y0, int z0, int x1, int y1, int z1, bool onlySolid); + + // func_175821_a + void generateFloor(Level* level, BoundingBox* bb, int offX, int offZ, bool hasOpening); + + // func_175819_a + void fillWaterWith(Level* level, BoundingBox* bb, int x0, int y0, int z0, int x1, int y1, int z1, int block); + + // func_175818_a + bool intersectsXZ(BoundingBox* chunkBB, int x0, int z0, int x1, int z1); + + // func_175817_a + bool spawnElderGuardian(Level* level, BoundingBox* bb, int x, int y, int z); + + public: + virtual void addAdditonalSaveData(CompoundTag* tag) override; + virtual void readAdditonalSaveData(CompoundTag* tag) override; + virtual EStructurePiece GetType() = 0; + }; + + + struct RoomFitHelper + { + virtual bool canFit(RoomDefinition* room) = 0; + virtual Piece* createPiece(int facing, RoomDefinition* room, Random* random) = 0; + virtual ~RoomFitHelper() {} + }; + + + class MonumentBuilding : public Piece + { + private: + static const int ARRAY_SIZE = 75; // 5*5*3 + RoomDefinition* entryRoom; // field_175845_o + RoomDefinition* coreRoom; // field_175844_p + std::vector subPieces; // field_175843_q + + std::vector buildRoomGrid(Random* random); + + + void buildWing(bool isRight, int offsetX, Level* level, Random* random, BoundingBox* chunkBB); + void buildEntrance(Level* level, Random* random, BoundingBox* chunkBB); + void buildTopSection(Level* level, Random* random, BoundingBox* chunkBB); + void buildCorridorCenter(Level* level, Random* random, BoundingBox* chunkBB); + void buildSideCorridor(Level* level, Random* random, BoundingBox* chunkBB); + void buildInnerCorridor(Level* level, Random* random, BoundingBox* chunkBB); + void buildUpperSection(Level* level, Random* random, BoundingBox* chunkBB); + + public: + static StructurePiece* Create() { return new MonumentBuilding(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentBuilding; } + + MonumentBuilding(); + MonumentBuilding(Random* random, int x, int z, int facing); + ~MonumentBuilding(); + + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + class CoreRoom : public Piece { + public: + static StructurePiece* Create() { return new CoreRoom(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentCore; } + CoreRoom(); + CoreRoom(int facing, RoomDefinition* room, Random* random); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + + class SimpleRoom : public Piece { + private: + int variant; // field_175833_o + public: + static StructurePiece* Create() { return new SimpleRoom(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentSimple; } + SimpleRoom(); + SimpleRoom(int facing, RoomDefinition* room, Random* random); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + class SimpleTopRoom : public Piece { + public: + static StructurePiece* Create() { return new SimpleTopRoom(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentSimpleTop; } + SimpleTopRoom(); + SimpleTopRoom(int facing, RoomDefinition* room, Random* random); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + + class DoubleXRoom : public Piece { + public: + static StructurePiece* Create() { return new DoubleXRoom(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentDoubleX; } + DoubleXRoom(); + DoubleXRoom(int facing, RoomDefinition* room, Random* random); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + + class DoubleXYRoom : public Piece { + public: + static StructurePiece* Create() { return new DoubleXYRoom(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentDoubleXY; } + DoubleXYRoom(); + DoubleXYRoom(int facing, RoomDefinition* room, Random* random); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + + class DoubleYRoom : public Piece { + public: + static StructurePiece* Create() { return new DoubleYRoom(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentDoubleY; } + DoubleYRoom(); + DoubleYRoom(int facing, RoomDefinition* room, Random* random); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + + class DoubleYZRoom : public Piece { + public: + static StructurePiece* Create() { return new DoubleYZRoom(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentDoubleYZ; } + DoubleYZRoom(); + DoubleYZRoom(int facing, RoomDefinition* room, Random* random); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + + class DoubleZRoom : public Piece { + public: + static StructurePiece* Create() { return new DoubleZRoom(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentDoubleZ; } + DoubleZRoom(); + DoubleZRoom(int facing, RoomDefinition* room, Random* random); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + + + class EntryRoom : public Piece { + public: + static StructurePiece* Create() { return new EntryRoom(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentEntry; } + EntryRoom(); + EntryRoom(int facing, RoomDefinition* room); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + + class Penthouse : public Piece { + public: + static StructurePiece* Create() { return new Penthouse(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentPenthouse; } + Penthouse(); + Penthouse(int facing, BoundingBox* box); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; + + + class WingRoom : public Piece { + private: + int wingType; // field_175834_o = p_i45585_3_ & 1 + public: + static StructurePiece* Create() { return new WingRoom(); } + virtual EStructurePiece GetType() override { return eStructurePiece_OceanMonumentWing; } + WingRoom(); + WingRoom(int facing, BoundingBox* box, int seed); + virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB) override; + }; +}; diff --git a/Minecraft.World/OreFeature.cpp b/Minecraft.World/OreFeature.cpp index cea881aa..01ddb993 100644 --- a/Minecraft.World/OreFeature.cpp +++ b/Minecraft.World/OreFeature.cpp @@ -3,21 +3,27 @@ #include "net.minecraft.world.level.tile.h" #include "OreFeature.h" -void OreFeature::_init(int tile, int count, int targetTile) +void OreFeature::_init(int tile, int data, int count, int targetTile) { this->tile = tile; + this->data = data; this->count = count; this->targetTile = targetTile; } OreFeature::OreFeature(int tile, int count) { - _init(tile, count, Tile::stone_Id); + _init(tile, 0, count, Tile::stone_Id); } -OreFeature::OreFeature(int tile, int count, int targetTile) +OreFeature::OreFeature(int tile, int data, int count) { - _init(tile, count, targetTile); + _init(tile, data, count, Tile::stone_Id); +} + +OreFeature::OreFeature(int tile, int data, int count, int targetTile) +{ + _init(tile, data, count, targetTile); } bool OreFeature::place(Level *level, Random *random, int x, int y, int z) @@ -134,7 +140,7 @@ bool OreFeature::place(Level *level, Random *random, int x, int y, int z) { if ( level->getTile(x2, y2, z2) == targetTile) { - level->setTileAndData(x2, y2, z2, tile, 0, Tile::UPDATE_INVISIBLE_NO_LIGHT); + level->setTileAndData(x2, y2, z2, tile, data, Tile::UPDATE_INVISIBLE_NO_LIGHT); } } } diff --git a/Minecraft.World/OreFeature.h b/Minecraft.World/OreFeature.h index 4103f962..644851ef 100644 --- a/Minecraft.World/OreFeature.h +++ b/Minecraft.World/OreFeature.h @@ -7,13 +7,15 @@ class OreFeature : public Feature { private: int tile; + int data; int count; int targetTile; - void _init(int tile, int count, int targetTile); + void _init(int tile, int data, int count, int targetTile); public: OreFeature (int tile, int count); - OreFeature(int tile, int count, int targetTile); + OreFeature(int tile, int data, int count); + OreFeature(int tile, int data, int count, int targetTile); virtual bool place(Level *level, Random *random, int x, int y, int z); }; \ No newline at end of file diff --git a/Minecraft.World/RandomLevelSource.cpp b/Minecraft.World/RandomLevelSource.cpp index cd305df5..cc709bae 100644 --- a/Minecraft.World/RandomLevelSource.cpp +++ b/Minecraft.World/RandomLevelSource.cpp @@ -9,6 +9,8 @@ #include "net.minecraft.world.level.storage.h" #include "net.minecraft.world.entity.h" #include "RandomLevelSource.h" +#include "OceanMonumentFeature.h" + #ifdef __PS3__ #include "../Minecraft.Client/PS3/SPU_Tasks/PerlinNoise/PerlinNoiseJob.h" @@ -38,9 +40,13 @@ RandomLevelSource::RandomLevelSource(Level *level, int64_t seed, bool generateSt mineShaftFeature = new MineShaftFeature(); scatteredFeature = new RandomScatteredLargeFeature(); canyonFeature = new CanyonFeature(); + oceanMonument = new OceanMonumentFeature(); this->level = level; + oceanMonument->setLevel(level); + oceanMonument->prescanNearby(24); + random = new Random(seed); pprandom = new Random(seed); // 4J - added, so that we can have a separate random for doing post-processing in parallel with creation lperlinNoise1 = new PerlinNoise(random, 16); @@ -73,6 +79,7 @@ RandomLevelSource::~RandomLevelSource() delete mineShaftFeature; delete scatteredFeature; delete canyonFeature; + delete oceanMonument; this->level = level; @@ -361,14 +368,11 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) } -void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks, BiomeArray biomes) +void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks, byteArray blockData, BiomeArray biomes) { - int waterHeight = level->seaLevel; - double s = 1 / 32.0; doubleArray depthBuffer(16*16); // 4J - used to be declared with class level scope but moved here for thread safety - depthBuffer = perlinNoise3->getRegion(depthBuffer, xOffs * 16, zOffs * 16, 0, 16, 16, 1, s * 2, s * 2, s * 2); for (int x = 0; x < 16; x++) @@ -376,88 +380,20 @@ void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, byteArray blocks, Bi for (int z = 0; z < 16; z++) { Biome *b = biomes[z + x * 16]; - float temp = b->getTemperature(); - int runDepth = static_cast(depthBuffer[x + z * 16] / 3 + 3 + random->nextDouble() * 0.25); - int run = -1; - - byte top = b->topMaterial; - byte material = b->material; - - LevelGenerationOptions *lgo = app.getLevelGenerationOptions(); - if(lgo != nullptr) - { - lgo->getBiomeOverride(b->id,material,top); - } - - for (int y = Level::genDepthMinusOne; y >= 0; y--) - { - int offs = (z * 16 + x) * Level::genDepth + y; - - if (y <= 1 + random->nextInt(2)) // 4J - changed to make the bedrock not have bits you can get stuck in - // if (y <= 0 + random->nextInt(5)) - { - blocks[offs] = static_cast(Tile::unbreakable_Id); - } - else - { - int old = blocks[offs]; - - if (old == 0) - { - run = -1; - } - else if (old == Tile::stone_Id) - { - if (run == -1) - { - if (runDepth <= 0) - { - top = 0; - material = static_cast(Tile::stone_Id); - } - else if (y >= waterHeight - 4 && y <= waterHeight + 1) - { - top = b->topMaterial; - material = b->material; - if(lgo != nullptr) - { - lgo->getBiomeOverride(b->id,material,top); - } - } - - if (y < waterHeight && top == 0) - { - if (temp < 0.15f) top = static_cast(Tile::ice_Id); - else top = static_cast(Tile::calmWater_Id); - } - - run = runDepth; - if (y >= waterHeight - 1) blocks[offs] = top; - else blocks[offs] = material; - } - else if (run > 0) - { - run--; - blocks[offs] = material; - - // place a few sandstone blocks beneath sand runs - if (run == 0 && material == Tile::sand_Id) - { - run = random->nextInt(4); - material = static_cast(Tile::sandStone_Id); - } - } - } - } - } + + // This is equivalent to Java's biome.genTerrainBlocks(world, rand, primer, x, z, noise). + b->buildSurfaceAtDefault(level, random, blocks.data, blockData.data, + xOffs * 16 + x, zOffs * 16 + z, + depthBuffer[x + z * 16]); } } delete [] depthBuffer.data; - } + + LevelChunk *RandomLevelSource::create(int x, int z) { return getChunk(x,z); @@ -482,14 +418,16 @@ LevelChunk *RandomLevelSource::getChunk(int xOffs, int zOffs) BiomeArray biomes; level->getBiomeSource()->getBiomeBlock(biomes, xOffs * 16, zOffs * 16, 16, 16, true); - buildSurfaces(xOffs, zOffs, blocks, biomes); + // equivalent to Java's ChunkPrimer data. + + byteArray blockData(blocksSize); + memset(blockData.data, 0, blocksSize); + + buildSurfaces(xOffs, zOffs, blocks, blockData, biomes); delete [] biomes.data; caveFeature->apply(this, level, xOffs, zOffs, blocks); - // 4J Stu Design Change - 1.8 gen goes stronghold, mineshaft, village, canyon - // this changed in 1.2 to canyon, mineshaft, village, stronghold - // This change makes sense as it stops canyons running through other structures canyonFeature->apply(this, level, xOffs, zOffs, blocks); if (generateStructures) { @@ -497,18 +435,39 @@ LevelChunk *RandomLevelSource::getChunk(int xOffs, int zOffs) villageFeature->apply(this, level, xOffs, zOffs, blocks); strongholdFeature->apply(this, level, xOffs, zOffs, blocks); scatteredFeature->apply(this, level, xOffs, zOffs, blocks); + oceanMonument->apply(this, level, xOffs, zOffs, blocks); } - // canyonFeature.apply(this, level, xOffs, zOffs, blocks); - // townFeature.apply(this, level, xOffs, zOffs, blocks); - // addCaves(xOffs, zOffs, blocks); - // addTowns(xOffs, zOffs, blocks); - // levelChunk->recalcHeightmap(); // 4J - removed & moved into its own method + + byteArray nibbleData(blocksSize); + memset(nibbleData.data, 0, blocksSize); + for (int z = 0; z < 16; ++z) + { + for (int x = 0; x < 16; ++x) + { + for (int y = 0; y < Level::genDepth; ++y) + { + int srcIdx = (x * 16 + z) * Level::genDepth + y; + byte val = blockData.data[srcIdx] & 0x0F; + if (val == 0) continue; + + int rawIdx = (x << 11) | (z << 7) | y; + int byteIdx = rawIdx >> 1; + if (rawIdx & 1) + nibbleData.data[byteIdx] = static_cast((nibbleData.data[byteIdx] & 0x0F) | (val << 4)); + else + nibbleData.data[byteIdx] = static_cast((nibbleData.data[byteIdx] & 0xF0) | val); + } + } + } // 4J - this now creates compressed block data from the blocks array passed in, so moved it until after the blocks are actually finalised. We also // now need to free the passed in blocks as the LevelChunk doesn't use the passed in allocation anymore. LevelChunk *levelChunk = new LevelChunk(level, blocks, xOffs, zOffs); + levelChunk->setDataData(nibbleData); XPhysicalFree(tileData); + delete [] nibbleData.data; + delete [] blockData.data; return levelChunk; } @@ -779,6 +738,7 @@ void RandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) hasVillage = villageFeature->postProcess(level, pprandom, xt, zt); strongholdFeature->postProcess(level, pprandom, xt, zt); scatteredFeature->postProcess(level, random, xt, zt); + oceanMonument->postProcess(level, pprandom, xt, zt); } PIXEndNamedEvent(); diff --git a/Minecraft.World/RandomLevelSource.h b/Minecraft.World/RandomLevelSource.h index ef145df0..61a3584a 100644 --- a/Minecraft.World/RandomLevelSource.h +++ b/Minecraft.World/RandomLevelSource.h @@ -10,6 +10,7 @@ class VillageFeature; class MineShaftFeature; class PerlinNoise; class RandomScatteredLargeFeature; +class OceanMonumentFeature; class RandomLevelSource : public ChunkSource { @@ -59,7 +60,7 @@ public: void prepareHeights(int xOffs, int zOffs, byteArray blocks); public: - void buildSurfaces(int xOffs, int zOffs, byteArray blocks, BiomeArray biomes); + void buildSurfaces(int xOffs, int zOffs, byteArray blocks, byteArray blockData, BiomeArray biomes); private: LargeFeature *caveFeature; @@ -68,6 +69,7 @@ private: MineShaftFeature *mineShaftFeature; RandomScatteredLargeFeature *scatteredFeature; LargeFeature *canyonFeature; + OceanMonumentFeature *oceanMonument; private: virtual LevelChunk *create(int x, int z); diff --git a/Minecraft.World/RareBiomeLayer.cpp b/Minecraft.World/RareBiomeLayer.cpp new file mode 100644 index 00000000..1872601c --- /dev/null +++ b/Minecraft.World/RareBiomeLayer.cpp @@ -0,0 +1,42 @@ +#include "stdafx.h" +#include "net.minecraft.world.level.biome.h" +#include "IntCache.h" +#include "RareBiomeLayer.h" + +RareBiomeLayer::RareBiomeLayer(int64_t seed, shared_ptr parent) : Layer(seed) +{ + this->parent = parent; +} + +intArray RareBiomeLayer::getArea(int xo, int yo, int w, int h) +{ + intArray aint = this->parent->getArea(xo - 1, yo - 1, w + 2, h + 2); + intArray aint1 = IntCache::allocate(w * h); + + for (int i = 0; i < h; ++i) + { + for (int j = 0; j < w; ++j) + { + this->initRandom((int64_t)(j + xo), (int64_t)(i + yo)); + int k = aint[j + 1 + (i + 1) * (w + 2)]; + + if (this->nextRandom(57) == 0) + { + if (k == Biome::plains->id) + { + aint1[j + i * w] = Biome::plains->id + 256; + } + else + { + aint1[j + i * w] = k; + } + } + else + { + aint1[j + i * w] = k; + } + } + } + + return aint1; +} diff --git a/Minecraft.World/RareBiomeLayer.h b/Minecraft.World/RareBiomeLayer.h new file mode 100644 index 00000000..b3f1b523 --- /dev/null +++ b/Minecraft.World/RareBiomeLayer.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Layer.h" + +class RareBiomeLayer : public Layer +{ +public: + RareBiomeLayer(int64_t seed, shared_ptr parent); + virtual ~RareBiomeLayer() {} + virtual intArray getArea(int xo, int yo, int w, int h) override; +}; diff --git a/Minecraft.World/RegionHillsLayer.cpp b/Minecraft.World/RegionHillsLayer.cpp index 7e3a9e83..9e5fc420 100644 --- a/Minecraft.World/RegionHillsLayer.cpp +++ b/Minecraft.World/RegionHillsLayer.cpp @@ -3,89 +3,158 @@ #include "IntCache.h" #include "RegionHillsLayer.h" + + RegionHillsLayer::RegionHillsLayer(int64_t seed, shared_ptr parent) : Layer(seed) { this->parent = parent; + this->riverNoise = nullptr; } +RegionHillsLayer::RegionHillsLayer(int64_t seed, shared_ptr parent, shared_ptr riverNoise) : Layer(seed) +{ + this->parent = parent; + this->riverNoise = riverNoise; +} + +void RegionHillsLayer::init(int64_t seed) +{ + Layer::init(seed); + if (riverNoise != nullptr) + riverNoise->init(seed); +} + + +bool RegionHillsLayer::biomesEqualOrMesaPlateau(int a, int b) +{ + return a == b; +} + + intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h) { - intArray b = parent->getArea(xo - 1, yo - 1, w + 2, h + 2); + + intArray b = parent->getArea(xo - 1, yo - 1, w + 2, h + 2); + intArray noise = (riverNoise != nullptr) + ? riverNoise->getArea(xo - 1, yo - 1, w + 2, h + 2) + : IntCache::allocate((w + 2) * (h + 2)); intArray result = IntCache::allocate(w * h); - for (int y = 0; y < h; y++) + + for (int y = 0; y < h; ++y) { - for (int x = 0; x < w; x++) + for (int x = 0; x < w; ++x) { initRandom(x + xo, y + yo); - int old = b[(x + 1) + (y + 1) * (w + 2)]; - if (nextRandom(3) == 0) - { - int next = old; - if (old == Biome::desert->id) - { - next = Biome::desertHills->id; - } - else if (old == Biome::forest->id) - { - next = Biome::forestHills->id; - } - else if (old == Biome::taiga->id) - { - next = Biome::taigaHills->id; - } - else if (old == Biome::coldTaiga->id) - { - next = Biome::coldTaigaHills->id; - } - else if (old == Biome::megaTaiga->id) - { - next = Biome::megaTaigaHills->id; - } - else if (old == Biome::plains->id) - { - next = Biome::forest->id; - } - else if (old == Biome::iceFlats->id) - { - next = Biome::iceMountains->id; - } - else if (old == Biome::iceFlats->id) - { - next = Biome::iceSpikes->id; - } - else if (old == Biome::jungle->id) - { - next = Biome::jungleHills->id; - } - /*else if (old == Biome::savanna->id) - { - next = Biome::savannaPlateau->id; - }*/ - if (next == old) - { - result[x + y * w] = old; - } - else - { - int _n = b[(x + 1) + (y + 1 - 1) * (w + 2)]; - int _e = b[(x + 1 + 1) + (y + 1) * (w + 2)]; - int _w = b[(x + 1 - 1) + (y + 1) * (w + 2)]; - int _s = b[(x + 1) + (y + 1 + 1) * (w + 2)]; - if (_n == old && _e == old && _w == old && _s == old) - { - result[x + y * w] = next; - } - else - { - result[x + y * w] = old; - } - } + int k = b [x + 1 + (y + 1) * (w + 2)]; + int l = noise[x + 1 + (y + 1) * (w + 2)]; + + + bool flag = (riverNoise != nullptr) && ((l - 2) % 29 == 0); + + if (riverNoise != nullptr && k != 0 && l >= 2 && (l - 2) % 29 == 1 && k < 128) + { + + result[x + y * w] = k; + } + else if (nextRandom(3) != 0 && !flag) + { + + result[x + y * w] = k; } else { - result[x + y * w] = old; + + int i1 = k; + + if (k == Biome::desert->id) + { + i1 = Biome::desertHills->id; + } + else if (k == Biome::forest->id) + { + i1 = Biome::forestHills->id; + } + else if (k == Biome::birchForest->id) + { + i1 = Biome::birchForestHills->id; + } + else if (k == Biome::roofedForest->id) + { + // Java: roofedForest -> plains + i1 = Biome::plains->id; + } + else if (k == Biome::taiga->id) + { + i1 = Biome::taigaHills->id; + } + else if (k == Biome::megaTaiga->id) + { + i1 = Biome::megaTaigaHills->id; + } + else if (k == Biome::coldTaiga->id) + { + i1 = Biome::coldTaigaHills->id; + } + else if (k == Biome::plains->id) + { + if (nextRandom(3) == 0) + i1 = Biome::forestHills->id; + else + i1 = Biome::forest->id; + } + else if (k == Biome::iceFlats->id) + { + i1 = Biome::iceMountains->id; + } + else if (k == Biome::jungle->id) + { + i1 = Biome::jungleHills->id; + } + else if (k == Biome::ocean->id) + { + // java: ocean → deepOcean + i1 = Biome::deepOcean->id; + } + else if (k == Biome::extremeHills->id) + { + i1 = Biome::smallerExtremeHills->id; + } + else if (k == Biome::savanna->id) + { + // Java: savanna → savannaPlateau + + i1 = Biome::savannaPlateau->id; + } + else if (k == Biome::deepOcean->id && nextRandom(3) == 0) + { + + i1 = (nextRandom(2) == 0) ? Biome::plains->id : Biome::forest->id; + } + + + + if (i1 == k) + { + result[x + y * w] = k; + } + else + { + + int _n = b[x + 1 + (y + 1 - 1) * (w + 2)]; + int _e = b[x + 1 + 1 + (y + 1) * (w + 2)]; + int _w = b[x + 1 - 1 + (y + 1) * (w + 2)]; + int _s = b[x + 1 + (y + 1 + 1) * (w + 2)]; + + int neighbours = 0; + if (biomesEqualOrMesaPlateau(_n, k)) ++neighbours; + if (biomesEqualOrMesaPlateau(_e, k)) ++neighbours; + if (biomesEqualOrMesaPlateau(_w, k)) ++neighbours; + if (biomesEqualOrMesaPlateau(_s, k)) ++neighbours; + + result[x + y * w] = (neighbours >= 3) ? i1 : k; + } } } } diff --git a/Minecraft.World/RegionHillsLayer.h b/Minecraft.World/RegionHillsLayer.h index 5ad0bb75..ef4c1bf3 100644 --- a/Minecraft.World/RegionHillsLayer.h +++ b/Minecraft.World/RegionHillsLayer.h @@ -4,8 +4,16 @@ class RegionHillsLayer : public Layer { -public: - RegionHillsLayer(int64_t seed, shared_ptr parent); +private: + shared_ptr riverNoise; // second parent: zoomed river init layer used as noise source - intArray getArea(int xo, int yo, int w, int h); +public: + RegionHillsLayer(int64_t seed, shared_ptr parent); + RegionHillsLayer(int64_t seed, shared_ptr parent, shared_ptr riverNoise); + + virtual void init(int64_t seed) override; + virtual intArray getArea(int xo, int yo, int w, int h) override; + +private: + static bool biomesEqualOrMesaPlateau(int a, int b); }; \ No newline at end of file diff --git a/Minecraft.World/RemoveTooMuchOceanLayer.cpp b/Minecraft.World/RemoveTooMuchOceanLayer.cpp new file mode 100644 index 00000000..4a095b3b --- /dev/null +++ b/Minecraft.World/RemoveTooMuchOceanLayer.cpp @@ -0,0 +1,40 @@ +#include "stdafx.h" +#include "net.minecraft.world.level.biome.h" +#include "IntCache.h" +#include "RemoveTooMuchOceanLayer.h" + +RemoveTooMuchOceanLayer::RemoveTooMuchOceanLayer(int64_t seed, shared_ptr parent) : Layer(seed) +{ + this->parent = parent; +} + +intArray RemoveTooMuchOceanLayer::getArea(int xo, int yo, int w, int h) +{ + int i = xo - 1; + int j = yo - 1; + int k = w + 2; + int l = h + 2; + intArray aint = this->parent->getArea(i, j, k, l); + intArray aint1 = IntCache::allocate(w * h); + + for (int i1 = 0; i1 < h; ++i1) + { + for (int j1 = 0; j1 < w; ++j1) + { + int k1 = aint[j1 + 1 + (i1 + 1 - 1) * (w + 2)]; + int l1 = aint[j1 + 1 + 1 + (i1 + 1) * (w + 2)]; + int i2 = aint[j1 + 1 - 1 + (i1 + 1) * (w + 2)]; + int j2 = aint[j1 + 1 + (i1 + 1 + 1) * (w + 2)]; + int k2 = aint[j1 + 1 + (i1 + 1) * k]; + aint1[j1 + i1 * w] = k2; + this->initRandom((int64_t)(j1 + xo), (int64_t)(i1 + yo)); + + if (k2 == 0 && k1 == 0 && l1 == 0 && i2 == 0 && j2 == 0) + { + aint1[j1 + i1 * w] = 1; + } + } + } + + return aint1; +} diff --git a/Minecraft.World/RemoveTooMuchOceanLayer.h b/Minecraft.World/RemoveTooMuchOceanLayer.h new file mode 100644 index 00000000..87ade519 --- /dev/null +++ b/Minecraft.World/RemoveTooMuchOceanLayer.h @@ -0,0 +1,11 @@ +#pragma once + +#include "Layer.h" + +class RemoveTooMuchOceanLayer : public Layer +{ +public: + RemoveTooMuchOceanLayer(int64_t seed, shared_ptr parent); + virtual ~RemoveTooMuchOceanLayer() {} + virtual intArray getArea(int xo, int yo, int w, int h) override; +}; diff --git a/Minecraft.World/RiverMixerLayer.cpp b/Minecraft.World/RiverMixerLayer.cpp index 4de49245..de6d4a5d 100644 --- a/Minecraft.World/RiverMixerLayer.cpp +++ b/Minecraft.World/RiverMixerLayer.cpp @@ -23,7 +23,7 @@ intArray RiverMixerLayer::getArea(int xo, int yo, int w, int h) intArray result = IntCache::allocate(w * h); for (int i = 0; i < w * h; i++) { - if (b[i] == Biome::ocean->id) + if (b[i] == Biome::ocean->id || b[i] == Biome::deepOcean->id) { result[i] = b[i]; diff --git a/Minecraft.World/SavannaBiome.cpp b/Minecraft.World/SavannaBiome.cpp index 58cb9317..3428618c 100644 --- a/Minecraft.World/SavannaBiome.cpp +++ b/Minecraft.World/SavannaBiome.cpp @@ -39,7 +39,7 @@ int SavannaBiome::getGrassColor() const return 0xBFB755; } -int SavannaBiome::getFoliageColor() const +int SavannaBiome::getFolageColor() const { return 0xAEA42A; } diff --git a/Minecraft.World/SavannaBiome.h b/Minecraft.World/SavannaBiome.h index 5d8f3ab5..9aea9d0f 100644 --- a/Minecraft.World/SavannaBiome.h +++ b/Minecraft.World/SavannaBiome.h @@ -8,7 +8,7 @@ public: SavannaBiome(int id); virtual Feature *getTreeFeature(Random *random); - virtual int getFoliageColor() const override; + virtual int getFolageColor() const override; virtual int getGrassColor() const override; //virtual int getWaterColor() override; virtual Feature *getFlowerFeature(Random *random, int x, int y, int z) override; diff --git a/Minecraft.World/ScatteredFeaturePieces.cpp b/Minecraft.World/ScatteredFeaturePieces.cpp index 2d6ac249..18082e46 100644 --- a/Minecraft.World/ScatteredFeaturePieces.cpp +++ b/Minecraft.World/ScatteredFeaturePieces.cpp @@ -673,15 +673,15 @@ bool ScatteredFeaturePieces::SwamplandHut::postProcess(Level *level, Random *ran } // floor and ceiling - generateBox(level, chunkBB, 1, 1, 1, 5, 1, 7, Tile::wood_Id, TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK, false); - generateBox(level, chunkBB, 1, 4, 2, 5, 4, 7, Tile::wood_Id, TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK, false); - generateBox(level, chunkBB, 2, 1, 0, 4, 1, 0, Tile::wood_Id, TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK, false); + generateBox(level, chunkBB, 1, 1, 1, 5, 1, 7, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 1, 4, 2, 5, 4, 7, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 2, 1, 0, 4, 1, 0, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); // walls - generateBox(level, chunkBB, 2, 2, 2, 3, 3, 2, Tile::wood_Id, TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK, false); - generateBox(level, chunkBB, 1, 2, 3, 1, 3, 6, Tile::wood_Id, TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK, false); - generateBox(level, chunkBB, 5, 2, 3, 5, 3, 6, Tile::wood_Id, TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK, false); - generateBox(level, chunkBB, 2, 2, 7, 4, 3, 7, Tile::wood_Id, TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK, false); + generateBox(level, chunkBB, 2, 2, 2, 3, 3, 2, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 1, 2, 3, 1, 3, 6, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 5, 2, 3, 5, 3, 6, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); + generateBox(level, chunkBB, 2, 2, 7, 4, 3, 7, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, Tile::wood_Id, TreeTile::SPRUCE_TRUNK, false); // pillars generateBox(level, chunkBB, 1, 0, 2, 1, 3, 2, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); diff --git a/Minecraft.World/ShoreLayer.cpp b/Minecraft.World/ShoreLayer.cpp index 7ae52557..a03277dc 100644 --- a/Minecraft.World/ShoreLayer.cpp +++ b/Minecraft.World/ShoreLayer.cpp @@ -24,7 +24,7 @@ intArray ShoreLayer::getArea(int xo, int yo, int w, int h) int _e = b[(x + 1 + 1) + (y + 1) * (w + 2)]; int _w = b[(x + 1 - 1) + (y + 1) * (w + 2)]; int _s = b[(x + 1) + (y + 1 + 1) * (w + 2)]; - if (_n == Biome::ocean->id || _e == Biome::ocean->id || _w == Biome::ocean->id || _s == Biome::ocean->id) + if (_n == Biome::ocean->id || _e == Biome::ocean->id || _w == Biome::ocean->id || _s == Biome::ocean->id || _n == Biome::deepOcean->id || _e == Biome::deepOcean->id || _w == Biome::deepOcean->id || _s == Biome::deepOcean->id) { result[x + y * w] = Biome::mushroomIslandShore->id; } @@ -33,15 +33,22 @@ intArray ShoreLayer::getArea(int xo, int yo, int w, int h) result[x + y * w] = old; } } - else if (old != Biome::ocean->id && old != Biome::river->id && old != Biome::swampland->id && old != Biome::extremeHills->id) + else if (old != Biome::ocean->id && old != Biome::deepOcean->id && old != Biome::river->id && old != Biome::swampland->id && old != Biome::extremeHills->id) { int _n = b[(x + 1) + (y + 1 - 1) * (w + 2)]; int _e = b[(x + 1 + 1) + (y + 1) * (w + 2)]; int _w = b[(x + 1 - 1) + (y + 1) * (w + 2)]; int _s = b[(x + 1) + (y + 1 + 1) * (w + 2)]; - if (_n == Biome::ocean->id || _e == Biome::ocean->id || _w == Biome::ocean->id || _s == Biome::ocean->id) + if (_n == Biome::ocean->id || _e == Biome::ocean->id || _w == Biome::ocean->id || _s == Biome::ocean->id || _n == Biome::deepOcean->id || _e == Biome::deepOcean->id || _w == Biome::deepOcean->id || _s == Biome::deepOcean->id) { - result[x + y * w] = Biome::beaches->id; + if (old == Biome::taiga->id || old == Biome::taigaHills->id || old == Biome::megaTaiga->id || old == Biome::megaTaigaHills->id || old == Biome::coldTaiga->id || old == Biome::coldTaigaHills->id) + { + result[x + y * w] = Biome::coldBeach->id; + } + else + { + result[x + y * w] = Biome::beaches->id; + } } else { diff --git a/Minecraft.World/StrongholdFeature.cpp b/Minecraft.World/StrongholdFeature.cpp index 2e702565..cdd36571 100644 --- a/Minecraft.World/StrongholdFeature.cpp +++ b/Minecraft.World/StrongholdFeature.cpp @@ -32,6 +32,13 @@ void StrongholdFeature::staticCtor() allowedBiomes.push_back(Biome::savanna); allowedBiomes.push_back(Biome::roofedForest); allowedBiomes.push_back(Biome::flowerForest); + allowedBiomes.push_back(Biome::coldTaiga); + allowedBiomes.push_back(Biome::megaTaiga); + allowedBiomes.push_back(Biome::coldTaigaHills); + allowedBiomes.push_back(Biome::coldTaigaM); + allowedBiomes.push_back(Biome::taigaM); + allowedBiomes.push_back(Biome::megaTaigaHills); + }; void StrongholdFeature::_init() diff --git a/Minecraft.World/StructureFeatureIO.cpp b/Minecraft.World/StructureFeatureIO.cpp index 784d14c9..b93c7e35 100644 --- a/Minecraft.World/StructureFeatureIO.cpp +++ b/Minecraft.World/StructureFeatureIO.cpp @@ -27,7 +27,9 @@ void StructureFeatureIO::staticCtor() setStartId(eStructureStart_NetherBridgeStart, NetherBridgeFeature::NetherBridgeStart::Create, L"Fortress"); setStartId(eStructureStart_StrongholdStart, StrongholdFeature::StrongholdStart::Create, L"Stronghold"); setStartId(eStructureStart_ScatteredFeatureStart, RandomScatteredLargeFeature::ScatteredFeatureStart::Create, L"Temple"); + setStartId(eStructureStart_Monument, OceanMonumentFeature::MonumentStart::Create, L"Monument"); + OceanMonumentPieces::loadStatic(); MineShaftPieces::loadStatic(); VillagePieces::loadStatic(); NetherBridgePieces::loadStatic(); diff --git a/Minecraft.World/StructureFeatureIO.h b/Minecraft.World/StructureFeatureIO.h index 90fc115d..aeb17b87 100644 --- a/Minecraft.World/StructureFeatureIO.h +++ b/Minecraft.World/StructureFeatureIO.h @@ -13,6 +13,7 @@ enum EStructureStart eStructureStart_NetherBridgeStart, eStructureStart_StrongholdStart, eStructureStart_ScatteredFeatureStart, + eStructureStart_Monument, }; enum EStructurePiece @@ -42,6 +43,20 @@ enum EStructurePiece eStructurePiece_JunglePyramidPiece, eStructurePiece_SwamplandHut, + eStructurePiece_OceanMonumentBuilding, + eStructurePiece_OceanMonumentCore, + eStructurePiece_OceanMonumentDoubleX, + eStructurePiece_OceanMonumentDoubleXY, + eStructurePiece_OceanMonumentDoubleY, + eStructurePiece_OceanMonumentDoubleYZ, + eStructurePiece_OceanMonumentDoubleZ, + eStructurePiece_OceanMonumentEntry, + eStructurePiece_OceanMonumentPenthouse, + eStructurePiece_OceanMonumentSimple, + eStructurePiece_OceanMonumentSimpleTop, + eStructurePiece_OceanMonumentWing, + + eStructurePiece_FillerCorridor, eStructurePiece_StairsDown, eStructurePiece_Straight, diff --git a/Minecraft.World/SwampBiome.cpp b/Minecraft.World/SwampBiome.cpp index be229aa6..a7a0f489 100644 --- a/Minecraft.World/SwampBiome.cpp +++ b/Minecraft.World/SwampBiome.cpp @@ -35,9 +35,9 @@ void SwampBiome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunk int localX = x & 15; int localZ = z & 15; - for (int y = 255; y >= 0; --y) + for (int y = Level::genDepthMinusOne; y >= 0; --y) { - int index = (localX * 16 + localZ) * 256 + y; + int index = (localZ * 16 + localX) * Level::genDepth + y; if (chunkBlocks[index] != 0) { if (y == 62 && chunkBlocks[index] != static_cast(Tile::water_Id)) diff --git a/Minecraft.World/TaigaBiome.cpp b/Minecraft.World/TaigaBiome.cpp index 7300a2a8..7e9d9e58 100644 --- a/Minecraft.World/TaigaBiome.cpp +++ b/Minecraft.World/TaigaBiome.cpp @@ -82,14 +82,17 @@ void TaigaBiome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunk if (type == 1 || type == 2) { topMaterial = static_cast(Tile::grass_Id); + topMaterialData = 0; material = static_cast(Tile::dirt_Id); if (noiseVal > 1.75) { topMaterial = static_cast(Tile::dirt_Id); + topMaterialData = 1; } else if (noiseVal > -0.95) { topMaterial = static_cast(Tile::dirt_Id); + topMaterialData = 2; } } Biome::buildSurfaceAtDefault(level, random, chunkBlocks, x, z, noiseVal); diff --git a/Minecraft.World/Tile.h b/Minecraft.World/Tile.h index 9d6c177b..29faecdf 100644 --- a/Minecraft.World/Tile.h +++ b/Minecraft.World/Tile.h @@ -188,6 +188,7 @@ public: static bool propagate[TILE_NUM_COUNT]; // 4J - this array of simple constants made so the compiler can optimise references to Ids that were previous of the form Tile::->id, and are now simply Tile::whatever_Id + static const int air_Id = 0; static const int stone_Id = 1; static const int grass_Id = 2; static const int dirt_Id = 3; diff --git a/Minecraft.World/cmake/sources/Common.cmake b/Minecraft.World/cmake/sources/Common.cmake index 19e92eaf..2856d770 100644 --- a/Minecraft.World/cmake/sources/Common.cmake +++ b/Minecraft.World/cmake/sources/Common.cmake @@ -1352,6 +1352,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_BIOME "${CMAKE_CURRENT_SOURCE_DIR}/TheEndBiomeDecorator.h" "${CMAKE_CURRENT_SOURCE_DIR}/WaterlilyFeature.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/WaterlilyFeature.h" + "${CMAKE_CURRENT_SOURCE_DIR}/MesaBiome.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/MesaBiome.h" "${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.level.biome.h" ) source_group("net/minecraft/world/level/biome" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_BIOME}) @@ -1374,6 +1376,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_CHUNK "${CMAKE_CURRENT_SOURCE_DIR}/SparseLightStorage.h" "${CMAKE_CURRENT_SOURCE_DIR}/WaterLevelChunk.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/WaterLevelChunk.h" + "${CMAKE_CURRENT_SOURCE_DIR}/ChunkPrimer.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/ChunkPrimer.h" "${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.level.chunk.h" ) source_group("net/minecraft/world/level/chunk" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_CHUNK}) @@ -1563,6 +1567,10 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_STRUCTURE "${CMAKE_CURRENT_SOURCE_DIR}/VillagePieces.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/VillagePieces.h" "${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.level.levelgen.structure.h" + "${CMAKE_CURRENT_SOURCE_DIR}/OceanMonumentFeature.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/OceanMonumentFeature.h" +"${CMAKE_CURRENT_SOURCE_DIR}/OceanMonumentPieces.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/OceanMonumentPieces.h" ) source_group("net/minecraft/world/level/levelgen/structure" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_STRUCTURE}) @@ -1656,6 +1664,12 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_NEWBIOME_LAYER "${CMAKE_CURRENT_SOURCE_DIR}/VoronoiZoom.h" "${CMAKE_CURRENT_SOURCE_DIR}/ZoomLayer.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/ZoomLayer.h" + "${CMAKE_CURRENT_SOURCE_DIR}/DeepOceanLayer.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/DeepOceanLayer.h" +"${CMAKE_CURRENT_SOURCE_DIR}/RemoveTooMuchOceanLayer.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/RemoveTooMuchOceanLayer.h" +"${CMAKE_CURRENT_SOURCE_DIR}/RareBiomeLayer.cpp" +"${CMAKE_CURRENT_SOURCE_DIR}/RareBiomeLayer.h" "${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.level.newbiome.layer.h" ) source_group("net/minecraft/world/level/newbiome/layer" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_NEWBIOME_LAYER}) diff --git a/Minecraft.World/net.minecraft.world.level.biome.h b/Minecraft.World/net.minecraft.world.level.biome.h index 8339e462..b7e0bc60 100644 --- a/Minecraft.World/net.minecraft.world.level.biome.h +++ b/Minecraft.World/net.minecraft.world.level.biome.h @@ -25,6 +25,7 @@ #include "PlainsBiome.h" #include "RiverBiome.h" + // 1.1 #include "BeachBiome.h" @@ -32,4 +33,5 @@ #include "JungleBiome.h" //TU31 -#include "SavannaBiome.h" \ No newline at end of file +#include "SavannaBiome.h" +#include "MesaBiome.h" \ No newline at end of file diff --git a/Minecraft.World/net.minecraft.world.level.levelgen.structure.h b/Minecraft.World/net.minecraft.world.level.levelgen.structure.h index e7dae5ea..0619437b 100644 --- a/Minecraft.World/net.minecraft.world.level.levelgen.structure.h +++ b/Minecraft.World/net.minecraft.world.level.levelgen.structure.h @@ -12,9 +12,11 @@ #include "StructureFeature.h" #include "StructureFeatureIO.h" #include "StructureFeatureSavedData.h" +#include "OceanMonumentFeature.h" +#include "OceanMonumentPieces.h" #include "StructurePiece.h" #include "StructureStart.h" #include "VillageFeature.h" #include "VillagePieces.h" #include "RandomScatteredLargeFeature.h" -#include "ScatteredFeaturePieces.h" \ No newline at end of file +#include "ScatteredFeaturePieces.h" diff --git a/Minecraft.World/net.minecraft.world.level.newbiome.layer.h b/Minecraft.World/net.minecraft.world.level.newbiome.layer.h index c45659d4..b6f93cb2 100644 --- a/Minecraft.World/net.minecraft.world.level.newbiome.layer.h +++ b/Minecraft.World/net.minecraft.world.level.newbiome.layer.h @@ -8,9 +8,12 @@ #include "DownfallMixerLayer.h" #include "FlatLayer.h" #include "FuzzyZoomLayer.h" +#include "DeepOceanLayer.h" #include "IntCache.h" #include "IslandLayer.h" #include "Layer.h" +#include "RemoveTooMuchOceanLayer.h" +#include "RareBiomeLayer.h" #include "RiverInitLayer.h" #include "RiverLayer.h" #include "RiverMixerLayer.h"