diff --git a/Minecraft.World/BiomeInitLayer.cpp b/Minecraft.World/BiomeInitLayer.cpp index 61363308..bdba2915 100644 --- a/Minecraft.World/BiomeInitLayer.cpp +++ b/Minecraft.World/BiomeInitLayer.cpp @@ -1,71 +1,74 @@ -#include "stdafx.h" +#include "stdafx.h" #include "net.minecraft.world.level.biome.h" #include "net.minecraft.world.level.newbiome.layer.h" #include "net.minecraft.world.level.h" #include "BiomeInitLayer.h" +#include "Biome.h" + +struct CustomizableSourceSettings { + char pad[100]; + int biome; +}; BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptr parent, int64_t seedMixup, LevelType *levelType, void* superflatConfig) : Layer(seedMixup) { - this->parent = parent; - bLegacy1_1 = (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; - startBiomes[2] = Biome::extremeHills; - startBiomes[3] = Biome::swampland; - startBiomes[4] = Biome::plains; - startBiomes[5] = Biome::taiga; - } - else - { - - // - // 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; + this->parent = parent; + this->customSettings = nullptr; + desertBiomes = BiomeArray(6); + warmBiomes = BiomeArray(6); + coolBiomes = BiomeArray(4); + icyBiomes = BiomeArray(4); + if (levelType == LevelType::lvl_normal_1_1) + { + + desertBiomes[0] = Biome::desert; + desertBiomes[1] = Biome::forest; + desertBiomes[2] = Biome::extremeHills; + desertBiomes[3] = Biome::swampland; + desertBiomes[4] = Biome::plains; + desertBiomes[5] = Biome::taiga; + + } + else + { + + 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[0] = Biome::forest; + warmBiomes[1] = Biome::roofedForest; + warmBiomes[2] = Biome::extremeHills; + warmBiomes[3] = Biome::plains; warmBiomes[4] = Biome::birchForest; - warmBiomes[5] = Biome::plains; - warmBiomes[6] = Biome::mesaPlateauF; + warmBiomes[5] = Biome::swampland; + - // 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); + + coolBiomes[0] = Biome::forest; + coolBiomes[1] = Biome::extremeHills; + coolBiomes[2] = Biome::taiga; + coolBiomes[3] = Biome::plains; + icyBiomes[0] = Biome::iceFlats; icyBiomes[1] = Biome::iceFlats; - icyBiomes[2] = Biome::coldTaiga; - } + icyBiomes[2] = Biome::iceFlats; + icyBiomes[3] = Biome::coldTaiga; + + + if (levelType != LevelType::lvl_normal_1_1 && levelType == LevelType::lvl_flat) + { + this->customSettings = (CustomizableSourceSettings*)superflatConfig; + } } BiomeInitLayer::~BiomeInitLayer() { - delete [] startBiomes.data; + delete [] desertBiomes.data; delete [] warmBiomes.data; delete [] coolBiomes.data; @@ -74,103 +77,84 @@ BiomeInitLayer::~BiomeInitLayer() intArray BiomeInitLayer::getArea(int xo, int yo, int w, int h) { - intArray b = parent->getArea(xo, yo, w, h); + intArray b = parent->getArea(xo, yo, w, h); + intArray result = IntCache::allocate(w * h); - intArray result = IntCache::allocate(w * h); - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - initRandom(x + xo, y + yo); - int k = b[x + y * w]; + if (h > 0) + { + for (int y = 0; y < h; y++) + { + if (w > 0) + { + for (int x = 0; x < w; x++) + { + initRandom(x + xo, y + yo); - // flat list - if (bLegacy1_1) - { - if (k == 0) - { - 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; - } + int val = b[x + y * w]; + int v18 = (val >> 8) & 0xF; + int v19 = val & 0xFFFFF0FF; - + if (customSettings && customSettings->biome >= 0) + { + result[x + y * w] = customSettings->biome; + 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 bits flag. - int rareBit = (k & 3840) >> 8; // Java: (k & 0xF00) >> 8 - k = k & ~3840; + if (isOcean(v19) || v19 == Biome::mushroomIsland->id) + { + result[x + y * w] = v19; + continue; + } - - 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 - { - - 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 + 128) - { - result[x + y * w] = Biome::sunflowersPlains->id; - } - else - { - - result[x + y * w] = k; - } - } - } + if (v19 == 1) + { + if (v18 <= 0) + { + result[x + y * w] = desertBiomes[nextRandom(desertBiomes.length)]->id; + } + else if (nextRandom(3)) + { + result[x + y * w] = Biome::mesaPlateauF->id; + } + else + { + result[x + y * w] = Biome::plains->id; + } + } + else if (v19 == 2) + { + if (v18 <= 0) + { + result[x + y * w] = warmBiomes[nextRandom(warmBiomes.length)]->id; + } + else + { + result[x + y * w] = Biome::jungle->id; + } + } + else if (v19 == 3) + { + if (v18 <= 0) + { + result[x + y * w] = coolBiomes[nextRandom(coolBiomes.length)]->id; + } + else + { + result[x + y * w] = Biome::megaTaiga->id; + } + } + else if (v19 == 4) + { + result[x + y * w] = icyBiomes[nextRandom(icyBiomes.length)]->id; + } + else + { + result[x + y * w] = v19; + } + } + } + } + } - return result; + return result; } \ No newline at end of file diff --git a/Minecraft.World/BiomeInitLayer.h b/Minecraft.World/BiomeInitLayer.h index a703e855..289da3d5 100644 --- a/Minecraft.World/BiomeInitLayer.h +++ b/Minecraft.World/BiomeInitLayer.h @@ -1,25 +1,24 @@ #pragma once #include "Layer.h" +#include class LevelType; +class Biome; +struct CustomizableSourceSettings; class BiomeInitLayer : public Layer { private: - - BiomeArray startBiomes; - - // matching Java GenLayerBiome - BiomeArray desertBiomes; - BiomeArray warmBiomes; - BiomeArray coolBiomes; - BiomeArray icyBiomes; - - bool bLegacy1_1; + BiomeArray desertBiomes; + BiomeArray warmBiomes; + BiomeArray coolBiomes; + BiomeArray icyBiomes; + + CustomizableSourceSettings* customSettings; public: - BiomeInitLayer(int64_t seed, shared_ptr parent, int64_t seedMixup, LevelType *levelType, void* superflatConfig); - virtual ~BiomeInitLayer(); - intArray getArea(int xo, int yo, int w, int h); -}; + BiomeInitLayer(int64_t seed, shared_ptr parent, int64_t seedMixup, LevelType *levelType, void* superflatConfig); + virtual ~BiomeInitLayer(); + intArray getArea(int xo, int yo, int w, int h) override; +}; \ No newline at end of file diff --git a/Minecraft.World/BiomeSource.cpp b/Minecraft.World/BiomeSource.cpp index 7b3fc078..e010b4d2 100644 --- a/Minecraft.World/BiomeSource.cpp +++ b/Minecraft.World/BiomeSource.cpp @@ -15,11 +15,11 @@ void BiomeSource::_init() generatorOptions = L""; cache = new BiomeCache(this); + playerSpawnBiomes.push_back(Biome::plains); playerSpawnBiomes.push_back(Biome::forest); playerSpawnBiomes.push_back(Biome::taiga); - playerSpawnBiomes.push_back(Biome::plains); - playerSpawnBiomes.push_back(Biome::taigaHills); playerSpawnBiomes.push_back(Biome::forestHills); + playerSpawnBiomes.push_back(Biome::taigaHills); playerSpawnBiomes.push_back(Biome::jungle); playerSpawnBiomes.push_back(Biome::jungleHills); } diff --git a/Minecraft.World/Layer.cpp b/Minecraft.World/Layer.cpp index d4e1e81d..8998cb4b 100644 --- a/Minecraft.World/Layer.cpp +++ b/Minecraft.World/Layer.cpp @@ -198,4 +198,10 @@ void Layer::init(int64_t seed) this->seed += seedMixup; this->seed *= this->seed * 6364136223846793005LL + 1442695040888963407LL; this->seed += seedMixup; +} +bool Layer::isOcean(int biomeId) +{ + return biomeId == Biome::ocean->id || + biomeId == Biome::deepOcean->id || + biomeId == Biome::frozenOcean->id; } \ No newline at end of file diff --git a/Minecraft.World/Layer.h b/Minecraft.World/Layer.h index f3b90a1d..71a1aba0 100644 --- a/Minecraft.World/Layer.h +++ b/Minecraft.World/Layer.h @@ -26,6 +26,7 @@ public: Layer(int64_t seedMixup); virtual void init(int64_t seed); + bool isOcean(int biomeId); virtual void initRandom(int64_t x, int64_t y); protected: diff --git a/Minecraft.World/MesaBiome.cpp b/Minecraft.World/MesaBiome.cpp index 8d06d5d5..0572053e 100644 --- a/Minecraft.World/MesaBiome.cpp +++ b/Minecraft.World/MesaBiome.cpp @@ -75,7 +75,7 @@ void MesaBiome::initBands(int64_t /*seed*/) {} int MesaBiome::getBandColor(int x, int y, int z) { if (!clayBandsOffsetNoise) - return BAND_ORANGE; + return BAND_HARDENED_CLAY; double noiseX = static_cast(x) / 512.0; int offset = static_cast(std::round( @@ -179,7 +179,7 @@ void MesaBiome::buildSurfaceAtDefault(Level* level, Random* random, for (int y = Level::genDepthMinusOne; y >= 0; --y) { - int index = (localX * 16 + localZ) * Level::genDepth + y; + int index = (localZ * 16 + localX) * Level::genDepth + y; if (y <= 1 + random->nextInt(2)) @@ -293,4 +293,4 @@ void MesaBiome::buildSurfaceAtDefault(Level* level, Random* random, } } } -} \ No newline at end of file +} diff --git a/Minecraft.World/MesaBiome.h b/Minecraft.World/MesaBiome.h index ded41fed..991904ba 100644 --- a/Minecraft.World/MesaBiome.h +++ b/Minecraft.World/MesaBiome.h @@ -2,13 +2,15 @@ #include "Biome.h" #include "PerlinNoise.h" #include "Random.h" +#include "Level.h" +#include "Feature.h" #include class MesaBiome : public Biome { public: - static constexpr int BAND_HARDENED_CLAY = 255; + 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; @@ -16,47 +18,32 @@ public: 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; - + 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); + int getBandColor(int x, int y, int z); - - bool isMesaPlateau; - bool hasTrees; + bool isMesaPlateau; + bool hasTrees; - - int64_t lastSeed; + int64_t lastSeed; - - byte clayBands[64]; + byte clayBands[64]; - PerlinNoise* clayBandsOffsetNoise; - - - PerlinNoise* pillarNoise; - PerlinNoise* pillarRoofNoise; + PerlinNoise* pillarNoise; + PerlinNoise* pillarRoofNoise; }; \ No newline at end of file