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/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 7adbfcae..ef58797a 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,16 +130,25 @@ 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)->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::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); - 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); @@ -381,23 +392,25 @@ 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 fillerState = this->material; - - int runDepth = -1; + 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; } @@ -409,41 +422,47 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock } else if (currentBlockId == static_cast(Tile::stone_Id)) { - if (runDepth == -1) + if (runDepth == -1) { if (noiseDepth <= 0) { - topState = 0; - fillerState = static_cast(Tile::stone_Id); + topState = 0; + topStateData = 0; + fillerState = static_cast(Tile::stone_Id); + fillerStateData = 0; } - else if (y >= seaLevel - 4 && y <= seaLevel + 1) + else if (y >= SEA_LEVEL - 7 - noiseDepth && y < SEA_LEVEL - 1) { - topState = this->topMaterial; - fillerState = this->material; + 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; - fillerState = static_cast(Tile::stone_Id); + topState = 0; + topStateData = 0; + fillerState = static_cast(Tile::stone_Id); + fillerStateData = 0; chunkBlocks[index] = static_cast(Tile::gravel_Id); } - else + else { chunkBlocks[index] = fillerState; } @@ -455,8 +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 - 63 > 0 ? y - 63 : 0); - fillerState = static_cast(Tile::sandStone_Id); + 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 63269e89..f33792cd 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; @@ -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 61363308..c9389419 100644 --- a/Minecraft.World/BiomeInitLayer.cpp +++ b/Minecraft.World/BiomeInitLayer.cpp @@ -3,69 +3,72 @@ #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_customized) + { + this->customSettings = (CustomizableSourceSettings*)superflatConfig; + } } BiomeInitLayer::~BiomeInitLayer() { - delete [] startBiomes.data; + delete [] desertBiomes.data; delete [] warmBiomes.data; delete [] coolBiomes.data; @@ -74,103 +77,98 @@ 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) != 0) + { + result[x + y * w] = Biome::mesaPlateauF->id; + } + else + { + 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; + } + } - return result; + else if (v19 == 4) + { + result[x + y * w] = icyBiomes[nextRandom(icyBiomes.length)]->id; + } + else + { + + result[x + y * w] = v19; + } + } + } + } + } + + 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/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/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/ExtremeHillsBiome.cpp b/Minecraft.World/ExtremeHillsBiome.cpp index d5c05244..87be6845 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,17 @@ 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); + this->setWaterSkyColor(baseBiome->getWaterColor(), baseBiome->getSkyColor()); + 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/Layer.cpp b/Minecraft.World/Layer.cpp index d4e1e81d..52010d59 100644 --- a/Minecraft.World/Layer.cpp +++ b/Minecraft.World/Layer.cpp @@ -1,201 +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 || + 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 f3b90a1d..cfc3cf28 100644 --- a/Minecraft.World/Layer.h +++ b/Minecraft.World/Layer.h @@ -26,11 +26,15 @@ public: Layer(int64_t seedMixup); 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 1a2c9b51..184d84e5 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" @@ -4790,4 +4790,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/MesaBiome.cpp b/Minecraft.World/MesaBiome.cpp index 8d06d5d5..0aef5182 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_ORANGE; - 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 0x9E814D; +} +int MesaBiome::getGrassColor() const +{ + return 0x90814D; +} 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&& id == Biome::mesaBryce->id) +{ + 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 = (localX * 16 + localZ) * 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.2f); + } + + 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 ded41fed..d0df393d 100644 --- a/Minecraft.World/MesaBiome.h +++ b/Minecraft.World/MesaBiome.h @@ -1,62 +1,62 @@ #pragma once #include "Biome.h" -#include "PerlinNoise.h" +#include "PerlinSimplexNoise.h" #include "Random.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/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/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) 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/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 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..3181b63d 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) { return new SavannaTreeFeature(false); } - - return new TreeFeature(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::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); + 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); + + Biome::buildSurfaceAt(level, random, primer, 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..f942a651 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,22 @@ 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 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 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 555feb7f..60573cbb 100644 --- a/Minecraft.World/cmake/sources/Common.cmake +++ b/Minecraft.World/cmake/sources/Common.cmake @@ -1459,6 +1459,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})