From 54958075bb3c9ab166e9b3fef9a867c073c598f2 Mon Sep 17 00:00:00 2001 From: Lord_Cambion Date: Tue, 14 Apr 2026 13:07:02 +0200 Subject: [PATCH 1/7] worldgenerationissues --- Minecraft.World/BiomeInitLayer.cpp | 264 ++++++++++++++--------------- Minecraft.World/BiomeInitLayer.h | 27 ++- Minecraft.World/BiomeSource.cpp | 4 +- Minecraft.World/Layer.cpp | 6 + Minecraft.World/Layer.h | 1 + Minecraft.World/MesaBiome.cpp | 6 +- Minecraft.World/MesaBiome.h | 39 ++--- 7 files changed, 162 insertions(+), 185 deletions(-) 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 From f17f5a98e589f51fd2ae7fcc5ebae7351c97a984 Mon Sep 17 00:00:00 2001 From: Lord_Cambion Date: Tue, 14 Apr 2026 21:04:09 +0200 Subject: [PATCH 2/7] some changes --- Minecraft.World/Biome.cpp | 53 +++++--- Minecraft.World/Biome.h | 2 +- Minecraft.World/BiomeInitLayer.cpp | 2 +- Minecraft.World/ExtremeHillsBiome.cpp | 141 ++++++++++++--------- Minecraft.World/ExtremeHillsBiome.h | 31 +++-- Minecraft.World/MutatedBiome.cpp | 9 +- Minecraft.World/OceanBiome.h | 4 + Minecraft.World/SuperflatConfig.h | 8 ++ Minecraft.World/cmake/sources/Common.cmake | 1 + 9 files changed, 155 insertions(+), 96 deletions(-) create mode 100644 Minecraft.World/SuperflatConfig.h diff --git a/Minecraft.World/Biome.cpp b/Minecraft.World/Biome.cpp index 7adbfcae..3c0e4b2c 100644 --- a/Minecraft.World/Biome.cpp +++ b/Minecraft.World/Biome.cpp @@ -12,7 +12,7 @@ #include "PerlinNoise.h" -Biome *Biome::biomes[256]; +Biome *Biome::biomes[257]; Biome *Biome::ocean = nullptr;//0 Biome *Biome::plains = nullptr;//1 @@ -120,6 +120,8 @@ void Biome::staticCtor() 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::extremeHills_plus = (new ExtremeHillsBiome(34, true))->setColor(0x507050)->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::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); @@ -128,12 +130,13 @@ void Biome::staticCtor() 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::extremeHillsM = static_cast(Biome::biomes[3])->createMutatedBiome(131); 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::extremeHills_plusM = static_cast(Biome::biomes[34])->createMutatedBiome(162); 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); @@ -382,28 +385,31 @@ float Biome::getTemperature(int x, int y, int z) void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal) { byte topState = this->topMaterial; + byte topStateData = this->topMaterialData; byte fillerState = this->material; - + byte fillerStateData = this->materialData; + int runDepth = -1; 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 = Level::genDepthMinusOne; y >= 0; --y) + + const int SEA_LEVEL = 63; + + for (int y = 127; y >= 0; --y) { - int index = (localZ * 16 + localX) * Level::genDepth + y; - if (y <= 1 + random->nextInt(2)) + if (y <= 1 + random->nextInt(2)) { - chunkBlocks[index] = static_cast(Tile::unbreakable_Id); + chunkBlocks[index] = static_cast(Tile::unbreakable_Id); continue; } byte currentBlockId = chunkBlocks[index]; - if (currentBlockId == 0) + if (currentBlockId == 0) { runDepth = -1; } @@ -413,34 +419,41 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock { if (noiseDepth <= 0) { - topState = 0; + topState = 0; + topStateData = 0; fillerState = static_cast(Tile::stone_Id); + fillerStateData = 0; } - else if (y >= seaLevel - 4 && y <= seaLevel + 1) + else if (y < 6) { topState = this->topMaterial; + topStateData = this->topMaterialData; fillerState = this->material; + fillerStateData = this->materialData; } - if (y < seaLevel && topState == 0) + if (y < SEA_LEVEL && topState == 0) { - if (this->getTemperature(x, y, z) < 0.15f) { + if (this->getTemperature(x, y, z) < 0.15f) topState = static_cast(Tile::ice_Id); - } else { - topState = static_cast(Tile::calmWater_Id); - } + else + topState = static_cast(Tile::calmWater_Id); + topStateData = 0; } runDepth = noiseDepth; - if (y >= seaLevel - 1) + if (y >= SEA_LEVEL - 1) { chunkBlocks[index] = topState; + } - else if (y < seaLevel - 7 - noiseDepth) + else if (y < SEA_LEVEL - 7 - noiseDepth) { topState = 0; + topStateData = 0; fillerState = static_cast(Tile::stone_Id); + fillerStateData = 0; chunkBlocks[index] = static_cast(Tile::gravel_Id); } else @@ -455,8 +468,10 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock if (runDepth == 0 && fillerState == static_cast(Tile::sand_Id)) { - runDepth = random->nextInt(4) + (y - 63 > 0 ? y - 63 : 0); + runDepth = random->nextInt(4) + (y > 0 ? y : 0); + fillerState = static_cast(Tile::sandStone_Id); + fillerStateData = 0; } } } diff --git a/Minecraft.World/Biome.h b/Minecraft.World/Biome.h index 63269e89..ed6e766f 100644 --- a/Minecraft.World/Biome.h +++ b/Minecraft.World/Biome.h @@ -27,7 +27,7 @@ class Biome public: static void staticCtor(); - static Biome *biomes[256]; + static Biome *biomes[257]; static Biome *ocean; static Biome *plains; diff --git a/Minecraft.World/BiomeInitLayer.cpp b/Minecraft.World/BiomeInitLayer.cpp index bdba2915..8616725f 100644 --- a/Minecraft.World/BiomeInitLayer.cpp +++ b/Minecraft.World/BiomeInitLayer.cpp @@ -60,7 +60,7 @@ BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptr parent, int64_t s icyBiomes[3] = Biome::coldTaiga; - if (levelType != LevelType::lvl_normal_1_1 && levelType == LevelType::lvl_flat) + if (levelType != LevelType::lvl_normal_1_1 && levelType == LevelType::lvl_customized) { this->customSettings = (CustomizableSourceSettings*)superflatConfig; } diff --git a/Minecraft.World/ExtremeHillsBiome.cpp b/Minecraft.World/ExtremeHillsBiome.cpp index d5c05244..2e517ad2 100644 --- a/Minecraft.World/ExtremeHillsBiome.cpp +++ b/Minecraft.World/ExtremeHillsBiome.cpp @@ -1,85 +1,98 @@ + #include "stdafx.h" #include "net.minecraft.world.level.h" #include "net.minecraft.world.level.tile.h" #include "net.minecraft.world.level.levelgen.feature.h" #include "ExtremeHillsBiome.h" #include "BiomeDecorator.h" - #include "SpruceFeature.h" #include "TreeFeature.h" +ExtremeHillsBiome::ExtremeHillsBiome(int id) : ExtremeHillsBiome(id, false) +{ +} + ExtremeHillsBiome::ExtremeHillsBiome(int id, bool extraTrees) : Biome(id) { - silverfishFeature = new OreFeature(Tile::monsterStoneEgg_Id, 8); - taigaFeature = new SpruceFeature(false); - friendlies.clear(); - type = 0; - if (extraTrees) - { - decorator->treeCount = 3; - type = 1; - } + + silverfishFeature = new OreFeature(Tile::monsterStoneEgg_Id, 9); + + taigaFeature = new SpruceFeature(false); + + friendlies.clear(); + type = TYPE_NORMAL; + + if (extraTrees) + { + decorator->treeCount = 3; + type = TYPE_TREES; + } } ExtremeHillsBiome::~ExtremeHillsBiome() { - delete silverfishFeature; - delete taigaFeature; + delete silverfishFeature; + delete taigaFeature; } -Feature *ExtremeHillsBiome::getTreeFeature(Random *random) +Feature* ExtremeHillsBiome::getTreeFeature(Random* random) { - if (random->nextInt(3) > 0) - { - return new SpruceFeature(false); - } - return Biome::getTreeFeature(random); + + if (random->nextInt(3) > 0) + { + return new SpruceFeature(false); + } + return Biome::getTreeFeature(random); } -void ExtremeHillsBiome::decorate(Level *level, Random *random, int xo, int zo) { - Biome::decorate(level, random, xo, zo); - - if (GENERATE_EMERALD_ORE) - { - int emeraldCount = 3 + random->nextInt(6); - for (int d = 0; d < emeraldCount; d++) - { - int x = xo + random->nextInt(16); - int y = random->nextInt((Level::genDepth / 4) - 4) + 4; - int z = zo + random->nextInt(16); - int tile = level->getTile(x, y, z); - if (tile == Tile::stone_Id) - { - level->setTileAndData(x, y, z, Tile::emeraldOre_Id, 0, Tile::UPDATE_CLIENTS); - } - } - } - - for (int i = 0; i < 7; i++) - { - int x = xo + random->nextInt(16); - int y = random->nextInt(64); - int z = zo + random->nextInt(16); - silverfishFeature->place(level, random, x, y, z); - } -} - -void ExtremeHillsBiome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal) +void ExtremeHillsBiome::decorate(Level* level, Random* random, int xo, int zo) { - topMaterial = static_cast(Tile::grass_Id); - material = static_cast(Tile::dirt_Id); + Biome::decorate(level, random, xo, zo); - if ((noiseVal < -1.0 || noiseVal > 2.0) && type == 2) + if (GENERATE_EMERALD_ORE) + { + int emeraldCount = 3 + random->nextInt(6); + for (int d = 0; d < emeraldCount; d++) + { + int x = xo + random->nextInt(16); + + int y = random->nextInt(28) + 4; + int z = zo + random->nextInt(16); + int tile = level->getTile(x, y, z); + if (tile == Tile::stone_Id) + { + level->setTileAndData(x, y, z, Tile::emeraldOre_Id, 0, Tile::UPDATE_CLIENTS); + } + } + } + + for (int i = 0; i < 7; i++) + { + int x = xo + random->nextInt(16); + int y = random->nextInt(64); + int z = zo + random->nextInt(16); + silverfishFeature->place(level, random, x, y, z); + } +} + +void ExtremeHillsBiome::buildSurfaceAtDefault(Level* level, Random* random, byte* chunkBlocks, int x, int z, double noiseVal) +{ + topMaterial = static_cast(Tile::grass_Id); + topMaterialData = 0; + material = static_cast(Tile::dirt_Id); + materialData = 0; + + if ((noiseVal < -1.0 || noiseVal > 2.0) && type == TYPE_MUTATED) { topMaterial = static_cast(Tile::gravel_Id); - material = static_cast(Tile::gravel_Id); + material = static_cast(Tile::gravel_Id); } - else if (noiseVal > 1.0 && type != 1) + else if (noiseVal > 1.0 && type != TYPE_TREES) { - topMaterial = static_cast(Tile::stone_Id); + topMaterial = static_cast(Tile::stone_Id); topMaterialData = 0; - material = static_cast(Tile::stone_Id); - materialData = 0; + material = static_cast(Tile::stone_Id); + materialData = 0; } Biome::buildSurfaceAtDefault(level, random, chunkBlocks, x, z, noiseVal); @@ -87,10 +100,16 @@ void ExtremeHillsBiome::buildSurfaceAtDefault(Level *level, Random *random, byte Biome* ExtremeHillsBiome::mutateHills(Biome* baseBiome) { - this->type = 2; // Mutated type - this->setColor(baseBiome->color, true); - this->setName(baseBiome->m_name + L" M"); - this->setDepthAndScale(baseBiome->depth, baseBiome->scale); - this->setTemperatureAndDownfall(baseBiome->temperature, baseBiome->downfall); - return this; + this->type = TYPE_MUTATED; + this->setColor(baseBiome->color, true); + this->setName(baseBiome->m_name + L" M"); + this->setDepthAndScale(baseBiome->depth, baseBiome->scale); + this->setTemperatureAndDownfall(baseBiome->temperature, baseBiome->downfall); + return this; } + + +Biome* ExtremeHillsBiome::createMutatedBiome(int id) +{ + return (new ExtremeHillsBiome(id, false))->mutateHills(this); +} \ No newline at end of file diff --git a/Minecraft.World/ExtremeHillsBiome.h b/Minecraft.World/ExtremeHillsBiome.h index 3fd57d12..cec0ef15 100644 --- a/Minecraft.World/ExtremeHillsBiome.h +++ b/Minecraft.World/ExtremeHillsBiome.h @@ -1,23 +1,32 @@ -#pragma once +#pragma once #include "Biome.h" +#include "OreFeature.h" +#include "SpruceFeature.h" class ExtremeHillsBiome : public Biome { - friend class Biome; private: - static const bool GENERATE_EMERALD_ORE = true; + static const bool GENERATE_EMERALD_ORE = true; Feature *silverfishFeature; int type; Feature *taigaFeature; -protected: - ExtremeHillsBiome(int id, bool extraTrees = false); - ~ExtremeHillsBiome(); - + static constexpr int TYPE_NORMAL = 0; + static constexpr int TYPE_TREES = 1; + static constexpr int TYPE_MUTATED = 2; public: - virtual void decorate(Level *level, Random *random, int xo, int zo) override; - virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal) override; - virtual Feature *getTreeFeature(Random *random) override; - Biome* mutateHills(Biome* baseBiome); + + ExtremeHillsBiome(int id); + + ExtremeHillsBiome(int id, bool extraTrees); + ~ExtremeHillsBiome(); + + Feature* getTreeFeature(Random* random) override; + void decorate(Level* level, Random* random, int xo, int zo) override; + void buildSurfaceAtDefault(Level* level, Random* random, byte* chunkBlocks, int x, int z, double noiseVal) override; + Biome* mutateHills(Biome* baseBiome); + Biome* createMutatedBiome(int id); + + }; \ No newline at end of file diff --git a/Minecraft.World/MutatedBiome.cpp b/Minecraft.World/MutatedBiome.cpp index e98f821d..455e52f0 100644 --- a/Minecraft.World/MutatedBiome.cpp +++ b/Minecraft.World/MutatedBiome.cpp @@ -20,7 +20,8 @@ MutatedBiome::MutatedBiome(int id, Biome* baseBiome) scale = baseBiome->scale + 0.2f; temperature = baseBiome->temperature; downfall = baseBiome->downfall; - + _hasRain = baseBiome->_hasRain; + snowCovered = baseBiome->snowCovered; friendlies = baseBiome->friendlies; enemies = baseBiome->enemies; @@ -32,15 +33,17 @@ MutatedBiome::MutatedBiome(int id, Biome* baseBiome) m_waterColor = baseBiome->m_waterColor; m_skyColor = baseBiome->m_skyColor; + m_grassColor = baseBiome->m_grassColor; + m_foliageColor = baseBiome->m_foliageColor; m_name = baseBiome->m_name + L" Mutated"; - // Copia parametri del decorator + if (decorator && baseBiome->decorator) { decorator->treeCount = baseBiome->decorator->treeCount; decorator->grassCount = baseBiome->decorator->grassCount; decorator->flowerCount = baseBiome->decorator->flowerCount; decorator->hugeMushrooms = baseBiome->decorator->hugeMushrooms; - // ... altri campi se necessari + } } diff --git a/Minecraft.World/OceanBiome.h b/Minecraft.World/OceanBiome.h index 2f27b6f9..7f590d8c 100644 --- a/Minecraft.World/OceanBiome.h +++ b/Minecraft.World/OceanBiome.h @@ -13,4 +13,8 @@ public: topMaterial = Tile::gravel_Id; // surfaceblock material = Tile::gravel_Id; } + int OceanBiome::getTemperatureCategory() const override +{ + return 0; +} }; diff --git a/Minecraft.World/SuperflatConfig.h b/Minecraft.World/SuperflatConfig.h new file mode 100644 index 00000000..3a0c2029 --- /dev/null +++ b/Minecraft.World/SuperflatConfig.h @@ -0,0 +1,8 @@ +#pragma once + +#include "ByteArrayTag.h" + +class SuperflatConfig { +public: + ByteArrayTag* toTag(); +}; \ No newline at end of file diff --git a/Minecraft.World/cmake/sources/Common.cmake b/Minecraft.World/cmake/sources/Common.cmake index 8e58801c..99f4a115 100644 --- a/Minecraft.World/cmake/sources/Common.cmake +++ b/Minecraft.World/cmake/sources/Common.cmake @@ -1451,6 +1451,7 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_LEVELGEN "${CMAKE_CURRENT_SOURCE_DIR}/TheEndLevelRandomLevelSource.h" "${CMAKE_CURRENT_SOURCE_DIR}/TownFeature.h" "${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.level.levelgen.h" + "${CMAKE_CURRENT_SOURCE_DIR}/SuperflatConfig.h" ) source_group("net/minecraft/world/level/levelgen" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_LEVELGEN}) From d6e1a4ce75968b5ce092520702751a6ecf3a2915 Mon Sep 17 00:00:00 2001 From: Lord_Cambion Date: Tue, 21 Apr 2026 18:48:04 +0200 Subject: [PATCH 3/7] fix: mistakes i did when i was decompiling it. --- Minecraft.World/RemoveTooMuchOceanLayer.cpp | 57 ++++++++++----------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/Minecraft.World/RemoveTooMuchOceanLayer.cpp b/Minecraft.World/RemoveTooMuchOceanLayer.cpp index 3bfd5ae4..5500ee17 100644 --- a/Minecraft.World/RemoveTooMuchOceanLayer.cpp +++ b/Minecraft.World/RemoveTooMuchOceanLayer.cpp @@ -5,40 +5,39 @@ RemoveTooMuchOceanLayer::RemoveTooMuchOceanLayer(int64_t seed, shared_ptr parent, int64_t seedMixup) : Layer(seedMixup) { - this->parent = parent; + 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); + 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)); + for (int i1 = 0; i1 < h; ++i1) + { + for (int j1 = 0; j1 < w; ++j1) + { + int k1 = aint[(j1 + 1) + (i1) * k]; + int l1 = aint[(j1 + 2) + (i1 + 1) * k]; + int i2 = aint[(j1) + (i1 + 1) * k]; + int j2 = aint[(j1 + 1) + (i1 + 2) * k]; + int k2 = aint[(j1 + 1) + (i1 + 1) * k]; - if (k2 == 0 && k1 == 0 && l1 == 0 && i2 == 0 && j2 == 0) - { - if (this->nextRandom(2) == 0) - { - aint1[j1 + i1 * w] = 1; - } - } - } - } + this->initRandom((int64_t)(j1 + xo), (int64_t)(i1 + yo)); + aint1[j1 + i1 * w] = k2; - return aint1; + if (k2 == 0 && k1 == 0 && l1 == 0 && i2 == 0 && j2 == 0) + { + if (this->nextRandom(2) == 0) + { + aint1[j1 + i1 * w] = 1; + } + } + } + } + return aint1; } \ No newline at end of file From 4303b4966a33dc9624229ed1960f16b6d6843e92 Mon Sep 17 00:00:00 2001 From: Lord_Cambion Date: Wed, 22 Apr 2026 12:26:18 +0200 Subject: [PATCH 4/7] fix: biome generation biomes like extreme hills now have correct blocks sky and water, also correct grass. another thing is that now in the world spawns mutated biomes and it is acceptable as a world generation. i dont thjink it is the same because seeds are not giving me the ones from youtube videos but we will work on it later. For now it works and it is acceptable. spawns a variety of biomes that before was spawned in a random way, now depending on next biomes and temperature --- Minecraft.World/AddIslandLayer.cpp | 8 +- Minecraft.World/AddSnowLayer.cpp | 5 +- Minecraft.World/Biome.cpp | 59 +++-- Minecraft.World/Biome.h | 4 +- Minecraft.World/BiomeInitLayer.cpp | 28 ++- Minecraft.World/DeepOceanLayer.cpp | 3 +- Minecraft.World/ExtremeHillsBiome.cpp | 1 + Minecraft.World/Layer.cpp | 330 ++++++++++++++----------- Minecraft.World/Layer.h | 5 +- Minecraft.World/Level.cpp | 22 +- Minecraft.World/Level.h | 2 +- Minecraft.World/RareBiomeLayer.cpp | 33 ++- Minecraft.World/RareBiomeSpotLayer.cpp | 21 +- Minecraft.World/RegionHillsLayer.cpp | 22 +- Minecraft.World/RiverMixerLayer.cpp | 12 +- Minecraft.World/SavannaBiome.cpp | 105 ++++---- Minecraft.World/SavannaBiome.h | 23 +- 17 files changed, 421 insertions(+), 262 deletions(-) diff --git a/Minecraft.World/AddIslandLayer.cpp b/Minecraft.World/AddIslandLayer.cpp index 5edee3c4..37e05822 100644 --- a/Minecraft.World/AddIslandLayer.cpp +++ b/Minecraft.World/AddIslandLayer.cpp @@ -14,7 +14,7 @@ intArray AddIslandLayer::getArea(int xo, int yo, int w, int h) int pw = w + 2; int ph = h + 2; intArray p = parent->getArea(px, py, pw, ph); - + PIXBeginNamedEvent(0.0, "AddIslandLayer::getArea"); intArray result = IntCache::allocate(w * h); for (int y = 0; y < h; y++) { @@ -40,7 +40,7 @@ intArray AddIslandLayer::getArea(int xo, int yo, int w, int h) } else { - if (swap == Biome::iceFlats->id) result[x + y * w] = Biome::frozenOcean->id; + if (swap == 4) result[x + y * w] = Biome::frozenOcean->id; else result[x + y * w] = 0; } } @@ -48,7 +48,7 @@ intArray AddIslandLayer::getArea(int xo, int yo, int w, int h) { if (nextRandom(5) == 0) { - if (c == Biome::iceFlats->id) result[x + y * w] = Biome::frozenOcean->id; + if (c == 4) result[x + y * w] = Biome::frozenOcean->id; else result[x + y * w] = 0; } else result[x + y * w] = c; @@ -59,6 +59,6 @@ intArray AddIslandLayer::getArea(int xo, int yo, int w, int h) } } } - + PIXEndNamedEvent(); return result; } \ No newline at end of file diff --git a/Minecraft.World/AddSnowLayer.cpp b/Minecraft.World/AddSnowLayer.cpp index 252dbd50..6b41b8ae 100644 --- a/Minecraft.World/AddSnowLayer.cpp +++ b/Minecraft.World/AddSnowLayer.cpp @@ -28,8 +28,9 @@ intArray AddSnowLayer::getArea(int xo, int yo, int w, int h) } else { - int r = nextRandom(5); - if (r == 0) r = Biome::iceFlats->id; + int r = nextRandom(6); + if (r == 0) r = 4; + else if (r <= 1) r = 3; else r = 1; result[x + y * w] = r; } diff --git a/Minecraft.World/Biome.cpp b/Minecraft.World/Biome.cpp index 3c0e4b2c..1d036950 100644 --- a/Minecraft.World/Biome.cpp +++ b/Minecraft.World/Biome.cpp @@ -130,13 +130,21 @@ void Biome::staticCtor() 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::extremeHillsM = static_cast(Biome::biomes[3])->createMutatedBiome(131); + Biome::extremeHillsM = static_cast(Biome::biomes[3])->createMutatedBiome(131)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills, eMinecraftColour_Foliage_ExtremeHills, eMinecraftColour_Water_ExtremeHills,eMinecraftColour_Sky_ExtremeHills); 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::desertM = (new DesertBiome(130))->setColor(0xFA9418)->setName(L"Desert M")->setNoRain()->setTemperatureAndDownfall(2, 0)->setDepthAndScale(0.225f, 0.25f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Desert, eMinecraftColour_Foliage_Desert, eMinecraftColour_Water_Desert,eMinecraftColour_Sky_Desert); + Biome::taigaM = (new TaigaBiome(133))->setColor(0x0b6659)->setName(L"Taiga M")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.25f, 0.8f)->setDepthAndScale(0.3f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga); + Biome::swamplandM = (new SwampBiome(134))->setColor(0x07F9B2)->setName(L"Swampland M")->setLeafColor(0x8BAF48)->setDepthAndScale(-0.1f, 0.3f)->setTemperatureAndDownfall(0.8f, 0.9f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Swampland, eMinecraftColour_Foliage_Swampland, eMinecraftColour_Water_Swampland,eMinecraftColour_Sky_Swampland); 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::jungleM = (new JungleBiome(149, false))->setColor(0x537b09)->setName(L"Jungle M")->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::jungleEdgeM = (new JungleBiome(151, true))->setColor(0x6458135)->setName(L"Jungle Edge M")->setLeafColor(0x5470985)->setTemperatureAndDownfall(0.95F, 0.8F); 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::extremeHills_plusM = static_cast(Biome::biomes[34])->createMutatedBiome(162); + Biome::coldTaigaM = (new TaigaBiome(158))->setColor(0x0b6659)->setName(L"Cold Taiga M")->setLeafColor(0x4EBA31)->setSnowCovered()->setTemperatureAndDownfall(-0.5f, 0.4f)->setDepthAndScale(0.3f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga); + Biome::redwoodTaiga = (new TaigaBiome(160, 1))->setColor(0x0b6659)->setName(L"Mega Spruce Taiga")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.3f, 0.8f)->setDepthAndScale(0.2f, 0.2f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga); + Biome::redwoodTaigaHills = (new TaigaBiome(161, 2))->setColor(0x0b6659)->setName(L"Mega Spruce Taiga Hills")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.3f, 0.8f)->setDepthAndScale(0.2f, 0.2f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga); + Biome::extremeHills_plusM = static_cast(Biome::biomes[34])->createMutatedBiome(162)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills,eMinecraftColour_Foliage_ExtremeHills,eMinecraftColour_Water_ExtremeHills, eMinecraftColour_Sky_ExtremeHills); 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); @@ -384,18 +392,17 @@ float Biome::getTemperature(int x, int y, int z) void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal) { - byte topState = this->topMaterial; + byte topState = this->topMaterial; byte topStateData = this->topMaterialData; - byte fillerState = this->material; + byte fillerState = this->material; byte fillerStateData = this->materialData; - int runDepth = -1; + int runDepth = -1; int noiseDepth = (int)(noiseVal / 3.0 + 3.0 + random->nextDouble() * 0.25); int localX = x & 15; int localZ = z & 15; - - const int SEA_LEVEL = 63; + const int SEA_LEVEL = 63; for (int y = 127; y >= 0; --y) { @@ -409,26 +416,26 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock byte currentBlockId = chunkBlocks[index]; - if (currentBlockId == 0) + if (currentBlockId == 0) { runDepth = -1; } else if (currentBlockId == static_cast(Tile::stone_Id)) { - if (runDepth == -1) + if (runDepth == -1) { if (noiseDepth <= 0) { - topState = 0; + topState = 0; topStateData = 0; - fillerState = static_cast(Tile::stone_Id); + fillerState = static_cast(Tile::stone_Id); fillerStateData = 0; } - else if (y < 6) + else if (y >= SEA_LEVEL - 7 - noiseDepth && y < SEA_LEVEL - 1) { - topState = this->topMaterial; + topState = this->topMaterial; topStateData = this->topMaterialData; - fillerState = this->material; + fillerState = this->material; fillerStateData = this->materialData; } @@ -446,17 +453,16 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock if (y >= SEA_LEVEL - 1) { chunkBlocks[index] = topState; - } - else if (y < SEA_LEVEL - 7 - noiseDepth) + else if (y < SEA_LEVEL - 7 - noiseDepth) { - topState = 0; + topState = 0; topStateData = 0; - fillerState = static_cast(Tile::stone_Id); + fillerState = static_cast(Tile::stone_Id); fillerStateData = 0; chunkBlocks[index] = static_cast(Tile::gravel_Id); } - else + else { chunkBlocks[index] = fillerState; } @@ -468,10 +474,17 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock if (runDepth == 0 && fillerState == static_cast(Tile::sand_Id)) { - runDepth = random->nextInt(4) + (y > 0 ? y : 0); - - fillerState = static_cast(Tile::sandStone_Id); - fillerStateData = 0; + runDepth = random->nextInt(4); + if (fillerStateData == 1) + { + fillerState = static_cast(Tile::red_sandstone_Id); + fillerStateData = 0; + } + else + { + fillerState = static_cast(Tile::sandStone_Id); + fillerStateData = 0; + } } } } diff --git a/Minecraft.World/Biome.h b/Minecraft.World/Biome.h index ed6e766f..f33792cd 100644 --- a/Minecraft.World/Biome.h +++ b/Minecraft.World/Biome.h @@ -227,6 +227,6 @@ public: virtual int getGrassColor() const; virtual Feature *getFlowerFeature(Random *random, int x, int y, int z); virtual int getRandomDoublePlantType(Random *random); - Biome* getBiome(uint32_t id); - Biome* getBiome(uint32_t id, Biome* fallback); + static Biome* getBiome(uint32_t id); + static Biome* getBiome(uint32_t id, Biome* fallback); }; \ No newline at end of file diff --git a/Minecraft.World/BiomeInitLayer.cpp b/Minecraft.World/BiomeInitLayer.cpp index 8616725f..c9389419 100644 --- a/Minecraft.World/BiomeInitLayer.cpp +++ b/Minecraft.World/BiomeInitLayer.cpp @@ -1,4 +1,4 @@ -#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" @@ -90,66 +90,80 @@ intArray BiomeInitLayer::getArea(int xo, int yo, int w, int h) { initRandom(x + xo, y + yo); - int val = b[x + y * w]; - int v18 = (val >> 8) & 0xF; - int v19 = val & 0xFFFFF0FF; + 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; } + if (isOcean(v19) || v19 == Biome::mushroomIsland->id) { result[x + y * w] = v19; continue; } + if (v19 == 1) { if (v18 <= 0) { + result[x + y * w] = desertBiomes[nextRandom(desertBiomes.length)]->id; } - else if (nextRandom(3)) + else if (nextRandom(3) != 0) { result[x + y * w] = Biome::mesaPlateauF->id; } else { - result[x + y * w] = Biome::plains->id; + result[x + y * w] = Biome::mesaPlateau->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; + + result[x + y * w] = v19; } } } diff --git a/Minecraft.World/DeepOceanLayer.cpp b/Minecraft.World/DeepOceanLayer.cpp index 6e9ded7b..782baf27 100644 --- a/Minecraft.World/DeepOceanLayer.cpp +++ b/Minecraft.World/DeepOceanLayer.cpp @@ -15,6 +15,7 @@ intArray DeepOceanLayer::getArea(int xo, int yo, int w, int h) int k = w + 2; int l = h + 2; intArray aint = this->parent->getArea(i, j, k, l); + PIXBeginNamedEvent(0.0, "AddDeepOceanLayer::getArea"); intArray aint1 = IntCache::allocate(w * h); for (int i1 = 0; i1 < h; ++i1) @@ -58,6 +59,6 @@ intArray DeepOceanLayer::getArea(int xo, int yo, int w, int h) } } } - + PIXEndNamedEvent(); return aint1; } diff --git a/Minecraft.World/ExtremeHillsBiome.cpp b/Minecraft.World/ExtremeHillsBiome.cpp index 2e517ad2..87be6845 100644 --- a/Minecraft.World/ExtremeHillsBiome.cpp +++ b/Minecraft.World/ExtremeHillsBiome.cpp @@ -105,6 +105,7 @@ Biome* ExtremeHillsBiome::mutateHills(Biome* baseBiome) this->setName(baseBiome->m_name + L" M"); this->setDepthAndScale(baseBiome->depth, baseBiome->scale); this->setTemperatureAndDownfall(baseBiome->temperature, baseBiome->downfall); + this->setWaterSkyColor(baseBiome->getWaterColor(), baseBiome->getSkyColor()); return this; } diff --git a/Minecraft.World/Layer.cpp b/Minecraft.World/Layer.cpp index 8998cb4b..52010d59 100644 --- a/Minecraft.World/Layer.cpp +++ b/Minecraft.World/Layer.cpp @@ -1,207 +1,249 @@ - #include "stdafx.h" - #include "net.minecraft.world.level.newbiome.layer.h" - #include "RiverInitLayer.h" - #include "RareBiomeSpotLayer.h" - #include "net.minecraft.world.level.h" - #include "BiomeOverrideLayer.h" - #include "CustomizableSourceSettings.h" +#include "stdafx.h" +#include "net.minecraft.world.level.newbiome.layer.h" +#include "RiverInitLayer.h" +#include "RareBiomeSpotLayer.h" +#include "net.minecraft.world.level.h" +#include "BiomeOverrideLayer.h" +#include "CustomizableSourceSettings.h" - #ifdef __PSVITA__ - // AP - this is used to perform fast 64bit divides of known values - #include "../Minecraft.Client/PSVita/PSVitaExtras/libdivide.h" +#ifdef __PSVITA__ +#include "../Minecraft.Client/PSVita/PSVitaExtras/libdivide.h" #include +libdivide::divider fast_d2(2); +libdivide::divider fast_d3(3); +libdivide::divider fast_d4(4); +libdivide::divider fast_d5(5); +libdivide::divider fast_d6(6); +libdivide::divider fast_d7(7); +libdivide::divider fast_d10(10); +#endif - libdivide::divider fast_d2(2); - libdivide::divider fast_d3(3); - libdivide::divider fast_d4(4); - libdivide::divider fast_d5(5); - libdivide::divider fast_d6(6); - libdivide::divider fast_d7(7); - libdivide::divider fast_d10(10); - #endif - -LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* superflatConfig) { - - +LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* superflatConfig) +{ shared_ptr islandLayer = std::make_shared(seed, 1); islandLayer = std::make_shared(seed, islandLayer, 0x7D0); islandLayer = std::make_shared(seed, islandLayer, 1); - islandLayer = std::make_shared(seed, islandLayer, 0x7D1); + islandLayer = std::make_shared(seed, islandLayer, 0x7D1); islandLayer = std::make_shared(seed, islandLayer, 2); - islandLayer = std::make_shared(seed, islandLayer, 0x32); - islandLayer = std::make_shared(seed, islandLayer, 0x46); + islandLayer = std::make_shared(seed, islandLayer, 0x32); + islandLayer = std::make_shared(seed, islandLayer, 0x46); islandLayer = std::make_shared(seed, islandLayer, 2); islandLayer = std::make_shared(seed, islandLayer, 2); islandLayer = std::make_shared(seed, islandLayer, 3); - islandLayer = std::make_shared(seed, islandLayer, 2, 0); - islandLayer = std::make_shared(seed, islandLayer, 2, 1); + islandLayer = std::make_shared(seed, islandLayer, 2, 0); + islandLayer = std::make_shared(seed, islandLayer, 2, 1); islandLayer = std::make_shared(seed, islandLayer, 3, 2); - islandLayer = std::make_shared(seed, islandLayer, 0x7D2); - islandLayer = std::make_shared(seed, islandLayer, 0x7D3); + islandLayer = std::make_shared(seed, islandLayer, 0x7D2); + islandLayer = std::make_shared(seed, islandLayer, 0x7D3); islandLayer = std::make_shared(seed, islandLayer, 4); - islandLayer = std::make_shared(seed, islandLayer, 5); + + + islandLayer = std::make_shared(seed, islandLayer, 4); - shared_ptr baseLayer = ZoomLayer::zoom(seed, islandLayer, 0x3E8, 0); + shared_ptr baseLayer = ZoomLayer::zoom(seed, islandLayer, 0x3E8, 0); + int zoomLevel = 4; int riverZoomCount = 4; - - if (levelType == LevelType::lvl_customized && superflatConfig != nullptr) { + + if (levelType == LevelType::lvl_customized && superflatConfig != nullptr) + { auto settings = CustomizableSourceSettings::Builder::build( CustomizableSourceSettings::Builder::fromString(superflatConfig)); + zoomLevel = settings->getBiomeSize(); riverZoomCount = settings->getRiverSize(); - } - - if (levelType == LevelType::lvl_largeBiomes) { - zoomLevel = 6; + } - - shared_ptr riverInit = make_shared(seed, baseLayer, 0x64); - - - shared_ptr hillsNoise = ZoomLayer::zoom(seed, riverInit, 0x3E8, 2); - - + if (levelType == LevelType::lvl_largeBiomes) + zoomLevel = 6; + + + shared_ptr riverInit = make_shared(seed, baseLayer, 0x64); + + shared_ptr hillsNoise = ZoomLayer::zoom(seed, riverInit, 0x3E8, 2); + shared_ptr riverLayerFinal = ZoomLayer::zoom(seed, riverInit, 0x3E8, 2); riverLayerFinal = ZoomLayer::zoom(seed, riverLayerFinal, 0x3E8, riverZoomCount); - riverLayerFinal = make_shared(seed, riverLayerFinal, 1); riverLayerFinal = make_shared(seed, riverLayerFinal, 0x3E8); - - - shared_ptr biomeLayer = make_shared(seed, baseLayer, 0xC8, levelType, superflatConfig); + + shared_ptr biomeLayer = make_shared(seed, baseLayer, 0xC8, levelType, superflatConfig); biomeLayer = ZoomLayer::zoom(seed, biomeLayer, 0x3E8, 2); biomeLayer = make_shared(seed, biomeLayer, 0x3E8); biomeLayer = make_shared(seed, biomeLayer, hillsNoise, 0x3E8); - biomeLayer = make_shared(seed, biomeLayer, 0x3E9); + biomeLayer = make_shared(seed, biomeLayer, 0x3E9); - - for (int i = 0; i < zoomLevel; ++i) { + for (int i = 0; i < zoomLevel; ++i) + { biomeLayer = make_shared(seed, biomeLayer, 0x3E8 + i); - - if (i == 0) { + + if (i == 0) + { biomeLayer = make_shared(seed, biomeLayer, 3); + biomeLayer = make_shared(seed, biomeLayer, 5); } - - if (i == 1 || zoomLevel == 1) { + + + if (zoomLevel == 1||i == 1) + { + biomeLayer = make_shared(seed, biomeLayer, 5); biomeLayer = make_shared(seed, biomeLayer, 0x3E8); } } biomeLayer = make_shared(seed, biomeLayer, 0x3E8); - - shared_ptr mixed = make_shared(seed, biomeLayer, riverLayerFinal, 0x64); - shared_ptr voronoi = make_shared(seed, mixed, 0xA); + shared_ptr mixed = make_shared(seed, biomeLayer, riverLayerFinal, 0x64); + shared_ptr voronoi = make_shared(seed, mixed, 0xA); mixed->init(seed); voronoi->init(seed); LayerArray result(3, false); - result[0] = mixed; - result[1] = voronoi; - result[2] = mixed; + result[0] = mixed; + result[1] = voronoi; + result[2] = mixed; return result; } - Layer::Layer(int64_t seedMixup) - { - parent = nullptr; +Layer::Layer(int64_t seedMixup) +{ + parent = nullptr; - this->seedMixup = seedMixup; - this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l; - this->seedMixup += seedMixup; - this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l; - this->seedMixup += seedMixup; - this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l; - this->seedMixup += seedMixup; - } + this->seedMixup = seedMixup; + this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l; + this->seedMixup += seedMixup; + this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l; + this->seedMixup += seedMixup; + this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l; + this->seedMixup += seedMixup; +} +void Layer::initRandom(int64_t x, int64_t y) +{ + rval = seed; + rval *= rval * 6364136223846793005L + 1442695040888963407L; + rval += x; + rval *= rval * 6364136223846793005L + 1442695040888963407L; + rval += y; + rval *= rval * 6364136223846793005L + 1442695040888963407L; + rval += x; + rval *= rval * 6364136223846793005L + 1442695040888963407L; + rval += y; +} +int Layer::nextRandom(int max) +{ +#ifdef __PSVITA__ + int result; + long long temp = rval; + temp >>= 24; + if (max == 2) + result = temp - (temp / fast_d2) * 2; + else if (max == 3) + result = temp - (temp / fast_d3) * 3; + else if (max == 4) + result = temp - (temp / fast_d4) * 4; + else if (max == 5) + result = temp - (temp / fast_d5) * 5; + else if (max == 6) + result = temp - (temp / fast_d6) * 6; + else if (max == 7) + result = temp - (temp / fast_d7) * 7; + else if (max == 10) + result = temp - (temp / fast_d10) * 10; + else + result = temp - (temp / max) * max; +#else + int result = static_cast((rval >> 24) % max); +#endif + if (result < 0) result += max; + rval *= rval * 6364136223846793005L + 1442695040888963407L; + rval += seed; + return result; +} - void Layer::initRandom(int64_t x, int64_t y) - { - rval = seed; - rval *= rval * 6364136223846793005l + 1442695040888963407l; - rval += x; - rval *= rval * 6364136223846793005l + 1442695040888963407l; - rval += y; - rval *= rval * 6364136223846793005l + 1442695040888963407l; - rval += x; - rval *= rval * 6364136223846793005l + 1442695040888963407l; - rval += y; - } - - int Layer::nextRandom(int max) - { - #ifdef __PSVITA__ - // AP - 64bit mods are very slow on Vita. Replaced with a divide/mult for general case and a fast divide library for specific numbers - // todo - this can sometimes yield a different number to the original. There's a strange bug sometimes with Vita where if the line - // "result = (int) ((rval >> 24) % max);" is done twice in a row 'result' will not be the same. Need to speak to Sony about that - // Also need to compare level against a different platform using the same seed - int result; - long long temp = rval; - temp >>= 24; - if( max == 2 ) - { - result = temp-(temp/fast_d2)*2; - } - else if( max == 3 ) - { - result = temp-(temp/fast_d3)*3; - } - else if( max == 4 ) - { - result = temp-(temp/fast_d4)*4; - } - else if( max == 5 ) - { - result = temp-(temp/fast_d5)*5; - } - else if( max == 6 ) - { - result = temp-(temp/fast_d6)*6; - } - else if( max == 7 ) - { - result = temp-(temp/fast_d7)*7; - } - else if( max == 10 ) - { - result = temp-(temp/fast_d10)*10; - } - else - { - result = temp-(temp/max)*max; - } - #else - - int result = static_cast((rval >> 24) % max); - #endif - - if (result < 0) result += max; - rval *= rval * 6364136223846793005l + 1442695040888963407l; - rval += seed; - return result; - } - -void Layer::init(int64_t seed) +void Layer::init(int64_t seed) { this->seed = seed; if (parent != nullptr) parent->init(seed); - this->seed *= this->seed * 6364136223846793005LL + 1442695040888963407LL; + this->seed *= this->seed * 6364136223846793005L + 1442695040888963407L; this->seed += seedMixup; - this->seed *= this->seed * 6364136223846793005LL + 1442695040888963407LL; + this->seed *= this->seed * 6364136223846793005L + 1442695040888963407L; this->seed += seedMixup; - this->seed *= this->seed * 6364136223846793005LL + 1442695040888963407LL; + this->seed *= this->seed * 6364136223846793005L + 1442695040888963407L; this->seed += seedMixup; } + bool Layer::isOcean(int biomeId) { - return biomeId == Biome::ocean->id || - biomeId == Biome::deepOcean->id || + return biomeId == Biome::ocean->id || + biomeId == Biome::deepOcean->id || biomeId == Biome::frozenOcean->id; +} + + +bool Layer::isSame(int biomeIdA, int biomeIdB) { + if (biomeIdA == biomeIdB) { + return true; + } else { + Biome* biome = Biome::getBiome(biomeIdA); + Biome* biome2 = Biome::getBiome(biomeIdB); + if (biome != nullptr && biome2 != nullptr) { + if (biome != Biome::mesaPlateauF && biome != Biome::mesaPlateau) { + return biome == biome2 || biome->getBaseBiomeId() == biome2->getBaseBiomeId(); + } else { + return biome2 == Biome::mesaPlateauF || biome2 == Biome::mesaPlateau; + } + } else { + return false; + } + } +} + + +int Layer::random(int i, int j, int k, int l) { + int random = nextRandom(4); + + int ret = (random != 2 ? i : k); + if (random == 3) + ret = l; + if (random == 1) + ret = j; + return ret; +} + +int Layer::random(int i, int j) { + if (nextRandom(2)) { + return j; + } + + return i; +} + +int Layer::modeOrRandom(int i, int j, int k, int l) { + if (j == k && k == l) { + return j; + } else if (i == j && i == k) { + return i; + } else if (i == j && i == l) { + return i; + } else if (i == k && i == l) { + return i; + } else if (i == j && k != l) { + return i; + } else if (i == k && j != l) { + return i; + } else if (i == l && j != k) { + return i; + } else if (j == k && i != l) { + return j; + } else if (j == l && i != k) { + return j; + } else { + return k == l && i != j ? k : random(i, j, k, l); + } } \ No newline at end of file diff --git a/Minecraft.World/Layer.h b/Minecraft.World/Layer.h index 71a1aba0..cfc3cf28 100644 --- a/Minecraft.World/Layer.h +++ b/Minecraft.World/Layer.h @@ -27,11 +27,14 @@ public: virtual void init(int64_t seed); bool isOcean(int biomeId); + bool isSame(int biomeIdA, int biomeIdB); virtual void initRandom(int64_t x, int64_t y); protected: int nextRandom(int max); - + int random(int i, int j, int k, int l); + int random(int i, int j); + int modeOrRandom(int i, int j, int k, int l); public: virtual intArray getArea(int xo, int yo, int w, int h) = 0; }; \ No newline at end of file diff --git a/Minecraft.World/Level.cpp b/Minecraft.World/Level.cpp index 19126b24..730362e2 100644 --- a/Minecraft.World/Level.cpp +++ b/Minecraft.World/Level.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "System.h" #include "BasicTypeContainers.h" #include "File.h" @@ -4798,4 +4798,24 @@ bool Level::canCreateMore(eINSTANCEOF type, ESPAWN_TYPE spawnType) } // 4J: Interpret 0 as no limit return max == 0 || count < max; +} + + +BlockPos Level::getHeightmapPos(int x, int z) +{ + + if (x < -MAX_LEVEL_SIZE || z < -MAX_LEVEL_SIZE || + x >= MAX_LEVEL_SIZE || z >= MAX_LEVEL_SIZE) + { + return BlockPos(x, 64, z); + } + + if (hasChunk(x >> 4, z >> 4)) + { + LevelChunk* lc = getChunk(x >> 4, z >> 4); + int y = lc->getHeightmap(x & 0xF, z & 0xF); + return BlockPos(x, y, z); + } + + return BlockPos(x, 0, z); } \ No newline at end of file diff --git a/Minecraft.World/Level.h b/Minecraft.World/Level.h index 0d96a297..4a6686fd 100644 --- a/Minecraft.World/Level.h +++ b/Minecraft.World/Level.h @@ -209,7 +209,7 @@ public: bool reallyHasChunkAt(int x, int y, int z); // 4J added bool reallyHasChunksAt(int x, int y, int z, int r); // 4J added bool reallyHasChunksAt(int x0, int y0, int z0, int x1, int y1, int z1); // 4J added - + BlockPos getHeightmapPos(int x, int z); public: bool hasChunk(int x, int z); bool reallyHasChunk(int x, int z ); // 4J added diff --git a/Minecraft.World/RareBiomeLayer.cpp b/Minecraft.World/RareBiomeLayer.cpp index f7499d5b..2efdb10d 100644 --- a/Minecraft.World/RareBiomeLayer.cpp +++ b/Minecraft.World/RareBiomeLayer.cpp @@ -22,14 +22,29 @@ intArray RareBiomeLayer::getArea(int xo, int yo, int w, int h) if (this->nextRandom(57) == 0) { - if (k == Biome::plains->id) - { - aint1[j + i * w] = Biome::plains->id + 128; - } - else - { - aint1[j + i * w] = k; - } + int mutated = k; + if (k == Biome::plains->id) mutated = Biome::sunflowersPlains->id; // 1 -> 129 + else if (k == Biome::desert->id) mutated = Biome::desertM->id; // 2 -> 130 + else if (k == Biome::extremeHills->id) mutated = Biome::extremeHillsM->id; // 3 -> 131 + else if (k == Biome::forest->id) mutated = Biome::flowerForest->id; // 4 -> 132 + else if (k == Biome::taiga->id) mutated = Biome::taigaM->id; // 5 -> 133 + else if (k == Biome::swampland->id) mutated = Biome::swamplandM->id; // 6 -> 134 + else if (k == Biome::iceFlats->id) mutated = Biome::iceSpikes->id; // 12 -> 140 + else if (k == Biome::jungle->id) mutated = Biome::jungleM->id; // 21 -> 149 + else if (k == Biome::jungleEdge->id) mutated = Biome::jungleEdgeM->id; // 23 -> 151 + else if (k == Biome::birchForest->id) mutated = Biome::birchForestM->id; // 27 -> 155 + else if (k == Biome::birchForestHills->id) mutated = Biome::birchForestHillsM->id; // 28 -> 156 + else if (k == Biome::roofedForest->id) mutated = Biome::roofedForestM->id; // 29 -> 157 + else if (k == Biome::coldTaiga->id) mutated = Biome::coldTaigaM->id; // 30 -> 158 + else if (k == Biome::megaTaiga->id) mutated = Biome::redwoodTaiga->id; // 32 -> 160 + else if (k == Biome::megaTaigaHills->id) mutated = Biome::redwoodTaigaHills->id; // 33 -> 161 + else if (k == Biome::extremeHills_plus->id) mutated = Biome::extremeHills_plusM->id; // 34 -> 162 + else if (k == Biome::savanna->id) mutated = Biome::savannaM->id; // 35 -> 163 + else if (k == Biome::savannaPlateau->id) mutated = Biome::savannaPlateauM->id; // 36 -> 164 + else if (k == Biome::mesa->id) mutated = Biome::mesaBryce->id; // 37 -> 165 + else if (k == Biome::mesaPlateauF->id) mutated = Biome::mesaPlateauFM->id; // 38 -> 166 + else if (k == Biome::mesaPlateau->id) mutated = Biome::mesaPlateauM->id; // 39 -> 167 + aint1[j + i * w] = mutated; } else { @@ -39,4 +54,4 @@ intArray RareBiomeLayer::getArea(int xo, int yo, int w, int h) } return aint1; -} +} \ No newline at end of file diff --git a/Minecraft.World/RareBiomeSpotLayer.cpp b/Minecraft.World/RareBiomeSpotLayer.cpp index 57885546..fbbc0113 100644 --- a/Minecraft.World/RareBiomeSpotLayer.cpp +++ b/Minecraft.World/RareBiomeSpotLayer.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "RareBiomeSpotLayer.h" #include "IntCache.h" +#include "net.minecraft.world.level.biome.h" RareBiomeSpotLayer::RareBiomeSpotLayer(int64_t seed, std::shared_ptr parent, int64_t seedMixup) : Layer(seedMixup) { @@ -9,6 +10,22 @@ RareBiomeSpotLayer::RareBiomeSpotLayer(int64_t seed, std::shared_ptr pare intArray RareBiomeSpotLayer::getArea(int xo, int yo, int w, int h) { - - return parent->getArea(xo, yo, w, h); + intArray b = parent->getArea(xo, yo, 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 biomeId = b[x + y * w]; + + if (nextRandom(57) == 0 && biomeId == Biome::plains->id) + result[x + y * w] = biomeId + 128; + else + result[x + y * w] = biomeId; + } + } + + return result; } diff --git a/Minecraft.World/RegionHillsLayer.cpp b/Minecraft.World/RegionHillsLayer.cpp index bc7e2498..81b3a49e 100644 --- a/Minecraft.World/RegionHillsLayer.cpp +++ b/Minecraft.World/RegionHillsLayer.cpp @@ -55,8 +55,14 @@ intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h) if (riverNoise != nullptr && k != 0 && l >= 2 && (l - 2) % 29 == 1 && k < 128) { - - result[x + y * w] = k; + if (Biome::biomes[k + 128] != nullptr) + { + result[x + y * w] = k + 128; + } + else + { + result[x + y * w] = k; + } } else if (nextRandom(3) != 0 && !flag) { @@ -135,6 +141,18 @@ intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h) + if (flag && i1 != k) + { + if (Biome::biomes[i1 + 128] != nullptr) + { + i1 += 128; + } + else + { + i1 = k; + } + } + if (i1 == k) { result[x + y * w] = k; diff --git a/Minecraft.World/RiverMixerLayer.cpp b/Minecraft.World/RiverMixerLayer.cpp index e27894a3..a6dda05c 100644 --- a/Minecraft.World/RiverMixerLayer.cpp +++ b/Minecraft.World/RiverMixerLayer.cpp @@ -23,18 +23,20 @@ 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 || b[i] == Biome::deepOcean->id) + if (b[i] == Biome::ocean->id || b[i] == Biome::deepOcean->id || b[i] == Biome::frozenOcean->id) { result[i] = b[i]; - } else { if (r[i] >= 0) { - if (b[i] == Biome::iceFlats->id) result[i] = Biome::frozenRiver->id; - else if (b[i] == Biome::mushroomIsland->id || b[i] == Biome::mushroomIslandShore->id) result[i] = Biome::mushroomIsland->id; // 4J - don't make mushroom island shores as we don't have any island left once we do this as our islands are small (this used to change to mushroomIslandShore) - else result[i] = r[i]; + if (b[i] == Biome::iceFlats->id || b[i] == Biome::iceSpikes->id || b[i] == Biome::coldTaiga->id || b[i] == Biome::coldTaigaHills->id) + result[i] = Biome::frozenRiver->id; + else if (b[i] == Biome::mushroomIsland->id || b[i] == Biome::mushroomIslandShore->id) + result[i] = Biome::mushroomIsland->id; // 4J - don't make mushroom island shores as we don't have any island left once we do this as our islands are small (this used to change to mushroomIslandShore) + else + result[i] = r[i]; } else { diff --git a/Minecraft.World/SavannaBiome.cpp b/Minecraft.World/SavannaBiome.cpp index 422388c8..37122a41 100644 --- a/Minecraft.World/SavannaBiome.cpp +++ b/Minecraft.World/SavannaBiome.cpp @@ -1,61 +1,55 @@ -#include "stdafx.h" +#include "stdafx.h" #include "net.minecraft.world.level.levelgen.feature.h" #include "net.minecraft.world.level.biome.h" #include "net.minecraft.world.entity.animal.h" #include "net.minecraft.world.entity.h" #include "SavannaBiome.h" -#include "SavannaTreeFeature.h" +#include "SavannaTreeFeature.h" #include "DoublePlantFeature.h" #include "TallGrass2.h" #include "Level.h" #include "Random.h" + SavannaBiome::SavannaBiome(int id) : Biome(id) { - friendlies.push_back(new MobSpawnerData(eTYPE_HORSE, 1, 2, 6)); - - decorator->treeCount = 1; + decorator->treeCount = 1; decorator->flowerCount = 4; - decorator->grassCount = 20; - + decorator->grassCount = 20; } -Feature *SavannaBiome::getTreeFeature(Random *random) +Feature* SavannaBiome::getTreeFeature(Random* random) { - - if (random->nextInt(5) > 0) + if (random->nextInt(5) <= 0) { - return new SavannaTreeFeature(false); + return new TreeFeature(false); } - - - return new TreeFeature(false); + return new SavannaTreeFeature(false); } int SavannaBiome::getGrassColor() const { - return 0xBFB755; + return 0xBFB755; } int SavannaBiome::getFolageColor() const { - return 0xAEA42A; + return 0xAEA42A; } -Feature *SavannaBiome::getFlowerFeature(Random *random, int x, int y, int z) +Feature* SavannaBiome::getFlowerFeature(Random* random, int x, int y, int z) { - - return nullptr; + return nullptr; } -int SavannaBiome::getRandomDoublePlantType(Random *random) +int SavannaBiome::getRandomDoublePlantType(Random* random) { - return 0; + return 0; } -void SavannaBiome::decorate(Level *level, Random *random, int xo, int zo) +void SavannaBiome::decorate(Level* level, Random* random, int xo, int zo) { DOUBLE_PLANT_GENERATOR->setPlantType(TallGrass2::TALL_GRASS); @@ -63,51 +57,68 @@ void SavannaBiome::decorate(Level *level, Random *random, int xo, int zo) { int x = xo + random->nextInt(16) + 8; int z = zo + random->nextInt(16) + 8; - int y = random->nextInt(level->getHeightmap(x, z) + 32); + int surfaceY = level->getHeightmapPos(x, z).getY(); + int y = random->nextInt(surfaceY + 32); DOUBLE_PLANT_GENERATOR->place(level, random, x, y, z); } Biome::decorate(level, random, xo, zo); } -MutatedSavannaBiome::MutatedSavannaBiome(int id, Biome* baseBiome) : MutatedBiome(id, baseBiome) +Biome* SavannaBiome::createMutatedCopy(int newId) { - decorator->treeCount = 2; - decorator->flowerCount = 2; - decorator->grassCount = 5; + MutatedSavannaBiome* mutated = new MutatedSavannaBiome(newId, this); + + + mutated->scale = (this->scale + 1.0f) * 0.5f; + mutated->depth = (this->depth * 0.5f) + 0.3f; + mutated->temperature = (this->temperature * 0.5f) + 1.2f; + + return mutated; } -void MutatedSavannaBiome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal) + +MutatedSavannaBiome::MutatedSavannaBiome(int id, Biome* baseBiome) + : MutatedBiome(id, baseBiome) { - topMaterial = static_cast(Tile::grass_Id); - material = static_cast(Tile::dirt_Id); + decorator->treeCount = 2; + decorator->flowerCount = 2; + decorator->grassCount = 5; +} + +void MutatedSavannaBiome::buildSurfaceAtDefault(Level* level, Random* random, + byte* chunkBlocks, + int x, int z, double noiseVal) +{ + + topMaterial = static_cast(Tile::grass_Id); + topMaterialData = 0; + material = static_cast(Tile::dirt_Id); + materialData = 0; if (noiseVal > 1.75) { - topMaterial = static_cast(Tile::stone_Id); + + topMaterial = static_cast(Tile::stone_Id); topMaterialData = 0; - material = static_cast(Tile::stone_Id); - materialData = 0; + material = static_cast(Tile::stone_Id); + materialData = 0; } else if (noiseVal > -0.5) { - topMaterial = static_cast(Tile::dirt_Id); - topMaterialData = 0; - material = static_cast(Tile::dirt_Id); - materialData = 0; - } - else - { - topMaterial = static_cast(Tile::grass_Id); - topMaterialData = 0; - material = static_cast(Tile::dirt_Id); - materialData = 0; + + topMaterial = static_cast(Tile::dirt_Id); + topMaterialData = 1; + material = static_cast(Tile::dirt_Id); + materialData = 0; } + Biome::buildSurfaceAtDefault(level, random, chunkBlocks, x, z, noiseVal); } -void MutatedSavannaBiome::decorate(Level *level, Random *random, int xo, int zo) +void MutatedSavannaBiome::decorate(Level* level, Random* random, int xo, int zo) { - MutatedBiome::decorate(level, random, xo, zo); -} + + decorator->decorate(level, random, xo, zo); +} \ No newline at end of file diff --git a/Minecraft.World/SavannaBiome.h b/Minecraft.World/SavannaBiome.h index 9aea9d0f..66c21310 100644 --- a/Minecraft.World/SavannaBiome.h +++ b/Minecraft.World/SavannaBiome.h @@ -1,3 +1,4 @@ + #pragma once #include "Biome.h" #include "MutatedBiome.h" @@ -6,21 +7,21 @@ class SavannaBiome : public Biome { public: SavannaBiome(int id); - - virtual Feature *getTreeFeature(Random *random); - 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; - virtual int getRandomDoublePlantType(Random *random) override; - virtual void decorate(Level *level, Random *random, int xo, int zo) override; + virtual Feature* getTreeFeature(Random* random) override; + virtual int getFolageColor() const override; + virtual int getGrassColor() const override; + virtual Feature* getFlowerFeature(Random* random, int x, int y, int z) override; + virtual int getRandomDoublePlantType(Random* random) override; + virtual void decorate(Level* level, Random* random, int xo, int zo) override; + virtual Biome* createMutatedCopy(int newId); }; class MutatedSavannaBiome : public MutatedBiome { public: MutatedSavannaBiome(int id, Biome* baseBiome); - - virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal) override; - virtual void decorate(Level *level, Random *random, int xo, int zo) override; + virtual void buildSurfaceAtDefault(Level* level, Random* random, + byte* chunkBlocks, int x, int z, + double noiseVal) override; + virtual void decorate(Level* level, Random* random, int xo, int zo) override; }; \ No newline at end of file From a9bf54ff8f39ef59a89fe957325bb3e04d4e45da Mon Sep 17 00:00:00 2001 From: Lord_Cambion Date: Fri, 24 Apr 2026 00:54:09 +0200 Subject: [PATCH 5/7] fix: mesa bryce now mesa bryce is implemented using decomp from ida 7 --- Minecraft.World/Biome.cpp | 2 +- Minecraft.World/MesaBiome.cpp | 477 +++++++++++++++---------- Minecraft.World/MesaBiome.h | 71 ++-- Minecraft.World/PerlinSimplexNoise.cpp | 2 +- 4 files changed, 334 insertions(+), 218 deletions(-) diff --git a/Minecraft.World/Biome.cpp b/Minecraft.World/Biome.cpp index 1d036950..ef58797a 100644 --- a/Minecraft.World/Biome.cpp +++ b/Minecraft.World/Biome.cpp @@ -148,7 +148,7 @@ void Biome::staticCtor() 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::mesaBryce = (new MesaBiome(165, true, 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); diff --git a/Minecraft.World/MesaBiome.cpp b/Minecraft.World/MesaBiome.cpp index 0572053e..1970db75 100644 --- a/Minecraft.World/MesaBiome.cpp +++ b/Minecraft.World/MesaBiome.cpp @@ -1,26 +1,23 @@ -#include "stdafx.h" - +#include "stdafx.h" #define _USE_MATH_DEFINES #include #include - #include "MesaBiome.h" -#include "BiomeDecorator.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 "PerlinSimplexNoise.h" #include "Random.h" - +#include "TreeFeature.h" #undef max #undef min - MesaBiome::MesaBiome(int id, bool mesaPlateau, bool hasTrees) : Biome(id) { this->isMesaPlateau = mesaPlateau; @@ -29,31 +26,22 @@ MesaBiome::MesaBiome(int id, bool mesaPlateau, bool hasTrees) : Biome(id) 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->topMaterialData = static_cast(SandTile::RED_SAND); this->material = static_cast(Tile::clayHardened_colored_Id); - this->materialData = static_cast(BAND_ORANGE); // 1 + this->materialData = static_cast(orangeColoredClayState); this->lastSeed = INVALID_SEED; + this->clayBands = nullptr; 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->treeCount = hasTrees ? 5 : -999; decorator->deadBushCount = 20; - decorator->reedsCount = 3; + decorator->reedsCount = 3; decorator->cactusCount = 5; decorator->flowerCount = 0; } @@ -61,31 +49,135 @@ MesaBiome::MesaBiome(int id, bool mesaPlateau, bool hasTrees) : Biome(id) MesaBiome::~MesaBiome() { + delete[] clayBands; + clayBands = nullptr; + delete pillarNoise; + pillarNoise = nullptr; delete pillarRoofNoise; + pillarRoofNoise = nullptr; delete clayBandsOffsetNoise; + clayBandsOffsetNoise = nullptr; } - -void MesaBiome::initBands(int64_t /*seed*/) {} - - - - -int MesaBiome::getBandColor(int x, int y, int z) +void MesaBiome::generateBands(int64_t seed) { - if (!clayBandsOffsetNoise) - return BAND_HARDENED_CLAY; - double noiseX = static_cast(x) / 512.0; - int offset = static_cast(std::round( - clayBandsOffsetNoise->getValue(noiseX, noiseX) * 2.0)); + delete[] clayBands; + clayBands = new BandEntry[BAND_COUNT]; - int index = ((y + offset) % 64 + 64) % 64; - return static_cast(static_cast(clayBands[index])); + for (int i = 0; i < BAND_COUNT; ++i) + { + clayBands[i].blockId = Tile::clayHardened_Id; + clayBands[i].blockData = defaultHardenedClayState; + } + + Random r(seed); + + + delete clayBandsOffsetNoise; + clayBandsOffsetNoise = new PerlinSimplexNoise(&r, 1); + + { + int i = 0; + while (i < BAND_COUNT) + { + i += r.nextInt(5) + 1; + if (i < BAND_COUNT) + { + clayBands[i].blockId = Tile::clayHardened_colored_Id; + clayBands[i].blockData = orangeColoredClayState; + } + } + } + + { + int groupCount = r.nextInt(4) + 2; + for (int g = 0; g < groupCount; ++g) + { + int len = r.nextInt(3) + 1; + int start = r.nextInt(BAND_COUNT); + for (int k = 0; start + k < BAND_COUNT && k < len; ++k) + { + clayBands[start + k].blockId = Tile::clayHardened_colored_Id; + clayBands[start + k].blockData = yellowColoredClayState; + } + } + } + + { + int groupCount = r.nextInt(4) + 2; + for (int g = 0; g < groupCount; ++g) + { + int len = r.nextInt(3) + 2; + int start = r.nextInt(BAND_COUNT); + for (int k = 0; start + k < BAND_COUNT && k < len; ++k) + { + clayBands[start + k].blockId = Tile::clayHardened_colored_Id; + clayBands[start + k].blockData = brownColoredClayState; + } + } + } + + { + int groupCount = r.nextInt(4) + 2; + for (int g = 0; g < groupCount; ++g) + { + int len = r.nextInt(3) + 1; + int start = r.nextInt(BAND_COUNT); + for (int k = 0; start + k < BAND_COUNT && k < len; ++k) + { + clayBands[start + k].blockId = Tile::clayHardened_colored_Id; + clayBands[start + k].blockData = redColoredClayState; + } + } + } + + { + int stripeCount = r.nextInt(3) + 3; + int cursor = 0; + for (int g = 0; g < stripeCount; ++g) + { + cursor += r.nextInt(16) + 4; + if (cursor >= BAND_COUNT) break; + + clayBands[cursor].blockId = Tile::clayHardened_colored_Id; + clayBands[cursor].blockData = whiteColoredClayState; + + + if (cursor > 1 && r.nextBoolean()) + { + clayBands[cursor - 1].blockId = Tile::clayHardened_colored_Id; + clayBands[cursor - 1].blockData = silverColoredClayState; + } + + if (cursor < 63 && r.nextBoolean()) + { + clayBands[cursor + 1].blockId = Tile::clayHardened_colored_Id; + clayBands[cursor + 1].blockData = silverColoredClayState; + } + } + } } +BandEntry MesaBiome::getBand(int x, int y, int z) +{ + if (!clayBandsOffsetNoise || !clayBands) + return { Tile::clayHardened_Id, 0 }; + + + double noiseVal = clayBandsOffsetNoise->getValue( + static_cast(x) * 0.001953125, + static_cast(x) * 0.001953125); + + + int offset = static_cast(std::round(noiseVal + noiseVal)); + + + int index = ((y + offset) + BAND_COUNT) % BAND_COUNT; + return clayBands[index]; +} void MesaBiome::decorate(Level* level, Random* random, int xo, int zo) { @@ -94,203 +186,214 @@ void MesaBiome::decorate(Level* level, Random* random, int xo, int zo) Feature* MesaBiome::getTreeFeature(Random* random) { - return Biome::getTreeFeature(random); + return new TreeFeature(false); } +int MesaBiome::getFolageColor() const +{ + return eMinecraftColour_Foliage_Mesa; +} +int MesaBiome::getGrassColor() const +{ + return eMinecraftColour_Grass_Mesa; +} 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) + + if (!clayBands || lastSeed != seed) + generateBands(seed); + + if (!pillarNoise || !pillarRoofNoise || 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); - } - } - + Random noiseRand(seed); + delete pillarNoise; + delete pillarRoofNoise; - 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 - } + pillarNoise = new PerlinSimplexNoise(&noiseRand, 4); + pillarRoofNoise = new PerlinSimplexNoise(&noiseRand, 1); } - - const int seaLevel = level->seaLevel; - const int localX = x & 15; - const int localZ = z & 15; + lastSeed = seed; - - int noiseDepth = (int)(noiseVal / 3.0 + 3.0 + random->nextDouble() * 0.25); - bool flag = (cos(noiseVal / 3.0 * PI) > 0.0); + const int localX = x & 0xF; + const int localZ = z & 0xF; - int run = -1; - bool flag1 = false; + double pillarHeight = 0.0; - for (int y = Level::genDepthMinusOne; y >= 0; --y) + + if (isMesaPlateau) +{ + double nx = static_cast((x & ~0xF) + localZ); + double nz = static_cast((z & ~0xF) + localX); + + + double roofVal = pillarNoise->getValue(nx * 0.25, nz * 0.25); + double d0 = std::abs(noiseVal) - roofVal; + + + if (d0 > 0.0) { - int index = (localZ * 16 + localX) * Level::genDepth + y; + + double pillarScale = pillarRoofNoise->getValue( + nx * 0.001953125, + nz * 0.001953125); - if (y <= 1 + random->nextInt(2)) + double scaled = std::ceil(std::abs(pillarScale) * 50.0); + double height = d0 * d0 * 2.5; + double cap = scaled + 14.0; + if (height > cap) height = cap; + pillarHeight = height + 64.0; + } +} + + const int localX2 = x & 0xF; + const int localZ2 = z & 0xF; + const int seaLevel = level->getSeaLevel(); + + int noiseDepth = static_cast(noiseVal / 3.0 + 3.0 + random->nextDouble() * 0.25); + bool cosFlag = (std::cos(noiseVal / 3.0 * PI) > 0.0); + + int run = -1; + bool underRedSand = false; + + for (int y = 0x7F; y >= 0; --y) + { + int idx = (localZ2 * 16 + localX2) * 128 + y; + + + byte cur = chunkBlocks[idx]; + if (cur == 0 && pillarHeight > 0.0 && y < static_cast(pillarHeight)) { - chunkBlocks[index] = static_cast(Tile::unbreakable_Id); + chunkBlocks[idx] = static_cast(Tile::stone_Id); + cur = static_cast(Tile::stone_Id); + } + + + if (y <= random->nextInt(5)) + { + chunkBlocks[idx] = static_cast(Tile::unbreakable_Id); continue; } - byte cur = chunkBlocks[index]; + + cur = chunkBlocks[idx]; - if (cur == 0) + + if (cur == 0) { run = -1; + continue; } - else if (cur == static_cast(Tile::stone_Id)) + + + if (cur != static_cast(Tile::stone_Id)) + continue; + + if (run == -1) { - if (run == -1) + underRedSand = false; + run = noiseDepth + std::max(0, y - seaLevel); + + + if (y < seaLevel - 1) { - flag1 = false; - - - run = noiseDepth + (y > seaLevel ? (y - seaLevel) : 0); - - - if (y < seaLevel - 1) + if (noiseDepth <= 0) { - 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; + chunkBlocks[idx] = static_cast(Tile::stone_Id); } 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); + chunkBlocks[idx] = static_cast(Tile::clayHardened_colored_Id); + chunkData[idx] = static_cast(BAND_ORANGE); } } - else if (run > 0) + else if (hasTrees && y > 86 + noiseDepth * 2) { - --run; - - if (flag1) + + if (cosFlag) { - chunkBlocks[index] = static_cast(Tile::clayHardened_colored_Id); - chunkData[index] = static_cast(BAND_ORANGE); + chunkBlocks[idx] = static_cast(Tile::dirt_Id); + chunkData[idx] = static_cast(DirtTile::COARSE_DIRT); } else { - int band = getBandColor(x, y, z); - if (band == BAND_HARDENED_CLAY) - chunkBlocks[index] = static_cast(Tile::clayHardened_Id); + chunkBlocks[idx] = static_cast(Tile::grass_Id); + } + } + else if (y <= seaLevel + 3 + noiseDepth) + { + chunkBlocks[idx] = static_cast(Tile::sand_Id); + chunkData[idx] = static_cast(SandTile::RED_SAND); + underRedSand = true; + } + else + { + + if (y >= 64 && y <= 127) + { + if (cosFlag) + { + chunkBlocks[idx] = static_cast(Tile::clayHardened_Id); + } else { - chunkBlocks[index] = static_cast(Tile::clayHardened_colored_Id); - chunkData[index] = static_cast(band); + BandEntry band = getBand(x, y, z); + chunkBlocks[idx] = static_cast(band.blockId); + if (band.blockId == Tile::clayHardened_colored_Id) + chunkData[idx] = static_cast(band.blockData); } } + else + { + chunkBlocks[idx] = static_cast(Tile::clayHardened_colored_Id); + chunkData[idx] = static_cast(BAND_ORANGE); + } + } + + + if (y < seaLevel && chunkBlocks[idx] == 0) + chunkBlocks[idx] = static_cast(Tile::calmWater_Id); + } + else if (run > 0) + { + --run; + + if (underRedSand) + { + chunkBlocks[idx] = static_cast(Tile::clayHardened_colored_Id); + chunkData[idx] = static_cast(BAND_ORANGE); + } + else + { + BandEntry band = getBand(x, y, z); + chunkBlocks[idx] = static_cast(band.blockId); + if (band.blockId == Tile::clayHardened_colored_Id) + chunkData[idx] = static_cast(band.blockData); } } } } + +MesaBiome* MesaBiome::createMutatedCopy(int newId) +{ + + bool isMesaBase = (this->id == Biome::mesa->id); + + MesaBiome* copy = new MesaBiome(newId, isMesaBase, this->hasTrees); + + if (!isMesaBase) + { + + copy->setDepthAndScale(0.1f, 0.3f); + } + + copy->setWaterSkyColor(this->getWaterColor(), this->getSkyColor()); + + return copy; +} \ No newline at end of file diff --git a/Minecraft.World/MesaBiome.h b/Minecraft.World/MesaBiome.h index 991904ba..d0df393d 100644 --- a/Minecraft.World/MesaBiome.h +++ b/Minecraft.World/MesaBiome.h @@ -1,49 +1,62 @@ #pragma once #include "Biome.h" -#include "PerlinNoise.h" +#include "PerlinSimplexNoise.h" #include "Random.h" -#include "Level.h" -#include "Feature.h" +#include "Level.h" +#include "Feature.h" #include +struct BandEntry { + int blockId; + int blockData; +}; + 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_COUNT = 64; + + 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 int BAND_SILVER = 8; - static constexpr int64_t INVALID_SEED = -1LL; + static constexpr int defaultHardenedClayState = 0; + static constexpr int orangeColoredClayState = BAND_ORANGE; + static constexpr int yellowColoredClayState = BAND_YELLOW; + static constexpr int brownColoredClayState = BAND_BROWN; + static constexpr int redColoredClayState = BAND_RED; + static constexpr int whiteColoredClayState = BAND_WHITE; + static constexpr int silverColoredClayState = BAND_SILVER; - MesaBiome(int id, bool mesaPlateau, bool hasTrees); + static constexpr int64_t INVALID_SEED = 0LL; + + MesaBiome(int id, bool isMesaPlateau, 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 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 int getFolageColor() const override; + virtual int getGrassColor() const override; + + MesaBiome* createMutatedCopy(int newId); private: - - void initBands(int64_t seed); + void generateBands(int64_t seed); + BandEntry getBand(int x, int y, int z); - int getBandColor(int x, int y, int z); + bool isMesaPlateau; //0x104 + bool hasTrees; //0x105 - bool isMesaPlateau; - bool hasTrees; + int64_t lastSeed; //0xF0/0xF4 - int64_t lastSeed; - - byte clayBands[64]; - - PerlinNoise* clayBandsOffsetNoise; - PerlinNoise* pillarNoise; - PerlinNoise* pillarRoofNoise; + BandEntry* clayBands; //0xE8 + PerlinSimplexNoise* pillarNoise; //0xF8 + PerlinSimplexNoise* pillarRoofNoise; //0xFC + PerlinSimplexNoise* clayBandsOffsetNoise; //0x100 }; \ No newline at end of file diff --git a/Minecraft.World/PerlinSimplexNoise.cpp b/Minecraft.World/PerlinSimplexNoise.cpp index 97d11448..7f620cf5 100644 --- a/Minecraft.World/PerlinSimplexNoise.cpp +++ b/Minecraft.World/PerlinSimplexNoise.cpp @@ -10,7 +10,7 @@ PerlinSimplexNoise::PerlinSimplexNoise(int levels) PerlinSimplexNoise::PerlinSimplexNoise(Random *random, int levels) { init(random,levels); - delete random; + //delete random; } void PerlinSimplexNoise::init(Random *random, int levels) From 35500de3cc960f7645f8f7d3ac4736b83ba66348 Mon Sep 17 00:00:00 2001 From: Lord_Cambion Date: Fri, 24 Apr 2026 01:25:06 +0200 Subject: [PATCH 6/7] fix: mesa colors and plateau i tried to give the colors of the mesa eMinecraftColour_Foliage_Mesa eMinecraftColour_Grass_Mesa but it took the actuale value like 50 and 37 if i remmebr so it gave black and dark blue colors to leaves and grass. then i fixed the plateau becoming bryce just adding an id check --- Minecraft.World/MesaBiome.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Minecraft.World/MesaBiome.cpp b/Minecraft.World/MesaBiome.cpp index 1970db75..0aef5182 100644 --- a/Minecraft.World/MesaBiome.cpp +++ b/Minecraft.World/MesaBiome.cpp @@ -191,12 +191,12 @@ Feature* MesaBiome::getTreeFeature(Random* random) int MesaBiome::getFolageColor() const { - return eMinecraftColour_Foliage_Mesa; + return 0x9E814D; } int MesaBiome::getGrassColor() const { - return eMinecraftColour_Grass_Mesa; + return 0x90814D; } void MesaBiome::buildSurfaceAtDefault(Level* level, Random* random, @@ -226,7 +226,7 @@ void MesaBiome::buildSurfaceAtDefault(Level* level, Random* random, double pillarHeight = 0.0; - if (isMesaPlateau) + if (isMesaPlateau&& id == Biome::mesaBryce->id) { double nx = static_cast((x & ~0xF) + localZ); double nz = static_cast((z & ~0xF) + localX); @@ -390,7 +390,7 @@ MesaBiome* MesaBiome::createMutatedCopy(int newId) if (!isMesaBase) { - copy->setDepthAndScale(0.1f, 0.3f); + copy->setDepthAndScale(0.1f, 0.2f); } copy->setWaterSkyColor(this->getWaterColor(), this->getSkyColor()); From 41d4334e80318c689e69fa2e07aaa071f5efa9db Mon Sep 17 00:00:00 2001 From: Lord_Cambion Date: Sun, 26 Apr 2026 16:12:20 +0200 Subject: [PATCH 7/7] fix: savanna biome + savanna tree used compilation to change savanna biome generation and savanna tree teatures using abstractTreeFeature that was missing. --- Minecraft.World/AbstractTreeFeature.h | 33 ++++ Minecraft.World/Direction.h | 20 +- Minecraft.World/SavannaBiome.cpp | 22 +-- Minecraft.World/SavannaBiome.h | 7 +- Minecraft.World/SavannaTreeFeature.cpp | 244 ++++++++++++++++--------- Minecraft.World/SavannaTreeFeature.h | 26 +-- 6 files changed, 230 insertions(+), 122 deletions(-) create mode 100644 Minecraft.World/AbstractTreeFeature.h diff --git a/Minecraft.World/AbstractTreeFeature.h b/Minecraft.World/AbstractTreeFeature.h new file mode 100644 index 00000000..37703e55 --- /dev/null +++ b/Minecraft.World/AbstractTreeFeature.h @@ -0,0 +1,33 @@ +#pragma once +#include "Feature.h" +#include "Level.h" +#include "Tile.h" + +class AbstractTreeFeature : public Feature +{ +public: + AbstractTreeFeature(bool doUpdate) : Feature(doUpdate) {} + virtual ~AbstractTreeFeature() {} + + static bool isFree(Level* level, int x, int y, int z) + { + int tile = level->getTile(x, y, z); + return tile == 0 + || tile == Tile::leaves_Id + || tile == Tile::leaves2_Id + || tile == Tile::treeTrunk_Id + || tile == Tile::tree2Trunk_Id + || tile == Tile::vine_Id + || tile == Tile::tallgrass_Id + || tile == Tile::flower_Id; + } + + void setDirtAt(Level* level, int x, int y, int z) + { + if (level->getTile(x, y, z) != Tile::dirt_Id) + { + placeBlock(level, x, y, z, Tile::dirt_Id, 0); + } + } + virtual void postPlaceTree() {} +}; \ No newline at end of file diff --git a/Minecraft.World/Direction.h b/Minecraft.World/Direction.h index 587bb653..8b8b91bf 100644 --- a/Minecraft.World/Direction.h +++ b/Minecraft.World/Direction.h @@ -54,4 +54,22 @@ public: return 0; } -}; \ No newline at end of file + + class Plane + { + public: + + static int getRandomFace(Random* random) + { + + static const int horizontal[4] = { + Direction::SOUTH, + Direction::WEST, + Direction::NORTH, + Direction::EAST + }; + return horizontal[random->nextInt(4)]; + } + }; + +}; diff --git a/Minecraft.World/SavannaBiome.cpp b/Minecraft.World/SavannaBiome.cpp index 37122a41..3181b63d 100644 --- a/Minecraft.World/SavannaBiome.cpp +++ b/Minecraft.World/SavannaBiome.cpp @@ -22,11 +22,11 @@ SavannaBiome::SavannaBiome(int id) : Biome(id) Feature* SavannaBiome::getTreeFeature(Random* random) { - if (random->nextInt(5) <= 0) + if (random->nextInt(5) > 0) { - return new TreeFeature(false); + return new SavannaTreeFeature(false); } - return new SavannaTreeFeature(false); + return new TreeFeature(false); } int SavannaBiome::getGrassColor() const @@ -86,11 +86,11 @@ MutatedSavannaBiome::MutatedSavannaBiome(int id, Biome* baseBiome) decorator->grassCount = 5; } -void MutatedSavannaBiome::buildSurfaceAtDefault(Level* level, Random* random, - byte* chunkBlocks, - int x, int z, double noiseVal) +void MutatedSavannaBiome::buildSurfaceAt(Level* level, Random* random, + ChunkPrimer* primer, + int x, int z, double noiseVal) { - + topMaterial = static_cast(Tile::grass_Id); topMaterialData = 0; material = static_cast(Tile::dirt_Id); @@ -98,7 +98,7 @@ void MutatedSavannaBiome::buildSurfaceAtDefault(Level* level, Random* random, if (noiseVal > 1.75) { - + topMaterial = static_cast(Tile::stone_Id); topMaterialData = 0; material = static_cast(Tile::stone_Id); @@ -108,13 +108,13 @@ void MutatedSavannaBiome::buildSurfaceAtDefault(Level* level, Random* random, { topMaterial = static_cast(Tile::dirt_Id); - topMaterialData = 1; + topMaterialData = 1; material = static_cast(Tile::dirt_Id); materialData = 0; } - - Biome::buildSurfaceAtDefault(level, random, chunkBlocks, x, z, noiseVal); + + Biome::buildSurfaceAt(level, random, primer, x, z, noiseVal); } void MutatedSavannaBiome::decorate(Level* level, Random* random, int xo, int zo) diff --git a/Minecraft.World/SavannaBiome.h b/Minecraft.World/SavannaBiome.h index 66c21310..f942a651 100644 --- a/Minecraft.World/SavannaBiome.h +++ b/Minecraft.World/SavannaBiome.h @@ -16,12 +16,13 @@ public: virtual Biome* createMutatedCopy(int newId); }; + class MutatedSavannaBiome : public MutatedBiome { public: MutatedSavannaBiome(int id, Biome* baseBiome); - virtual void buildSurfaceAtDefault(Level* level, Random* random, - byte* chunkBlocks, int x, int z, - double noiseVal) override; + virtual void buildSurfaceAt(Level* level, Random* random, + ChunkPrimer* primer, int x, int z, + double noiseVal) override; virtual void decorate(Level* level, Random* random, int xo, int zo) override; }; \ No newline at end of file diff --git a/Minecraft.World/SavannaTreeFeature.cpp b/Minecraft.World/SavannaTreeFeature.cpp index 39ac2c28..48457f21 100644 --- a/Minecraft.World/SavannaTreeFeature.cpp +++ b/Minecraft.World/SavannaTreeFeature.cpp @@ -1,122 +1,188 @@ #include "stdafx.h" #include "SavannaTreeFeature.h" #include "net.minecraft.world.level.tile.h" -#include "TreeTile2.h" -#include "LeafTile2.h" #include "Level.h" +#include "Random.h" +#include "Direction.h" -SavannaTreeFeature::SavannaTreeFeature(bool doUpdate) : Feature(doUpdate) { - this->baseHeight = 5; +SavannaTreeFeature::SavannaTreeFeature(bool doUpdate) : AbstractTreeFeature(doUpdate) +{ } -bool SavannaTreeFeature::place(Level* level, Random* random, int x, int y, int z) { - int height = random->nextInt(3) + baseHeight; - int ground = level->getTile(x, y - 1, z); - if (ground != Tile::grass_Id && ground != Tile::dirt_Id) return false; - - - if (random->nextBoolean()) { - generateForkingTree(level, random, x, y, z, height); - } else { - generateBendingTree(level, random, x, y, z, height); - } - - return true; +void SavannaTreeFeature::placeLog(Level* level, int x, int y, int z) +{ + placeBlock(level, x, y, z, Tile::tree2Trunk_Id, 0); } - -void SavannaTreeFeature::generateForkingTree(Level* level, Random* random, int x, int y, int z, int height) { - int curX = x; - int curZ = z; - int forkH = height - random->nextInt(4) - 1; - - - int dx1 = random->nextInt(3) - 1; - int dz1 = (dx1 == 0) ? (random->nextBoolean() ? 1 : -1) : (random->nextInt(3) - 1); - - for (int h = 0; h < height; h++) { - if (h >= forkH) { curX += dx1; curZ += dz1; } - placeBlock(level, curX, y + h, curZ, Tile::tree2Trunk_Id, TreeTile2::ACACIA_TRUNK); - if (h == height - 1) generateLeafCap(level, curX, y + h, curZ); +void SavannaTreeFeature::placeLeafAt(Level* level, int x, int y, int z) +{ + int tile = level->getTile(x, y, z); + if (tile == 0 || tile == Tile::leaves_Id || tile == Tile::leaves2_Id) + { + placeBlock(level, x, y, z, Tile::leaves2_Id, 0); } +} - - int dx2 = random->nextInt(3) - 1; - int dz2 = random->nextInt(3) - 1; - if (dx2 != dx1 || dz2 != dz1) { - int curX2 = x; - int curZ2 = z; - int forkH2 = forkH - random->nextInt(2) - 1; - for (int h = forkH2; h < height; h++) { - if (h >= 1) { - curX2 += dx2; curZ2 += dz2; - placeBlock(level, curX2, y + h, curZ2, Tile::tree2Trunk_Id, TreeTile2::ACACIA_TRUNK); - if (h == height - 1) generateLeafCap(level, curX2, y + h, curZ2); +void SavannaTreeFeature::placeLeavesLayer3(Level* level, int cx, int cy, int cz) +{ + for (int dx = -3; dx <= 3; ++dx) + { + for (int dz = -3; dz <= 3; ++dz) + { + if (abs(dx) != 3 || abs(dz) != 3) + { + placeLeafAt(level, cx + dx, cy, cz + dz); } } } } +void SavannaTreeFeature::placeLeavesLayer1(Level* level, int cx, int cy, int cz) +{ + for (int dx = -1; dx <= 1; ++dx) + { + for (int dz = -1; dz <= 1; ++dz) + { + placeLeafAt(level, cx + dx, cy, cz + dz); + } + } + placeLeafAt(level, cx + 2, cy, cz); + placeLeafAt(level, cx - 2, cy, cz); + placeLeafAt(level, cx, cy, cz + 2); + placeLeafAt(level, cx, cy, cz - 2); +} + +bool SavannaTreeFeature::place(Level* level, Random* random, int x, int y, int z) +{ + + int height = random->nextInt(3) + random->nextInt(3) + 5; + + if (y <= 0 || y + height + 1 > 256) + return false; + + bool canPlace = true; + for (int j = y; j <= y + 1 + height && canPlace; ++j) + { + int radius = 1; + if (j == y) radius = 0; + if (j >= y + 1 + height - 2) radius = 2; + + for (int lx = x - radius; lx <= x + radius && canPlace; ++lx) + { + for (int lz = z - radius; lz <= z + radius && canPlace; ++lz) + { + if (j >= 0 && j < 256) + { + if (!AbstractTreeFeature::isFree(level, lx, j, lz)) + canPlace = false; + } + else + { + canPlace = false; + } + } + } + } + + if (!canPlace) + return false; + + int belowTile = level->getTile(x, y - 1, z); + if (belowTile != Tile::grass_Id && belowTile != Tile::dirt_Id) + return false; + + if (y >= 255 - height) + return false; + + setDirtAt(level, x, y - 1, z); -void SavannaTreeFeature::generateBendingTree(Level* level, Random* random, int x, int y, int z, int height) { + int facing1 = Direction::Plane::getRandomFace(random); + int branchStart = height - random->nextInt(4) - 1; + int branchLen = 3 - random->nextInt(3); + int curX = x; int curZ = z; - int curY = y; + int topY = y; - - int dirX = 0, dirZ = 0; - int roll = random->nextInt(4); - if (roll == 0) dirX = 1; else if (roll == 1) dirX = -1; else if (roll == 2) dirZ = 1; else dirZ = -1; + for (int l1 = 0; l1 < height; ++l1) + { + int curY = y + l1; - - int straightHeight = 2 + random->nextInt(3); - for (int i = 0; i < straightHeight; i++) { - placeBlock(level, curX, curY, curZ, Tile::tree2Trunk_Id, TreeTile2::ACACIA_TRUNK); - curY++; - } + if (l1 >= branchStart && branchLen > 0) + { + curX += Direction::getStepX(facing1); + curZ += Direction::getStepZ(facing1); + --branchLen; + } - - int diagonalSteps = 2 + random->nextInt(2); - for (int i = 0; i < diagonalSteps; i++) { - curX += dirX; - curZ += dirZ; - - placeBlock(level, curX, curY, curZ, Tile::tree2Trunk_Id, TreeTile2::ACACIA_TRUNK); - - - if (i < diagonalSteps - 1) { - curY++; + int tile = level->getTile(curX, curY, curZ); + if (tile == 0 || tile == Tile::leaves_Id || tile == Tile::leaves2_Id) + { + placeLog(level, curX, curY, curZ); + topY = curY; } } - - generateLeafCap(level, curX, curY, curZ); -} + + placeLeavesLayer3(level, curX, topY, curZ); + placeLeavesLayer1(level, curX, topY + 1, curZ); -void SavannaTreeFeature::generateLeafCap(Level* level, int x, int y, int z) { - - for (int lx = -3; lx <= 3; lx++) { - for (int lz = -3; lz <= 3; lz++) { + int curX2 = x; + int curZ2 = z; + int facing2 = Direction::Plane::getRandomFace(random); + + if (facing2 != facing1) + { + + int start2 = branchStart - random->nextInt(2) - 1; + int steps2 = 1 + random->nextInt(3); + int topY2 = 0; + + + for (int l4 = start2; l4 < height && steps2 > 0; --steps2) + { + if (l4 >= 1) + { + int curY2 = y + l4; + curX2 += Direction::getStepX(facing2); + curZ2 += Direction::getStepZ(facing2); + + int tile2 = level->getTile(curX2, curY2, curZ2); + if (tile2 == 0 || tile2 == Tile::leaves_Id || tile2 == Tile::leaves2_Id) + { + placeLog(level, curX2, curY2, curZ2); + topY2 = curY2; + } + } + ++l4; + } + + + if (topY2 > 0) + { - if (abs(lx) == 3 && abs(lz) == 3) continue; - if (abs(lx) + abs(lz) > 4) continue; - placeLeaf(level, x + lx, y, z + lz); + for (int dx = -2; dx <= 2; ++dx) + { + for (int dz = -2; dz <= 2; ++dz) + { + if (abs(dx) != 2 || abs(dz) != 2) + { + placeLeafAt(level, curX2 + dx, topY2, curZ2 + dz); + } + } + } + + for (int dx = -1; dx <= 1; ++dx) + { + for (int dz = -1; dz <= 1; ++dz) + { + placeLeafAt(level, curX2 + dx, topY2 + 1, curZ2 + dz); + } + } } } - - for (int lx = -2; lx <= 2; lx++) { - for (int lz = -2; lz <= 2; lz++) { - if (abs(lx) == 2 && abs(lz) == 2) continue; - placeLeaf(level, x + lx, y + 1, z + lz); - } - } -} - -void SavannaTreeFeature::placeLeaf(Level* level, int x, int y, int z) { - if (level->getTile(x, y, z) == 0) { - placeBlock(level, x, y, z, Tile::leaves2_Id, 0); - } + return true; } \ No newline at end of file diff --git a/Minecraft.World/SavannaTreeFeature.h b/Minecraft.World/SavannaTreeFeature.h index 7c263178..83e04dc6 100644 --- a/Minecraft.World/SavannaTreeFeature.h +++ b/Minecraft.World/SavannaTreeFeature.h @@ -1,28 +1,18 @@ #pragma once -#include "net.minecraft.world.level.levelgen.feature.h" -#include "Feature.h" +#include "AbstractTreeFeature.h" -class SavannaTreeFeature : public Feature +class SavannaTreeFeature : public AbstractTreeFeature { public: - SavannaTreeFeature(bool doUpdate); - - virtual bool place(Level* level, Random* random, int x, int y, int z) override; private: - int baseHeight; + static int s_logState; + static int s_leafState; - - void generateBendingTree(Level* level, Random* random, int x, int y, int z, int height); - - - void generateForkingTree(Level* level, Random* random, int x, int y, int z, int height); - - - void generateLeafCap(Level* level, int x, int y, int z); - - - void placeLeaf(Level* level, int x, int y, int z); + void placeLog(Level* level, int x, int y, int z); + void placeLeafAt(Level* level, int x, int y, int z); + void placeLeavesLayer3(Level* level, int cx, int cy, int cz); + void placeLeavesLayer1(Level* level, int cx, int cy, int cz); }; \ No newline at end of file