From 6fc28085922b12580d637dee87e865d5655676ab Mon Sep 17 00:00:00 2001 From: Lord Cambion Date: Tue, 24 Mar 2026 13:41:49 +0100 Subject: [PATCH] 5 New Technical Biomes --- Minecraft.Client/TileRenderer.cpp | 48 +- Minecraft.World/Biome.cpp | 87 ++- Minecraft.World/Biome.h | 72 +- Minecraft.World/BiomeDecorator.cpp | 627 +++++++++--------- Minecraft.World/BiomeDecorator.h | 8 +- Minecraft.World/BiomeInitLayer.cpp | 8 +- Minecraft.World/BlockPos.cpp | 188 ++++++ Minecraft.World/BlockPos.h | 65 ++ Minecraft.World/ChunkPrimer.cpp | 105 +++ Minecraft.World/ChunkPrimer.h | 42 ++ Minecraft.World/DarkOakFeature.cpp | 189 ------ Minecraft.World/Direction.h | 20 + Minecraft.World/DoublePlantFeature.cpp | 43 ++ Minecraft.World/DoublePlantFeature.h | 16 + Minecraft.World/ForestBiome.cpp | 321 +++++++-- Minecraft.World/ForestBiome.h | 46 +- Minecraft.World/Minecraft.World.vcxproj | 14 +- .../Minecraft.World.vcxproj.filters | 14 +- Minecraft.World/MutatedBiome.cpp | 84 +++ Minecraft.World/MutatedBiome.h | 24 + Minecraft.World/PlainsBiome.cpp | 18 + Minecraft.World/PlainsBiome.h | 1 + Minecraft.World/RoofTreeFeature.cpp | 199 ++++++ .../{DarkOakFeature.h => RoofTreeFeature.h} | 4 +- Minecraft.World/RoofedForestBiome.cpp | 64 -- Minecraft.World/RoofedForestBiome.h | 12 - Minecraft.World/Sapling.cpp | 4 +- Minecraft.World/SavannaBiome.cpp | 19 +- Minecraft.World/SavannaBiome.h | 6 +- Minecraft.World/SwampBiome.h | 5 +- Minecraft.World/Vec3.cpp | 96 ++- Minecraft.World/Vec3.h | 9 +- Minecraft.World/Vec3i.cpp | 33 +- Minecraft.World/Vec3i.h | 45 +- .../net.minecraft.world.level.biome.h | 3 +- ...t.minecraft.world.level.levelgen.feature.h | 5 +- .../net.minecraft.world.level.tile.h | 4 +- 37 files changed, 1782 insertions(+), 766 deletions(-) create mode 100644 Minecraft.World/BlockPos.cpp create mode 100644 Minecraft.World/BlockPos.h create mode 100644 Minecraft.World/ChunkPrimer.cpp create mode 100644 Minecraft.World/ChunkPrimer.h delete mode 100644 Minecraft.World/DarkOakFeature.cpp create mode 100644 Minecraft.World/DoublePlantFeature.cpp create mode 100644 Minecraft.World/DoublePlantFeature.h create mode 100644 Minecraft.World/MutatedBiome.cpp create mode 100644 Minecraft.World/MutatedBiome.h create mode 100644 Minecraft.World/RoofTreeFeature.cpp rename Minecraft.World/{DarkOakFeature.h => RoofTreeFeature.h} (85%) delete mode 100644 Minecraft.World/RoofedForestBiome.cpp delete mode 100644 Minecraft.World/RoofedForestBiome.h diff --git a/Minecraft.Client/TileRenderer.cpp b/Minecraft.Client/TileRenderer.cpp index b77729ab..927836b1 100644 --- a/Minecraft.Client/TileRenderer.cpp +++ b/Minecraft.Client/TileRenderer.cpp @@ -1858,31 +1858,31 @@ bool TileRenderer::tesselateLeverInWorld( Tile* tt, int x, int y, int z ) if ( flipped ) { corners[i]->z -= 1 / 16.0f; - corners[i]->xRot( 40 * PI / 180 ); + corners[i]->xRotInPlace( 40 * PI / 180 ); } else { corners[i]->z += 1 / 16.0f; - corners[i]->xRot( -40 * PI / 180 ); + corners[i]->xRotInPlace( -40 * PI / 180 ); } if (dir == 0 || dir == 7) { - corners[i]->zRot(180 * PI / 180); + corners[i]->zRotInPlace(180 * PI / 180); } if ( dir == 6 || dir == 0 ) { - corners[i]->yRot( 90 * PI / 180 ); + corners[i]->yRotInPlace( 90 * PI / 180 ); } if ( dir > 0 && dir < 5 ) { corners[i]->y -= 6 / 16.0f; - corners[i]->xRot( 90 * PI / 180 ); + corners[i]->xRotInPlace( 90 * PI / 180 ); - if ( dir == 4 ) corners[i]->yRot( 0 * PI / 180 ); - if ( dir == 3 ) corners[i]->yRot( 180 * PI / 180 ); - if ( dir == 2 ) corners[i]->yRot( 90 * PI / 180 ); - if ( dir == 1 ) corners[i]->yRot( -90 * PI / 180 ); + if ( dir == 4 ) corners[i]->yRotInPlace( 0 * PI / 180 ); + if ( dir == 3 ) corners[i]->yRotInPlace( 180 * PI / 180 ); + if ( dir == 2 ) corners[i]->yRotInPlace( 90 * PI / 180 ); + if ( dir == 1 ) corners[i]->yRotInPlace( -90 * PI / 180 ); corners[i]->x += x + 0.5; corners[i]->y += y + 8 / 16.0f; @@ -2047,26 +2047,26 @@ bool TileRenderer::tesselateTripwireSourceInWorld(Tile *tt, int x, int y, int z) if (powered) { - corners[i]->xRot(30 * PI / 180); + corners[i]->xRotInPlace(30 * PI / 180); corners[i]->y -= 7 / 16.0f; } else if (attached) { - corners[i]->xRot(5 * PI / 180); + corners[i]->xRotInPlace(5 * PI / 180); corners[i]->y -= 7 / 16.0f; } else { - corners[i]->xRot(-40 * PI / 180); + corners[i]->xRotInPlace(-40 * PI / 180); corners[i]->y -= 6 / 16.0f; } - corners[i]->xRot(90 * PI / 180); + corners[i]->xRotInPlace(90 * PI / 180); - if (dir == Direction::NORTH) corners[i]->yRot(0 * PI / 180); - if (dir == Direction::SOUTH) corners[i]->yRot(180 * PI / 180); - if (dir == Direction::WEST) corners[i]->yRot(90 * PI / 180); - if (dir == Direction::EAST) corners[i]->yRot(-90 * PI / 180); + if (dir == Direction::NORTH) corners[i]->yRotInPlace(0 * PI / 180); + if (dir == Direction::SOUTH) corners[i]->yRotInPlace(180 * PI / 180); + if (dir == Direction::WEST) corners[i]->yRotInPlace(90 * PI / 180); + if (dir == Direction::EAST) corners[i]->yRotInPlace(-90 * PI / 180); corners[i]->x += x + 0.5; corners[i]->y += y + 5 / 16.0f; @@ -2158,23 +2158,23 @@ bool TileRenderer::tesselateTripwireSourceInWorld(Tile *tt, int x, int y, int z) { corners[i]->y -= 1.5 / 16.0f; corners[i]->z -= 2.6 / 16.0f; - corners[i]->xRot(0 * PI / 180); + corners[i]->xRotInPlace(0 * PI / 180); } else if (attached) { corners[i]->y += 0.25 / 16.0f; corners[i]->z -= 2.75 / 16.0f; - corners[i]->xRot(10 * PI / 180); + corners[i]->xRotInPlace(10 * PI / 180); } else { - corners[i]->xRot(50 * PI / 180); + corners[i]->xRotInPlace(50 * PI / 180); } - if (dir == Direction::NORTH) corners[i]->yRot(0 * PI / 180); - if (dir == Direction::SOUTH) corners[i]->yRot(180 * PI / 180); - if (dir == Direction::WEST) corners[i]->yRot(90 * PI / 180); - if (dir == Direction::EAST) corners[i]->yRot(-90 * PI / 180); + if (dir == Direction::NORTH) corners[i]->yRotInPlace(0 * PI / 180); + if (dir == Direction::SOUTH) corners[i]->yRotInPlace(180 * PI / 180); + if (dir == Direction::WEST) corners[i]->yRotInPlace(90 * PI / 180); + if (dir == Direction::EAST) corners[i]->yRotInPlace(-90 * PI / 180); corners[i]->x += x + 0.5; corners[i]->y += y + 5 / 16.0f; diff --git a/Minecraft.World/Biome.cpp b/Minecraft.World/Biome.cpp index 09280ff6..311aba55 100644 --- a/Minecraft.World/Biome.cpp +++ b/Minecraft.World/Biome.cpp @@ -13,6 +13,8 @@ Biome *Biome::biomes[256]; + + Biome *Biome::ocean = nullptr; Biome *Biome::plains = nullptr; Biome *Biome::desert = nullptr; @@ -39,14 +41,23 @@ Biome *Biome::jungleHills = nullptr; Biome *Biome::savanna = nullptr; Biome *Biome::roofedForest = nullptr; Biome *Biome::flowerForest = nullptr; +Biome *Biome::birchForest = nullptr; +Biome *Biome::birchForestHills = nullptr; +Biome *Biome::birchForestHillsM = nullptr; +Biome *Biome::birchForestM = nullptr; +Biome *Biome::deepOcean = nullptr; +Biome *Biome::roofedForestM = nullptr; void Biome::staticCtor() { - Biome::ocean = (new OceanBiome(0))->setColor(0x000070)->setName(L"Ocean")->setDepthAndScale(-1, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Ocean, eMinecraftColour_Foliage_Ocean, eMinecraftColour_Water_Ocean,eMinecraftColour_Sky_Ocean); + Biome::ocean = (new OceanBiome(0))->setColor(0x000070)->setName(L"Ocean")->setDepthAndScale(-1, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Ocean, eMinecraftColour_Foliage_Ocean, eMinecraftColour_Water_Ocean,eMinecraftColour_Sky_Ocean); Biome::plains = (new PlainsBiome(1))->setColor(0x8db360)->setName(L"Plains")->setTemperatureAndDownfall(0.8f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Plains, eMinecraftColour_Foliage_Plains, eMinecraftColour_Water_Plains,eMinecraftColour_Sky_Plains); Biome::desert = (new DesertBiome(2))->setColor(0xFA9418)->setName(L"Desert")->setNoRain()->setTemperatureAndDownfall(2, 0)->setDepthAndScale(0.1f, 0.2f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Desert, eMinecraftColour_Foliage_Desert, eMinecraftColour_Water_Desert,eMinecraftColour_Sky_Desert); Biome::extremeHills = (new ExtremeHillsBiome(3))->setColor(0x606060)->setName(L"Extreme Hills")->setDepthAndScale(0.3f, 1.5f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills, eMinecraftColour_Foliage_ExtremeHills, eMinecraftColour_Water_ExtremeHills,eMinecraftColour_Sky_ExtremeHills); + + // Foreste Base Biome::forest = (new ForestBiome(4,0))->setColor(0x056621)->setName(L"Forest")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.7f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Forest, eMinecraftColour_Water_Forest,eMinecraftColour_Sky_Forest); + Biome::forestHills = (new ForestBiome(18,0))->setColor(0x22551c)->setName(L"ForestHills")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.7f, 0.8f)->setDepthAndScale(0.3f, 0.7f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_ForestHills, eMinecraftColour_Water_ForestHills,eMinecraftColour_Sky_ForestHills); Biome::taiga = (new TaigaBiome(5))->setColor(0x0b6659)->setName(L"Taiga")->setLeafColor(0x4EBA31)->setSnowCovered()->setTemperatureAndDownfall(0.05f, 0.8f)->setDepthAndScale(0.1f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga); Biome::swampland = (new SwampBiome(6))->setColor(0x07F9B2)->setName(L"Swampland")->setLeafColor(0x8BAF48)->setDepthAndScale(-0.2f, 0.1f)->setTemperatureAndDownfall(0.8f, 0.9f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Swampland, eMinecraftColour_Foliage_Swampland, eMinecraftColour_Water_Swampland,eMinecraftColour_Sky_Swampland); @@ -61,17 +72,25 @@ void Biome::staticCtor() Biome::mushroomIslandShore = (new MushroomIslandBiome(15))->setColor(0xa000ff)->setName(L"MushroomIslandShore")->setTemperatureAndDownfall(0.9f, 1.0f)->setDepthAndScale(-1, 0.1f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_MushroomIslandShore, eMinecraftColour_Foliage_MushroomIslandShore, eMinecraftColour_Water_MushroomIslandShore,eMinecraftColour_Sky_MushroomIslandShore); Biome::beaches = (new BeachBiome(16))->setColor(0xfade55)->setName(L"Beach")->setTemperatureAndDownfall(0.8f, 0.4f)->setDepthAndScale(0.0f, 0.1f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Beach, eMinecraftColour_Foliage_Beach, eMinecraftColour_Water_Beach,eMinecraftColour_Sky_Beach); Biome::desertHills = (new DesertBiome(17))->setColor(0xd25f12)->setName(L"DesertHills")->setNoRain()->setTemperatureAndDownfall(2, 0)->setDepthAndScale(0.3f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_DesertHills, eMinecraftColour_Foliage_DesertHills, eMinecraftColour_Water_DesertHills,eMinecraftColour_Sky_DesertHills); - Biome::forestHills = (new ForestBiome(18,1))->setColor(0x22551c)->setName(L"ForestHills")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.7f, 0.8f)->setDepthAndScale(0.3f, 0.7f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_ForestHills, eMinecraftColour_Water_ForestHills,eMinecraftColour_Sky_ForestHills); Biome::taigaHills = (new TaigaBiome(19))->setColor(0x163933)->setName(L"TaigaHills")->setSnowCovered()->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.05f, 0.8f)->setDepthAndScale(0.3f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_TaigaHills, eMinecraftColour_Foliage_TaigaHills, eMinecraftColour_Water_TaigaHills,eMinecraftColour_Sky_TaigaHills); Biome::smallerExtremeHills = (new ExtremeHillsBiome(20))->setColor(0x72789a)->setName(L"Extreme Hills Edge")->setDepthAndScale(0.2f, 0.8f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHillsEdge, eMinecraftColour_Foliage_ExtremeHillsEdge, eMinecraftColour_Water_ExtremeHillsEdge,eMinecraftColour_Sky_ExtremeHillsEdge); Biome::jungle = (new JungleBiome(21))->setColor(0x537b09)->setName(L"Jungle")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(0.2f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_Jungle,eMinecraftColour_Sky_Jungle); Biome::jungleHills = (new JungleBiome(22))->setColor(0x2c4205)->setName(L"JungleHills")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(1.8f, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_JungleHills, eMinecraftColour_Foliage_JungleHills, eMinecraftColour_Water_JungleHills,eMinecraftColour_Sky_JungleHills); 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::deepOcean= (new OceanBiome(24))->setName(L"Deep Ocean")->setDepthAndScale(-1.8,0.1f)->setColor(0x000070)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Ocean, eMinecraftColour_Foliage_Ocean, eMinecraftColour_Water_Ocean,eMinecraftColour_Sky_Ocean);; + // Foreste Avanzate e Speciali Biome::roofedForest = (new ForestBiome(29, 3))->setColor(0x056621)->setName(L"Roofed Forest")->setTemperatureAndDownfall(0.7f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_RoofedForest, eMinecraftColour_Foliage_RoofedForest, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest); 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); -} + // Nuovi Biomi Betulla + Biome::birchForest=(new ForestBiome(27, 2))->setColor(0x307444)->setName(L"Birch Forest")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest); + Biome::birchForestHills=(new ForestBiome(28, 2))->setColor(0x1f5f32)->setName(L"Birch Forest Hills")->setDepthAndScale(0.45f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_ForestHills); + + // Varianti Mutate (M) + 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::Biome(int id) : id(id) { color = 0; @@ -86,7 +105,6 @@ Biome::Biome(int id) : id(id) decorator = nullptr; m_temperatureNoise = nullptr; - m_grassColor = eMinecraftColour_NOT_SET; m_foliageColor = eMinecraftColour_NOT_SET; m_waterColor = eMinecraftColour_NOT_SET; @@ -94,6 +112,10 @@ Biome::Biome(int id) : id(id) biomes[id] = this; decorator = createDecorator(); + // -- FIX FIORI ED ERBA GLOBALI -- + decorator->flowerCount = 2; // Valore base di fiori (esclusi biomi speciali che ne sovrascrivono il numero) + decorator->grassCount = 1; // Valore base di erba alta + friendlies.push_back(new MobSpawnerData(eTYPE_SHEEP, 12, 4, 4)); friendlies.push_back(new MobSpawnerData(eTYPE_PIG, 10, 4, 4)); friendlies_chicken.push_back(new MobSpawnerData(eTYPE_CHICKEN, 10, 4, 4)); @@ -223,7 +245,7 @@ bool Biome::isHumid() return downfall > .85f; } -float Biome::getCreatureProbability() +float Biome::getCreatureProbability() const { return 0.1f; } @@ -253,12 +275,12 @@ void Biome::decorate(Level *level, Random *random, int xo, int zo) decorator->decorate(level, random, xo, zo); } -int Biome::getGrassColor() +int Biome::getGrassColor() const { return Minecraft::GetInstance()->getColourTable()->getColor( m_grassColor ); } -int Biome::getFolageColor() +int Biome::getFoliageColor() const { return Minecraft::GetInstance()->getColourTable()->getColor( m_foliageColor ); } @@ -363,4 +385,53 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock } } } +} + +float Biome::getTemperature(const BlockPos& pos) +{ + return getTemperature(pos.getX(), pos.getY(), pos.getZ()); +} + + +void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, const BlockPos& pos, double noiseVal) +{ + buildSurfaceAtDefault(level, random, chunkBlocks, pos.getX(), pos.getZ(), noiseVal); +} + +bool Biome::isSame(const Biome* other) const +{ + if (!other) return false; + return id == other->id; +} + +int Biome::getTemperatureCategory() const +{ + if (temperature < 0.2f) return 1; + if (temperature > 1.0f) return 3; + return 2; +} + +void Biome::buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal) +{ + buildSurfaceAtDefault(level, random, primer->getBlockIds(), x, z, noiseVal); +} + +Feature *Biome::getFlowerFeature(Random *random, int x, int y, int z) +{ + + if (random->nextInt(3) > 0) + { + return new FlowerFeature(Tile::flower_Id); + } + return new FlowerFeature(Tile::rose_Id); +} + +int Biome::getRandomDoublePlantType(Random *random) +{ + + int type = random->nextInt(10); + if (type < 7) return 0; + if (type == 7) return 3; + if (type == 8) return 4; + return 2; } \ No newline at end of file diff --git a/Minecraft.World/Biome.h b/Minecraft.World/Biome.h index fc4f9a6f..8f8f9771 100644 --- a/Minecraft.World/Biome.h +++ b/Minecraft.World/Biome.h @@ -4,6 +4,9 @@ using namespace std; #include "LevelSource.h" #include "Mob.h" #include "WeighedRandom.h" +#include "BlockPos.h" +#include "ChunkPrimer.h" + class Feature; class MobCategory; @@ -14,6 +17,8 @@ class BirchFeature; class SwampTreeFeature; class ChunkRebuildData; class PerlinNoise; +class MutatedBiome; +class ChunkPrimer; class Biome { @@ -48,9 +53,20 @@ public: static Biome *jungleHills; static Biome *savanna; static Biome *roofedForest; - static Biome *flowerForest; - static const int BIOME_COUNT = 23; // 4J Stu added + static Biome *flowerForest; + static Biome *Biome::birchForest; + + static Biome *Biome::birchForestHills ; + + static Biome *Biome::birchForestM ; + + static Biome *Biome::birchForestHillsM; + + static Biome *Biome::roofedForestM; + static Biome *Biome::deepOcean; + + static const int BIOME_COUNT = 32; public: wstring m_name; @@ -75,7 +91,8 @@ public: int minCount; int maxCount; - MobSpawnerData(eINSTANCEOF mobClass, int probabilityWeight, int minCount, int maxCount) : WeighedRandomItem(probabilityWeight) + MobSpawnerData(eINSTANCEOF mobClass, int probabilityWeight, int minCount, int maxCount) + : WeighedRandomItem(probabilityWeight) { this->mobClass = mobClass; this->minCount = minCount; @@ -83,7 +100,7 @@ public: } }; -protected: +public: vector enemies; vector friendlies; vector waterFriendlies; @@ -104,7 +121,6 @@ public: bool snowCovered; bool _hasRain; - // 4J Added eMinecraftColour m_grassColor; eMinecraftColour m_foliageColor; eMinecraftColour m_waterColor; @@ -121,12 +137,11 @@ protected: Biome *setName(const wstring &name); Biome *setLeafColor(int leafColor); - public: - +public: virtual Biome *setColor(int color, bool b = false); - // 4J Added - Biome *setLeafFoliageWaterSkyColor(eMinecraftColour grassColor, eMinecraftColour foliageColor, eMinecraftColour waterColour, eMinecraftColour skyColour); + Biome *setLeafFoliageWaterSkyColor(eMinecraftColour grassColor, eMinecraftColour foliageColor, + eMinecraftColour waterColour, eMinecraftColour skyColour); public: virtual int getSkyColor(float temp); @@ -137,22 +152,49 @@ public: virtual bool hasRain(); virtual bool isHumid(); - virtual float getCreatureProbability(); + virtual int getDownfallInt(); virtual int getTemperatureInt(); virtual float getDownfall(); virtual float getTemperature(); - - virtual float getTemperature(int x, int y, int z); + virtual float getTemperature(const BlockPos& pos); + virtual float getTemperature(int x, int y, int z); virtual void decorate(Level *level, Random *random, int xo, int zo); - virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal); - virtual int getGrassColor(); - virtual int getFolageColor(); + + virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, const BlockPos& pos, double noiseVal); + + + virtual int getWaterColor(); + + public: + + void setWaterSkyColor(int waterRGB, int skyRGB) { + m_waterColor = (eMinecraftColour)waterRGB; + m_skyColor = (eMinecraftColour)skyRGB; + } + void setDebugName(const wstring& name) { m_name = name; } + int getWaterColor() const { return m_waterColor; } + int getSkyColor() const { return m_skyColor; } + + virtual int getBaseBiomeId() const { return id; } + virtual int getFoliageColor() const; // rename from getFolageColor + virtual bool isSame(const Biome* other) const; + virtual int getTemperatureCategory() const; + virtual void buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal); + + + virtual float getCreatureProbability() const; + virtual int getGrassColor() const; + virtual int Biome::getFolageColor()const{ + return getFoliageColor(); } + virtual Feature *getFlowerFeature(Random *random, int x, int y, int z); + virtual int getRandomDoublePlantType(Random *random); + }; \ No newline at end of file diff --git a/Minecraft.World/BiomeDecorator.cpp b/Minecraft.World/BiomeDecorator.cpp index d1f2fc44..78cddb96 100644 --- a/Minecraft.World/BiomeDecorator.cpp +++ b/Minecraft.World/BiomeDecorator.cpp @@ -3,370 +3,393 @@ #include "net.minecraft.world.level.tile.h" #include "net.minecraft.world.level.levelgen.feature.h" #include "net.minecraft.world.level.biome.h" +#include "Rose.h" +#include "TallGrass.h" +#include "Tallgrass2.h" +#include "DoublePlantFeature.h" BiomeDecorator::BiomeDecorator(Biome *biome) { - _init(); + _init(); - // 4J inits - level = nullptr; - random = nullptr; - xo = 0; - zo = 0; + // 4J inits + level = nullptr; + random = nullptr; + xo = 0; + zo = 0; - this->biome = biome; + this->biome = biome; } void BiomeDecorator::decorate(Level *level, Random *random, int xo, int zo) { - if (this->level != nullptr) - { - app.DebugPrintf("BiomeDecorator::decorate - Already decorating!!\n"); + if (this->level != nullptr) + { + app.DebugPrintf("BiomeDecorator::decorate - Already decorating!!\n"); #ifndef _CONTENT_PACKAGE - __debugbreak(); - //throw new RuntimeException("Already decorating!!"); + __debugbreak(); + //throw new RuntimeException("Already decorating!!"); #endif - } - this->level = level; - this->random = random; - this->xo = xo; - this->zo = zo; + } + this->level = level; + this->random = random; + this->xo = xo; + this->zo = zo; - decorate(); + decorate(); - this->level = nullptr; - this->random = nullptr; + this->level = nullptr; + this->random = nullptr; } - - void BiomeDecorator::_init() { - clayFeature = new ClayFeature(4); - sandFeature = new SandFeature(7, Tile::sand_Id); - gravelFeature = new SandFeature(6, Tile::gravel_Id); - dirtOreFeature = new OreFeature(Tile::dirt_Id, 32); - gravelOreFeature = new OreFeature(Tile::gravel_Id, 32); - coalOreFeature = new OreFeature(Tile::coalOre_Id, 16); - ironOreFeature = new OreFeature(Tile::ironOre_Id, 8); - goldOreFeature = new OreFeature(Tile::goldOre_Id, 8); - redStoneOreFeature = new OreFeature(Tile::redStoneOre_Id, 7); - diamondOreFeature = new OreFeature(Tile::diamondOre_Id, 7); - lapisOreFeature = new OreFeature(Tile::lapisOre_Id, 6); - yellowFlowerFeature = new FlowerFeature(Tile::flower_Id); - roseFlowerFeature = new FlowerFeature(Tile::rose_Id); - - brownMushroomFeature = new FlowerFeature(Tile::mushroom_brown_Id); - redMushroomFeature = new FlowerFeature(Tile::mushroom_red_Id); - hugeMushroomFeature = new HugeMushroomFeature(); - reedsFeature = new ReedsFeature(); - cactusFeature = new CactusFeature(); - waterlilyFeature = new WaterlilyFeature(); - blueOrchidFeature = new FlowerFeature(Tile::rose_Id, Rose::BLUE_ORCHID); - alliumFeature = new FlowerFeature(Tile::rose_Id, Rose::ALLIUM); - azureBluetFeature = new FlowerFeature(Tile::rose_Id, Rose::AZURE_BLUET); - oxeyeDaisyFeature = new FlowerFeature(Tile::rose_Id, Rose::OXEYE_DAISY); + clayFeature = new ClayFeature(4); + sandFeature = new SandFeature(7, Tile::sand_Id); + gravelFeature = new SandFeature(6, Tile::gravel_Id); + dirtOreFeature = new OreFeature(Tile::dirt_Id, 32); + gravelOreFeature = new OreFeature(Tile::gravel_Id, 32); + coalOreFeature = new OreFeature(Tile::coalOre_Id, 16); + ironOreFeature = new OreFeature(Tile::ironOre_Id, 8); + goldOreFeature = new OreFeature(Tile::goldOre_Id, 8); + redStoneOreFeature = new OreFeature(Tile::redStoneOre_Id, 7); + diamondOreFeature = new OreFeature(Tile::diamondOre_Id, 7); + lapisOreFeature = new OreFeature(Tile::lapisOre_Id, 6); + + yellowFlowerFeature = new FlowerFeature(Tile::flower_Id); + roseFlowerFeature = new FlowerFeature(Tile::rose_Id); + brownMushroomFeature = new FlowerFeature(Tile::mushroom_brown_Id); + redMushroomFeature = new FlowerFeature(Tile::mushroom_red_Id); + hugeMushroomFeature = new HugeMushroomFeature(); + reedsFeature = new ReedsFeature(); + cactusFeature = new CactusFeature(); + waterlilyFeature = new WaterlilyFeature(); + + blueOrchidFeature = new FlowerFeature(Tile::rose_Id, Rose::BLUE_ORCHID); + alliumFeature = new FlowerFeature(Tile::rose_Id, Rose::ALLIUM); + azureBluetFeature = new FlowerFeature(Tile::rose_Id, Rose::AZURE_BLUET); + oxeyeDaisyFeature = new FlowerFeature(Tile::rose_Id, Rose::OXEYE_DAISY); + tulipRedFeature = new FlowerFeature(Tile::rose_Id, Rose::RED_TULIP); + tulipOrangeFeature = new FlowerFeature(Tile::rose_Id, Rose::ORANGE_TULIP); + tulipWhiteFeature = new FlowerFeature(Tile::rose_Id, Rose::WHITE_TULIP); + tulipPinkFeature = new FlowerFeature(Tile::rose_Id, Rose::PINK_TULIP); - waterlilyCount = 0; - treeCount = 0; - flowerCount = 2; - grassCount = 1; - deadBushCount = 0; - mushroomCount = 0; - reedsCount = 0; - cactusCount = 0; - gravelCount = 1; - sandCount = 3; - clayCount = 1; - hugeMushrooms = 0; - blueOrchidCount = 0; - alliumCount = 0; - azureBluetCount = 0; - oxeyeDaisyCount = 0; - liquids = true; + doublePlantFeature = new DoublePlantFeature(false); + + waterlilyCount = 0; + treeCount = 0; + flowerCount = 2; + grassCount = 1; + deadBushCount = 0; + mushroomCount = 0; + reedsCount = 0; + cactusCount = 0; + gravelCount = 1; + sandCount = 3; + clayCount = 1; + hugeMushrooms = 0; + blueOrchidCount = 0; + alliumCount = 0; + azureBluetCount = 0; + oxeyeDaisyCount = 0; + liquids = true; } - void BiomeDecorator::decorate() { - PIXBeginNamedEvent(0,"Decorate ores"); - decorateOres(); - PIXEndNamedEvent(); + PIXBeginNamedEvent(0,"Decorate ores"); + decorateOres(); + PIXEndNamedEvent(); - PIXBeginNamedEvent(0,"Decorate sand/clay/gravel"); - for (int i = 0; i < sandCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int z = zo + random->nextInt(16) + 8; - sandFeature->place(level, random, x, level->getTopSolidBlock(x, z), z); - } + PIXBeginNamedEvent(0,"Decorate sand/clay/gravel"); + for (int i = 0; i < sandCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int z = zo + random->nextInt(16) + 8; + sandFeature->place(level, random, x, level->getTopSolidBlock(x, z), z); + } - for (int i = 0; i < clayCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int z = zo + random->nextInt(16) + 8; - clayFeature->place(level, random, x, level->getTopSolidBlock(x, z), z); - } + for (int i = 0; i < clayCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int z = zo + random->nextInt(16) + 8; + clayFeature->place(level, random, x, level->getTopSolidBlock(x, z), z); + } - for (int i = 0; i < gravelCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int z = zo + random->nextInt(16) + 8; - sandFeature->place(level, random, x, level->getTopSolidBlock(x, z), z); - } - PIXEndNamedEvent(); + for (int i = 0; i < gravelCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int z = zo + random->nextInt(16) + 8; + sandFeature->place(level, random, x, level->getTopSolidBlock(x, z), z); + } + PIXEndNamedEvent(); - PIXBeginNamedEvent(0, "Decorate forests"); - int forests = treeCount; - if (random->nextInt(10) == 0) forests += 1; + PIXBeginNamedEvent(0, "Decorate forests"); + int forests = treeCount; + if (random->nextInt(10) == 0) forests += 1; - for (int i = 0; i < forests; i++) - { - int x = xo + random->nextInt(16) + 8; - int z = zo + random->nextInt(16) + 8; - Feature *tree = biome->getTreeFeature(random); - tree->init(1, 1, 1); - tree->place(level, random, x, level->getHeightmap(x, z), z); - delete tree; - } - PIXEndNamedEvent(); + for (int i = 0; i < forests; i++) + { + int x = xo + random->nextInt(16) + 8; + int z = zo + random->nextInt(16) + 8; + Feature *tree = biome->getTreeFeature(random); + tree->init(1, 1, 1); + tree->place(level, random, x, level->getHeightmap(x, z), z); + delete tree; + } + PIXEndNamedEvent(); - PIXBeginNamedEvent(0,"Decorate mushrooms/flowers/grass"); - for (int i = 0; i < hugeMushrooms; i++) - { - int x = xo + random->nextInt(16) + 8; - int z = zo + random->nextInt(16) + 8; - hugeMushroomFeature->place(level, random, x, level->getHeightmap(x, z), z); - } + PIXBeginNamedEvent(0,"Decorate mushrooms/flowers/grass"); + for (int i = 0; i < hugeMushrooms; i++) + { + int x = xo + random->nextInt(16) + 8; + int z = zo + random->nextInt(16) + 8; + hugeMushroomFeature->place(level, random, x, level->getHeightmap(x, z), z); + } - for (int i = 0; i < flowerCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - yellowFlowerFeature->place(level, random, x, y, z); + + for (int i = 0; i < flowerCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int z = zo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + + Feature* selectedFlower = biome->getFlowerFeature(random, x, y, z); + if (selectedFlower != nullptr) + { + selectedFlower->place(level, random, x, y, z); + delete selectedFlower; + } + } - if (random->nextInt(4) == 0) - { - x = xo + random->nextInt(16) + 8; - y = random->nextInt(Level::genDepth); - z = zo + random->nextInt(16) + 8; - roseFlowerFeature->place(level, random, x, y, z); - } - } + //forced biomes + for (int i = 0; i < blueOrchidCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + blueOrchidFeature->place(level, random, x, y, z); + } + for (int i = 0; i < alliumCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + alliumFeature->place(level, random, x, y, z); + } + for (int i = 0; i < azureBluetCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + azureBluetFeature->place(level, random, x, y, z); + } - // Nuovi fiori — generati solo se il bioma ha impostato il contatore - for (int i = 0; i < blueOrchidCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - blueOrchidFeature->place(level, random, x, y, z); - } + for (int i = 0; i < oxeyeDaisyCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + oxeyeDaisyFeature->place(level, random, x, y, z); + } - for (int i = 0; i < alliumCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - alliumFeature->place(level, random, x, y, z); - } + // 1block grass + for (int i = 0; i < grassCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + + MemSect(50); + Feature *grassFeature = biome->getGrassFeature(random); + MemSect(0); + + if (grassFeature) + { + grassFeature->place(level, random, x, y, z); + delete grassFeature; + } + } - for (int i = 0; i < azureBluetCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - azureBluetFeature->place(level, random, x, y, z); - } + // 2blockstall + int doublePlantsToGen = (grassCount + flowerCount) / 2; + if (doublePlantsToGen > 0 && random->nextInt(3) == 0) + { + for (int i = 0; i < doublePlantsToGen; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + + + int plantType = biome->getRandomDoublePlantType(random); + + DoublePlantFeature* dpf = static_cast(doublePlantFeature); + dpf->setPlantType(plantType); + dpf->place(level, random, x, y, z); + } + } + PIXEndNamedEvent(); - for (int i = 0; i < oxeyeDaisyCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - oxeyeDaisyFeature->place(level, random, x, y, z); - } + PIXBeginNamedEvent(0,"Decorate bush/waterlily/mushroom/reeds/pumpkins/cactuses"); - for (int i = 0; i < grassCount; i++) - { - //int grassType = TallGrass::TALL_GRASS; + DeadBushFeature *deadBushFeature = nullptr; + if(deadBushCount > 0) deadBushFeature = new DeadBushFeature(Tile::deadBush_Id); + for (int i = 0; i < deadBushCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + deadBushFeature->place(level, random, x, y, z); + } + if(deadBushFeature != nullptr) delete deadBushFeature; - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - MemSect(50); - Feature *grassFeature = biome->getGrassFeature(random); - MemSect(0); - grassFeature->place(level, random, x, y, z); - delete grassFeature; - } - PIXEndNamedEvent(); - PIXBeginNamedEvent(0,"Decorate bush/waterlily/mushroom/reeds/pumpkins/cactuses"); + for (int i = 0; i < waterlilyCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int z = zo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + while (y > 0 && level->getTile(x, y - 1, z) == 0) + y--; + waterlilyFeature->place(level, random, x, y, z); + } - // 4J Stu - For some reason this was created each time round in the loop - // I assume there is a case where deadBushCount could be 0 - DeadBushFeature *deadBushFeature = nullptr; - if(deadBushCount > 0) deadBushFeature = new DeadBushFeature(Tile::deadBush_Id); - for (int i = 0; i < deadBushCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - //new DeadBushFeature(Tile::deadBush_Id)->place(level, random, x, y, z); - deadBushFeature->place(level, random, x, y, z); - } - if(deadBushFeature != nullptr)delete deadBushFeature; + for (int i = 0; i < mushroomCount; i++) + { + if (random->nextInt(4) == 0) + { + int x = xo + random->nextInt(16) + 8; + int z = zo + random->nextInt(16) + 8; + int y = level->getHeightmap(x, z); + brownMushroomFeature->place(level, random, x, y, z); + } - for (int i = 0; i < waterlilyCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int z = zo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - while (y > 0 && level->getTile(x, y - 1, z) == 0) - y--; - waterlilyFeature->place(level, random, x, y, z); - } + if (random->nextInt(8) == 0) + { + int x = xo + random->nextInt(16) + 8; + int z = zo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + redMushroomFeature->place(level, random, x, y, z); + } + } - for (int i = 0; i < mushroomCount; i++) - { - if (random->nextInt(4) == 0) - { - int x = xo + random->nextInt(16) + 8; - int z = zo + random->nextInt(16) + 8; - int y = level->getHeightmap(x, z); - brownMushroomFeature->place(level, random, x, y, z); - } + if (random->nextInt(4) == 0) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + brownMushroomFeature->place(level, random, x, y, z); + } - if (random->nextInt(8) == 0) - { - int x = xo + random->nextInt(16) + 8; - int z = zo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - redMushroomFeature->place(level, random, x, y, z); - } - } + if (random->nextInt(8) == 0) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + redMushroomFeature->place(level, random, x, y, z); + } - if (random->nextInt(4) == 0) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - brownMushroomFeature->place(level, random, x, y, z); - } + for (int i = 0; i < reedsCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int z = zo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + reedsFeature->place(level, random, x, y, z); + } - if (random->nextInt(8) == 0) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - redMushroomFeature->place(level, random, x, y, z); - } + for (int i = 0; i < 10; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + reedsFeature->place(level, random, x, y, z); + } - for (int i = 0; i < reedsCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int z = zo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - reedsFeature->place(level, random, x, y, z); - } + if (random->nextInt(32) == 0) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + PumpkinFeature *pumpkinFeature = new PumpkinFeature(); + pumpkinFeature->place(level, random, x, y, z); + delete pumpkinFeature; + } - for (int i = 0; i < 10; i++) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - reedsFeature->place(level, random, x, y, z); - } + for (int i = 0; i < cactusCount; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(Level::genDepth); + int z = zo + random->nextInt(16) + 8; + cactusFeature->place(level, random, x, y, z); + } - if (random->nextInt(32) == 0) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - PumpkinFeature *pumpkinFeature = new PumpkinFeature(); - pumpkinFeature->place(level, random, x, y, z); - delete pumpkinFeature; - } + PIXEndNamedEvent(); + PIXBeginNamedEvent(0,"Decorate liquids"); - for (int i = 0; i < cactusCount; i++) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(Level::genDepth); - int z = zo + random->nextInt(16) + 8; - cactusFeature->place(level, random, x, y, z); - } + if( liquids ) + { + SpringFeature *waterSpringFeature = new SpringFeature(Tile::water_Id); + for (int i = 0; i < 50; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(random->nextInt(Level::genDepth - 8) + 8); + int z = zo + random->nextInt(16) + 8; + waterSpringFeature->place(level, random, x, y, z); + } + delete waterSpringFeature; - - PIXEndNamedEvent(); - PIXBeginNamedEvent(0,"Decorate liquids"); - - if( liquids ) - { - // 4J Stu - For some reason this was created each time round in the loop - SpringFeature *waterSpringFeature = new SpringFeature(Tile::water_Id); - for (int i = 0; i < 50; i++) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(random->nextInt(Level::genDepth - 8) + 8); - int z = zo + random->nextInt(16) + 8; - waterSpringFeature->place(level, random, x, y, z); - } - delete waterSpringFeature; - - // 4J Stu - For some reason this was created each time round in the loop - SpringFeature *lavaSpringFeature = new SpringFeature(Tile::lava_Id); - for (int i = 0; i < 20; i++) - { - int x = xo + random->nextInt(16) + 8; - int y = random->nextInt(random->nextInt(random->nextInt(Level::genDepth - 16) + 8) + 8); - int z = zo + random->nextInt(16) + 8; - lavaSpringFeature->place(level, random, x, y, z); - } - delete lavaSpringFeature; - } - PIXEndNamedEvent(); + SpringFeature *lavaSpringFeature = new SpringFeature(Tile::lava_Id); + for (int i = 0; i < 20; i++) + { + int x = xo + random->nextInt(16) + 8; + int y = random->nextInt(random->nextInt(random->nextInt(Level::genDepth - 16) + 8) + 8); + int z = zo + random->nextInt(16) + 8; + lavaSpringFeature->place(level, random, x, y, z); + } + delete lavaSpringFeature; + } + PIXEndNamedEvent(); } void BiomeDecorator::decorate(int count, Feature *feature) { - decorateDepthSpan(count, feature, 0, Level::genDepth); + decorateDepthSpan(count, feature, 0, Level::genDepth); } void BiomeDecorator::decorateDepthSpan(int count, Feature *feature, int y0, int y1) { - for (int i = 0; i < count; i++) - { - int x = xo + random->nextInt(16); - int y = random->nextInt(y1 - y0) + y0; - int z = zo + random->nextInt(16); - feature->place(level, random, x, y, z); - } + for (int i = 0; i < count; i++) + { + int x = xo + random->nextInt(16); + int y = random->nextInt(y1 - y0) + y0; + int z = zo + random->nextInt(16); + feature->place(level, random, x, y, z); + } } void BiomeDecorator::decorateDepthAverage(int count, Feature *feature, int yMid, int ySpan) { - for (int i = 0; i < count; i++) - { - int x = xo + random->nextInt(16); - int y = random->nextInt(ySpan) + random->nextInt(ySpan) + (yMid - ySpan); - int z = zo + random->nextInt(16); - feature->place(level, random, x, y, z); - } + for (int i = 0; i < count; i++) + { + int x = xo + random->nextInt(16); + int y = random->nextInt(ySpan) + random->nextInt(ySpan) + (yMid - ySpan); + int z = zo + random->nextInt(16); + feature->place(level, random, x, y, z); + } } void BiomeDecorator::decorateOres() { - level->setInstaTick(true); // 4J - optimisation - decorateDepthSpan(20, dirtOreFeature, 0, Level::genDepth); - decorateDepthSpan(10, gravelOreFeature, 0, Level::genDepth); - decorateDepthSpan(20, coalOreFeature, 0, Level::genDepth); - decorateDepthSpan(20, ironOreFeature, 0, Level::genDepth / 2); - decorateDepthSpan(2, goldOreFeature, 0, Level::genDepth / 4); - decorateDepthSpan(8, redStoneOreFeature, 0, Level::genDepth / 8); - decorateDepthSpan(1, diamondOreFeature, 0, Level::genDepth / 8); - decorateDepthAverage(1, lapisOreFeature, Level::genDepth / 8, Level::genDepth / 8); - level->setInstaTick(false); -} + level->setInstaTick(true); // 4J - optimisation + decorateDepthSpan(20, dirtOreFeature, 0, Level::genDepth); + decorateDepthSpan(10, gravelOreFeature, 0, Level::genDepth); + decorateDepthSpan(20, coalOreFeature, 0, Level::genDepth); + decorateDepthSpan(20, ironOreFeature, 0, Level::genDepth / 2); + decorateDepthSpan(2, goldOreFeature, 0, Level::genDepth / 4); + decorateDepthSpan(8, redStoneOreFeature, 0, Level::genDepth / 8); + decorateDepthSpan(1, diamondOreFeature, 0, Level::genDepth / 8); + decorateDepthAverage(1, lapisOreFeature, Level::genDepth / 8, Level::genDepth / 8); + level->setInstaTick(false); +} \ No newline at end of file diff --git a/Minecraft.World/BiomeDecorator.h b/Minecraft.World/BiomeDecorator.h index da2777e0..236fb0f7 100644 --- a/Minecraft.World/BiomeDecorator.h +++ b/Minecraft.World/BiomeDecorator.h @@ -16,7 +16,6 @@ class BiomeDecorator friend class BeachBiome; friend class SavannaBiome; friend class JungleBiome; - friend class RoofedForestBiome; friend class FlowerForestBiome; protected: Level *level; @@ -30,7 +29,7 @@ public: void decorate(Level *level, Random *random, int xo, int zo); -protected: +public: Feature *clayFeature; Feature *sandFeature; Feature *gravelFeature; @@ -54,6 +53,11 @@ protected: Feature *alliumFeature; Feature *azureBluetFeature; Feature *oxeyeDaisyFeature; + Feature *tulipRedFeature; + Feature *tulipOrangeFeature; + Feature *tulipWhiteFeature; + Feature *tulipPinkFeature; + Feature *doublePlantFeature; int waterlilyCount; int treeCount; diff --git a/Minecraft.World/BiomeInitLayer.cpp b/Minecraft.World/BiomeInitLayer.cpp index 9a78d38c..d3c88588 100644 --- a/Minecraft.World/BiomeInitLayer.cpp +++ b/Minecraft.World/BiomeInitLayer.cpp @@ -21,7 +21,7 @@ BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptrparent, LevelType } else { - startBiomes = BiomeArray(10); + startBiomes = BiomeArray(16); startBiomes[0] = Biome::desert; startBiomes[1] = Biome::forest; startBiomes[2] = Biome::extremeHills; @@ -32,6 +32,12 @@ BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptrparent, LevelType startBiomes[7] = Biome::savanna; startBiomes[8] = Biome::roofedForest; startBiomes[9] = Biome::flowerForest; + startBiomes[10] = Biome::birchForest; + startBiomes[11] = Biome::birchForestHills; + startBiomes[12] = Biome::birchForestM; + startBiomes[13] = Biome::birchForestHillsM; + startBiomes[14] = Biome::roofedForestM; + startBiomes[15] = Biome::deepOcean; } } diff --git a/Minecraft.World/BlockPos.cpp b/Minecraft.World/BlockPos.cpp new file mode 100644 index 00000000..13703c50 --- /dev/null +++ b/Minecraft.World/BlockPos.cpp @@ -0,0 +1,188 @@ +#include "stdafx.h" +#include "BlockPos.h" +#include "Entity.h" +#include "Direction.h" +#include "BlockSource.h" +#include +#include + +const BlockPos BlockPos::ZERO = BlockPos(0, 0, 0); + +// Costruttori +BlockPos::BlockPos() : Vec3i(0, 0, 0) {} + +BlockPos::BlockPos(int x, int y, int z) : Vec3i(x, y, z) {} + +BlockPos::BlockPos(double x, double y, double z) + : Vec3i((int)std::floor(x), (int)std::floor(y), (int)std::floor(z)) {} + +BlockPos::BlockPos(const std::shared_ptr& entity) : Vec3i(0, 0, 0) { + if (entity) { + x = (int)std::floor(entity->x); + y = (int)std::floor(entity->y); + z = (int)std::floor(entity->z); + } +} + +BlockPos::BlockPos(const double* pos) + : Vec3i((int)std::floor(pos[0]), (int)std::floor(pos[1]), (int)std::floor(pos[2])) {} + +BlockPos::BlockPos(const double* pos, bool fromEntity) : Vec3i(0, 0, 0) { + if (fromEntity) { + x = (int)std::floor(pos[10]); + y = (int)std::floor(pos[11]); + z = (int)std::floor(pos[12]); + } else { + x = (int)std::floor(pos[0]); + y = (int)std::floor(pos[1]); + z = (int)std::floor(pos[2]); + } +} + +BlockPos::BlockPos(const Vec3i& other) + : Vec3i(other.getX(), other.getY(), other.getZ()) {} + +BlockPos::BlockPos(int compressed) : Vec3i(0, 0, 0) { + *this = decompress(compressed); +} + +BlockPos::BlockPos(BlockSource& source) + : Vec3i(source.getBlockX(), source.getBlockY(), source.getBlockZ()) {} + +// Metodi di confronto +bool BlockPos::equals(const BlockPos& other) const { + return x == other.x && y == other.y && z == other.z; +} + +bool BlockPos::equals(int x, int y, int z) const { + return this->x == x && this->y == y && this->z == z; +} + +int BlockPos::hashCode() const { + int result = 0x1F * (y + 0x1F * z); + return result + x; +} + +// Offset +BlockPos BlockPos::offset(int dx, int dy, int dz) const { + return BlockPos(x + dx, y + dy, z + dz); +} + +BlockPos BlockPos::offset(double dx, double dy, double dz) const { + return BlockPos(x + dx, y + dy, z + dz); +} + +BlockPos BlockPos::offset(const BlockPos& delta) const { + return BlockPos(x + delta.x, y + delta.y, z + delta.z); +} + +BlockPos BlockPos::relative(int direction, int distance) const { + int dx = 0, dz = 0; + switch (direction) { + case Direction::NORTH: dz = -distance; break; + case Direction::SOUTH: dz = distance; break; + case Direction::WEST: dx = -distance; break; + case Direction::EAST: dx = distance; break; + default: break; + } + return BlockPos(x + dx, y, z + dz); +} + +// Metodi direzionali +BlockPos BlockPos::above(int distance) const { + return BlockPos(x, y + distance, z); +} + +BlockPos BlockPos::below(int distance) const { + return BlockPos(x, y - distance, z); +} + +BlockPos BlockPos::north(int distance) const { + return relative(Direction::NORTH, distance); +} + +BlockPos BlockPos::south(int distance) const { + return relative(Direction::SOUTH, distance); +} + +BlockPos BlockPos::east(int distance) const { + return relative(Direction::EAST, distance); +} + +BlockPos BlockPos::west(int distance) const { + return relative(Direction::WEST, distance); +} + +BlockPos BlockPos::multiply(int factor) const { + if (factor == 0) return ZERO; + if (factor == 1) return *this; + return BlockPos(x * factor, y * factor, z * factor); +} + +// Compressione +int BlockPos::compress() const { + static const int MASK_X = (1 << BITS_X) - 1; + static const int MASK_Y = (1 << BITS_Y) - 1; + static const int MASK_Z = (1 << BITS_Z) - 1; + static const int SHIFT_Z = 0; + static const int SHIFT_Y = BITS_Z; + static const int SHIFT_X = BITS_Z + BITS_Y; + + int cx = x & MASK_X; + int cy = y & MASK_Y; + int cz = z & MASK_Z; + + return (cx << SHIFT_X) | (cy << SHIFT_Y) | (cz << SHIFT_Z); +} + +BlockPos BlockPos::decompress(int compressed) { + static const int MASK_X = (1 << BITS_X) - 1; + static const int MASK_Y = (1 << BITS_Y) - 1; + static const int MASK_Z = (1 << BITS_Z) - 1; + static const int SHIFT_Z = 0; + static const int SHIFT_Y = BITS_Z; + static const int SHIFT_X = BITS_Z + BITS_Y; + + int x = (compressed >> SHIFT_X) & MASK_X; + int y = (compressed >> SHIFT_Y) & MASK_Y; + int z = (compressed >> SHIFT_Z) & MASK_Z; + + if (x & (1 << (BITS_X - 1))) x |= ~MASK_X; + if (y & (1 << (BITS_Y - 1))) y |= ~MASK_Y; + if (z & (1 << (BITS_Z - 1))) z |= ~MASK_Z; + + return BlockPos(x, y, z); +} + + +BlockPos BlockPos::operator+(const BlockPos& other) const { + return BlockPos(x + other.x, y + other.y, z + other.z); +} + +BlockPos BlockPos::operator-(const BlockPos& other) const { + return BlockPos(x - other.x, y - other.y, z - other.z); +} + +BlockPos BlockPos::operator*(int scalar) const { + return multiply(scalar); +} + +BlockPos& BlockPos::operator+=(const BlockPos& other) { + x += other.x; + y += other.y; + z += other.z; + return *this; +} + +BlockPos& BlockPos::operator-=(const BlockPos& other) { + x -= other.x; + y -= other.y; + z -= other.z; + return *this; +} + +std::string BlockPos::toString() const { + std::ostringstream oss; + oss << "(" << x << ", " << y << ", " << z << ")"; + return oss.str(); +} \ No newline at end of file diff --git a/Minecraft.World/BlockPos.h b/Minecraft.World/BlockPos.h new file mode 100644 index 00000000..48d522f0 --- /dev/null +++ b/Minecraft.World/BlockPos.h @@ -0,0 +1,65 @@ +#pragma once +#include "Vec3i.h" +#include +#include + +class Entity; +class BlockSource; + +class BlockPos : public Vec3i { +public: + BlockPos(); + BlockPos(int x, int y, int z); + BlockPos(double x, double y, double z); + explicit BlockPos(const std::shared_ptr& entity); + explicit BlockPos(const double* pos); + BlockPos(const double* pos, bool fromEntity); + explicit BlockPos(const Vec3i& other); + explicit BlockPos(int compressed); + explicit BlockPos(BlockSource& source); + + int getX() const { return x; } + int getY() const { return y; } + int getZ() const { return z; } + + void set(int x, int y, int z) { this->x = x; this->y = y; this->z = z; } + void set(const BlockPos& other) { x = other.x; y = other.y; z = other.z; } + + bool equals(const BlockPos& other) const; + bool equals(int x, int y, int z) const; + bool operator==(const BlockPos& other) const { return equals(other); } + bool operator!=(const BlockPos& other) const { return !equals(other); } + + int hashCode() const; + + BlockPos offset(int dx, int dy, int dz) const; + BlockPos offset(double dx, double dy, double dz) const; + BlockPos offset(const BlockPos& delta) const; + BlockPos relative(int direction, int distance = 1) const; + + BlockPos above(int distance = 1) const; + BlockPos below(int distance = 1) const; + BlockPos north(int distance = 1) const; + BlockPos south(int distance = 1) const; + BlockPos east(int distance = 1) const; + BlockPos west(int distance = 1) const; + + BlockPos multiply(int factor) const; + + int compress() const; + static BlockPos decompress(int compressed); + + BlockPos operator+(const BlockPos& other) const; + BlockPos operator-(const BlockPos& other) const; + BlockPos operator*(int scalar) const; + BlockPos& operator+=(const BlockPos& other); + BlockPos& operator-=(const BlockPos& other); + + bool isZero() const { return x == 0 && y == 0 && z == 0; } + std::string toString() const; + + static const BlockPos ZERO; + static const int BITS_X = 26; + static const int BITS_Y = 12; + static const int BITS_Z = 26; +}; \ No newline at end of file diff --git a/Minecraft.World/ChunkPrimer.cpp b/Minecraft.World/ChunkPrimer.cpp new file mode 100644 index 00000000..5443c448 --- /dev/null +++ b/Minecraft.World/ChunkPrimer.cpp @@ -0,0 +1,105 @@ +#include "stdafx.h" +#include "ChunkPrimer.h" +#include "Tile.h" // for Tile::air (or your air tile) + + +ChunkPrimer::ChunkPrimer() +{ + m_blockIds = new byte[65536]; + m_blockData = new byte[32768]; + memset(m_blockIds, 0, 65536); + memset(m_blockData, 0, 32768); + m_airBlockId = 0; // adjust if your air tile has a different ID +} + +ChunkPrimer::~ChunkPrimer() +{ + delete[] m_blockIds; + delete[] m_blockData; +} + +int ChunkPrimer::getIndex(int x, int y, int z) +{ + // Match the indexing used in the decompiled code: (x << 12) | (z << 8) | y + return (x << 12) | (z << 8) | y; +} + +void ChunkPrimer::setBlockAndData(int packedPos, int blockId, int data) +{ + if (packedPos < 0 || packedPos >= 65536) + { + // Handle error (log, assert, etc.) + return; + } + m_blockIds[packedPos] = static_cast(blockId); + int byteIdx = packedPos >> 1; + if (packedPos & 1) + m_blockData[byteIdx] = (m_blockData[byteIdx] & 0x0F) | ((data & 0x0F) << 4); + else + m_blockData[byteIdx] = (m_blockData[byteIdx] & 0xF0) | (data & 0x0F); +} + +int ChunkPrimer::getState(int packedPos) const +{ + if (packedPos < 0 || packedPos >= 65536) + return 0; // air + int id = m_blockIds[packedPos]; + int byteIdx = packedPos >> 1; + int data; + if (packedPos & 1) + data = (m_blockData[byteIdx] >> 4) & 0x0F; + else + data = m_blockData[byteIdx] & 0x0F; + // Return a packed state (can be used in place of BlockState* for material checks) + return (id << 4) | data; +} + +int ChunkPrimer::getBlockId(int packedPos) const +{ + if (packedPos < 0 || packedPos >= 65536) + return 0; + return m_blockIds[packedPos]; +} + +int ChunkPrimer::getBlockData(int packedPos) const +{ + if (packedPos < 0 || packedPos >= 65536) + return 0; + int byteIdx = packedPos >> 1; + if (packedPos & 1) + return (m_blockData[byteIdx] >> 4) & 0x0F; + else + return m_blockData[byteIdx] & 0x0F; +} + +int ChunkPrimer::getHighestNonAirPos(int x, int z) const +{ + // We iterate from top (y=127) down to 0, checking the block ID. + // The decompiled code uses: (x << 11) | (z << 7) | 1 + y + 126? + // In the decompiled version, they had: + // base = (x << 11) | (z << 7) | 1; + // for (int y = 127; y >= 0; y--) + // if (Block::byId(m_blockIds[base + y + 126]) != Blocks::AIR) + // return y; + // We'll use the same indexing: linear index = (x << 12) | (z << 8) | y. + // To find the topmost non‑air block for given x,z, we need to check all y. + // We can compute the base offset for this column: (x << 12) | (z << 8) + int base = (x << 12) | (z << 8); + for (int y = 127; y >= 0; --y) + { + int idx = base | y; + if (m_blockIds[idx] != m_airBlockId) + return y; + } + return 0; +} + +void ChunkPrimer::setBlockAndData(int x, int y, int z, int blockId, int data) +{ + setBlockAndData(getIndex(x, y, z), blockId, data); +} + +int ChunkPrimer::getState(int x, int y, int z) const +{ + return getState(getIndex(x, y, z)); +} \ No newline at end of file diff --git a/Minecraft.World/ChunkPrimer.h b/Minecraft.World/ChunkPrimer.h new file mode 100644 index 00000000..170716b7 --- /dev/null +++ b/Minecraft.World/ChunkPrimer.h @@ -0,0 +1,42 @@ +#pragma once + +#include "stdafx.h" + +class ChunkPrimer +{ +public: + + ChunkPrimer(); + ~ChunkPrimer(); + + + void setBlockAndData(int packedPos, int blockId, int data); + + + int getState(int packedPos) const; + + + int getBlockId(int packedPos) const; + + + int getBlockData(int packedPos) const; + + + int getHighestNonAirPos(int x, int z) const; + + + byte* getBlockIds() const { return m_blockIds; } + byte* getBlockData() const { return m_blockData; } + + + void setBlockAndData(int x, int y, int z, int blockId, int data); + int getState(int x, int y, int z) const; + +private: + + static int getIndex(int x, int y, int z); + + byte* m_blockIds; + byte* m_blockData; + int m_airBlockId; +}; \ No newline at end of file diff --git a/Minecraft.World/DarkOakFeature.cpp b/Minecraft.World/DarkOakFeature.cpp deleted file mode 100644 index c61a050c..00000000 --- a/Minecraft.World/DarkOakFeature.cpp +++ /dev/null @@ -1,189 +0,0 @@ -#include "stdafx.h" -#include "DarkOakFeature.h" -#include "net.minecraft.world.level.h" -#include "net.minecraft.world.level.tile.h" -#include "TreeTile2.h" -#include "LeafTile2.h" -#include -#include - -DarkOakFeature::DarkOakFeature(bool doUpdate) : Feature(doUpdate) { - -} - -bool DarkOakFeature::place(Level *level, Random *rand, int x, int y, int z) { - int treeHeight = rand->nextInt(3) + rand->nextInt(2) + 6; - int startX = x; - int startY = y; - int startZ = z; - - if (startY >= 1 && startY + treeHeight + 1 < Level::maxBuildHeight) { - int belowTile = level->getTile(startX, startY - 1, startZ); - bool isSoil = (belowTile == Tile::grass_Id || belowTile == Tile::dirt_Id); - - if (!(isSoil && startY < Level::maxBuildHeight - treeHeight - 1)) { - return false; - } else if (!this->checkSpace(level, startX, startY, startZ, treeHeight)) { - return false; - } else { - - if(app.getLevelGenerationOptions() != nullptr) - { - LevelGenerationOptions *levelGenOptions = app.getLevelGenerationOptions(); - int radius = 4; - bool intersects = levelGenOptions->checkIntersects(x - radius, y - 1, z - radius, x + radius + 1, y + treeHeight, z + radius + 1); - if(intersects) - { - return false; - } - } - - - placeBlock(level, startX, startY - 1, startZ, Tile::dirt_Id); - placeBlock(level, startX + 1, startY - 1, startZ, Tile::dirt_Id); - placeBlock(level, startX, startY - 1, startZ + 1, Tile::dirt_Id); - placeBlock(level, startX + 1, startY - 1, startZ + 1, Tile::dirt_Id); - - - int face = rand->nextInt(4); // Direzione: 0=N, 1=E, 2=S, 3=W - int dx = 0; - int dz = 0; - if (face == 0) dz = -1; - else if (face == 1) dx = 1; - else if (face == 2) dz = 1; - else if (face == 3) dx = -1; - - int bendHeight = treeHeight - rand->nextInt(4); - int bendLength = 2 - rand->nextInt(3); - int trunkX = startX; - int trunkZ = startZ; - int topY = startY + treeHeight - 1; - - - for (int j2 = 0; j2 < treeHeight; ++j2) { - - if (j2 >= bendHeight && bendLength > 0) { - trunkX += dx; - trunkZ += dz; - --bendLength; - } - - int currentY = startY + j2; - this->placeLog(level, trunkX, currentY, trunkZ); - this->placeLog(level, trunkX + 1, currentY, trunkZ); - this->placeLog(level, trunkX, currentY, trunkZ + 1); - this->placeLog(level, trunkX + 1, currentY, trunkZ + 1); - } - - - for (int i3 = -2; i3 <= 0; ++i3) { - for (int l3 = -2; l3 <= 0; ++l3) { - int k4 = -1; - this->placeLeaf(level, trunkX + i3, topY + k4, trunkZ + l3); - this->placeLeaf(level, 1 + trunkX - i3, topY + k4, trunkZ + l3); - this->placeLeaf(level, trunkX + i3, topY + k4, 1 + trunkZ - l3); - this->placeLeaf(level, 1 + trunkX - i3, topY + k4, 1 + trunkZ - l3); - - if ((i3 > -2 || l3 > -1) && (i3 != -1 || l3 != -2)) { - k4 = 1; - this->placeLeaf(level, trunkX + i3, topY + k4, trunkZ + l3); - this->placeLeaf(level, 1 + trunkX - i3, topY + k4, trunkZ + l3); - this->placeLeaf(level, trunkX + i3, topY + k4, 1 + trunkZ - l3); - this->placeLeaf(level, 1 + trunkX - i3, topY + k4, 1 + trunkZ - l3); - } - } - } - - - if (rand->nextInt(2) == 0) { - this->placeLeaf(level, trunkX, topY + 2, trunkZ); - this->placeLeaf(level, trunkX + 1, topY + 2, trunkZ); - this->placeLeaf(level, trunkX + 1, topY + 2, trunkZ + 1); - this->placeLeaf(level, trunkX, topY + 2, trunkZ + 1); - } - - - for (int j3 = -3; j3 <= 4; ++j3) { - for (int i4 = -3; i4 <= 4; ++i4) { - if ((j3 != -3 || i4 != -3) && (j3 != -3 || i4 != 4) && (j3 != 4 || i4 != -3) && (j3 != 4 || i4 != 4) && (std::abs(j3) < 3 || std::abs(i4) < 3)) { - this->placeLeaf(level, trunkX + j3, topY, trunkZ + i4); - } - } - } - - - for (int k3 = -1; k3 <= 2; ++k3) { - for (int j4 = -1; j4 <= 2; ++j4) { - if ((k3 < 0 || k3 > 1 || j4 < 0 || j4 > 1) && rand->nextInt(3) <= 0) { - int l4 = rand->nextInt(3) + 2; - - - for (int i5 = 0; i5 < l4; ++i5) { - this->placeLog(level, startX + k3, topY - i5 - 1, startZ + j4); - } - - - for (int j5 = -1; j5 <= 1; ++j5) { - for (int l2 = -1; l2 <= 1; ++l2) { - this->placeLeaf(level, trunkX + k3 + j5, topY, trunkZ + j4 + l2); - } - } - - for (int k5 = -2; k5 <= 2; ++k5) { - for (int l5 = -2; l5 <= 2; ++l5) { - if (std::abs(k5) != 2 || std::abs(l5) != 2) { - this->placeLeaf(level, trunkX + k3 + k5, topY - 1, trunkZ + j4 + l5); - } - } - } - } - } - } - - return true; - } - } - return false; -} - -bool DarkOakFeature::checkSpace(Level *worldIn, int x, int y, int z, int height) { - for (int l = 0; l <= height + 1; ++l) { - int i1 = 1; - if (l == 0) i1 = 0; - if (l >= height - 1) i1 = 2; - - for (int j1 = -i1; j1 <= i1; ++j1) { - for (int k1 = -i1; k1 <= i1; ++k1) { - if (l == 0 && j1 == 0 && k1 == 0) continue; - - int tile = worldIn->getTile(x + j1, y + l, z + k1); - - if (tile != 0 && - tile != Tile::leaves_Id && tile != Tile::leaves2_Id && - tile != Tile::tallgrass_Id && tile != Tile::sapling_Id && - tile != Tile::grass_Id && tile != Tile::dirt_Id && - tile != Tile::treeTrunk_Id && tile != Tile::tree2Trunk_Id) { - return false; - } - - if (tile == Tile::water_Id) return false; - } - } - } - return true; -} - -void DarkOakFeature::placeLog(Level *worldIn, int x, int y, int z) { - int tile = worldIn->getTile(x, y, z); - if (tile == 0 || tile == Tile::leaves_Id || tile == Tile::leaves2_Id || tile == Tile::tallgrass_Id) { - placeBlock(worldIn, x, y, z, Tile::tree2Trunk_Id, TreeTile2::DARK_TRUNK); - } -} - -void DarkOakFeature::placeLeaf(Level *worldIn, int x, int y, int z) { - int tile = worldIn->getTile(x, y, z); - if (tile == 0) { - - placeBlock(worldIn, x, y, z, Tile::leaves2_Id, 1); - } -} \ No newline at end of file diff --git a/Minecraft.World/Direction.h b/Minecraft.World/Direction.h index 61c6ef58..587bb653 100644 --- a/Minecraft.World/Direction.h +++ b/Minecraft.World/Direction.h @@ -34,4 +34,24 @@ public: static int getDirection(double xd, double zd); static int getDirection(int x0, int z0, int x1, int z1); + + static int getStepX(int direction) { + switch (direction) { + case WEST: return -1; + case EAST: return 1; + default: return 0; + } + } + + static int getStepZ(int direction) { + switch (direction) { + case NORTH: return -1; + case SOUTH: return 1; + default: return 0; + } + } + static int getStepY(int direction) { + + return 0; + } }; \ No newline at end of file diff --git a/Minecraft.World/DoublePlantFeature.cpp b/Minecraft.World/DoublePlantFeature.cpp new file mode 100644 index 00000000..88138d3b --- /dev/null +++ b/Minecraft.World/DoublePlantFeature.cpp @@ -0,0 +1,43 @@ +#include "stdafx.h" +#include "DoublePlantFeature.h" +#include "net.minecraft.world.level.h" +#include "net.minecraft.world.level.tile.h" +#include "TallGrass2.h" + +DoublePlantFeature::DoublePlantFeature(bool doUpdate) + : Feature(doUpdate), m_plantType(0) +{ +} + +void DoublePlantFeature::setPlantType(int plantType) +{ + m_plantType = plantType; +} + +bool DoublePlantFeature::place(Level* level, Random* rand, int x, int y, int z) +{ + bool placed = false; + + for (int i = 0; i < 64; ++i) + { + int bx = x + rand->nextInt(8) - rand->nextInt(8); + int by = y + rand->nextInt(4) - rand->nextInt(4); + int bz = z + rand->nextInt(8) - rand->nextInt(8); + + if (by >= Level::maxBuildHeight - 1) continue; + if (by < 1) continue; + + if (level->getTile(bx, by, bz) != 0) continue; + if (level->getTile(bx, by + 1, bz) != 0) continue; + + + if (!static_cast(Tile::tiles[Tile::tallgrass2_Id])->mayPlace(level, bx, by, bz)) continue; + + level->setTileAndData(bx, by, bz, Tile::tallgrass2_Id, m_plantType, Tile::UPDATE_ALL); + level->setTileAndData(bx, by + 1, bz, Tile::tallgrass2_Id, m_plantType | TallGrass2::UPPER_BIT, Tile::UPDATE_ALL); + + placed = true; + } + + return placed; +} \ No newline at end of file diff --git a/Minecraft.World/DoublePlantFeature.h b/Minecraft.World/DoublePlantFeature.h new file mode 100644 index 00000000..dd02ff62 --- /dev/null +++ b/Minecraft.World/DoublePlantFeature.h @@ -0,0 +1,16 @@ +#pragma once +#include "Feature.h" + +class Level; +class Random; + +class DoublePlantFeature : public Feature +{ +private: + int m_plantType; + +public: + DoublePlantFeature(bool doUpdate = false); + void setPlantType(int plantType); + bool place(Level* level, Random* rand, int x, int y, int z); +}; \ No newline at end of file diff --git a/Minecraft.World/ForestBiome.cpp b/Minecraft.World/ForestBiome.cpp index 56c68622..8694ffb7 100644 --- a/Minecraft.World/ForestBiome.cpp +++ b/Minecraft.World/ForestBiome.cpp @@ -1,85 +1,298 @@ #include "stdafx.h" #include "ForestBiome.h" -#include "net.minecraft.world.level.levelgen.feature.h" -#include "net.minecraft.world.level.biome.h" -#include "DarkOakFeature.h" +#include "BiomeDecorator.h" +#include "TreeFeature.h" +#include "BirchFeature.h" +#include "FlowerFeature.h" +#include "RoofTreeFeature.h" +#include "Tile.h" +#include "Rose.h" +#include "HugeMushroomFeature.h" +#include "DoublePlantFeature.h" +#include "../Minecraft.Client/Minecraft.h" +#include "../Minecraft.Client/Common/Colours/ColourTable.h" +#include "Level.h" +#include "Random.h" +#include "BlockPos.h" +#include "PerlinNoise.h" -ForestBiome::ForestBiome(int id, int type) : Biome(id) +static const int LEAF_COLOR_NORMAL = 0x4EBA31; +static const int LEAF_COLOR_MUTATED = 0x7DA225; +static const int WATER_COLOR_NORMAL = 0x307444; +static const int SKY_COLOR_NORMAL = 0x56621; +static const int SKY_COLOR_BIRCH_ALT = 0x23310; +static const float TEMP_NORMAL = 0.7f; +static const float DOWNFALL_NORMAL = 0.8f; +static const float TEMP_BIRCH = 0.6f; +static const float DOWNFALL_BIRCH = 0.6f; + +ForestBiome::ForestBiome(int id, int type) + : Biome(id), biomeType(type) { - this->biomeType = type; - - this->setLeafColor(0x4EBA31); - this->setTemperatureAndDownfall(0.7f, 0.8f); + setLeafColor((eMinecraftColour)LEAF_COLOR_NORMAL); + setTemperatureAndDownfall(TEMP_NORMAL, DOWNFALL_NORMAL); - if (this->biomeType == 1) //flowerforest + if (type == 1) // flower forest { - this->decorator->treeCount = 10; - this->decorator->grassCount = 2; - this->decorator->flowerCount = 100; - this->decorator->alliumCount = 2; - this->decorator->azureBluetCount = 2; - this->decorator->oxeyeDaisyCount = 2; - this->decorator->blueOrchidCount = 0; - this->setTemperatureAndDownfall(0.6f, 0.6f); + decorator->treeCount = 6; + decorator->grassCount = 1; + decorator->flowerCount = 100; + friendlies.push_back(new MobSpawnerData(eTYPE_RABBIT, 4, 2, 3)); } - else if (this->biomeType == 2) //birchforest + else { - this->decorator->treeCount = 10; - this->decorator->grassCount = 2; - } - else if (this->biomeType == 3) //roofedforest - { - - this->decorator->treeCount = 50; - this->decorator->grassCount = 2; - this->decorator->flowerCount = 1; - this->decorator->hugeMushrooms = 2; - } - else - { - this->decorator->treeCount = 6; - this->decorator->flowerCount = 4; - this->decorator->grassCount = 1; - - MobSpawnerData* wolfSpawn = new MobSpawnerData(eTYPE_WOLF, 5, 4, 4); - this->friendlies.push_back(wolfSpawn); + decorator->grassCount = 2; + decorator->treeCount = 10; } - if (this->biomeType == 0) + if (type == 2) // birch forest { - MobSpawnerData* rabbitSpawn = new MobSpawnerData(eTYPE_RABBIT, 4, 2, 3); - this->friendlies.push_back(rabbitSpawn); + m_waterColor = (eMinecraftColour)WATER_COLOR_NORMAL; + m_skyColor = (eMinecraftColour)SKY_COLOR_NORMAL; + setTemperatureAndDownfall(TEMP_BIRCH, DOWNFALL_BIRCH); + } + else if (type == 0) // normale + { + enemies.push_back(new MobSpawnerData(eTYPE_WOLF, 5, 4, 4)); + } + else if (type == 3) // roofed forest + { + decorator->hugeMushrooms = 2; } } +ForestBiome::~ForestBiome() {} + Feature* ForestBiome::getTreeFeature(Random* random) { - if (this->biomeType == 3) // Roofed Forest + if (biomeType == 3) { - if (random->nextInt(3) > 0) + return new RoofTreeFeature(false); + } + if (biomeType == 2 || random->nextInt(5) == 0) + return new BirchFeature(false, false); + return new TreeFeature(false); +} + +Biome* ForestBiome::setColor(int color, bool b) +{ + if (biomeType != 2) + return Biome::setColor(color, b); + + m_waterColor = (eMinecraftColour)color; + m_skyColor = (eMinecraftColour)(b ? SKY_COLOR_BIRCH_ALT : SKY_COLOR_NORMAL); + return this; +} + +int ForestBiome::getRandomFlower(Random* rand, const BlockPos& pos) const +{ + if (biomeType == 1) + { + double noise = m_temperatureNoise->getValue(pos.getX() / 48.0, pos.getZ() / 48.0); + double t = (noise + 1.0) * 0.5; + if (t < 0.0) t = 0.0; + if (t > 0.9999) t = 0.9999; + int idx = (int)(t * 10.0); + + static const int FLOWER_COLORS[10] = { 0,1,2,3,4,5,6,7,8,9 }; + int color = FLOWER_COLORS[idx]; + return color; + } + return 0; +} + +void ForestBiome::decorate(Level* level, Random* rand, int xo, int zo) +{ + BlockPos pos(xo, 0, zo); + + if (biomeType == 3) + { + for (int i = 0; i < 4; ++i) { - return new DarkOakFeature(false); + int baseX = 9 + i * 4; + int y = 13; + for (int j = 0; j < 2; ++j) + { + + int dx = baseX + rand->nextInt(3); + int dz = y - 4 + rand->nextInt(3); + BlockPos treePos = pos.offset(dx, 0, dz); + + + int highestY = level->getHeightmap(treePos.getX(), treePos.getZ()); + treePos = BlockPos(treePos.getX(), highestY, treePos.getZ()); + + if (rand->nextInt(20) == 0) + { + HugeMushroomFeature mushroom; + mushroom.place(level, rand, treePos.getX(), treePos.getY(), treePos.getZ()); + } + else + { + Feature* tree = getTreeFeature(rand); + if (tree) + { + tree->place(level, rand, treePos.getX(), treePos.getY(), treePos.getZ()); + delete tree; + } + } + + + dx = baseX + rand->nextInt(3); + dz = y + rand->nextInt(3); + treePos = pos.offset(dx, 0, dz); + + + highestY = level->getHeightmap(treePos.getX(), treePos.getZ()); + treePos = BlockPos(treePos.getX(), highestY, treePos.getZ()); + + if (rand->nextInt(20) == 0) + { + HugeMushroomFeature mushroom; + mushroom.place(level, rand, treePos.getX(), treePos.getY(), treePos.getZ()); + } + else + { + Feature* tree = getTreeFeature(rand); + if (tree) + { + tree->place(level, rand, treePos.getX(), treePos.getY(), treePos.getZ()); + delete tree; + } + } + y += 8; + } } } + + + int count = rand->nextInt(5) - 3; + if (biomeType == 1) count += 2; + + if (count > 0) + { + do + { + int plantType = rand->nextInt(3); + DoublePlantFeature plantFeature; + + for (int attempts = 2; attempts >= 0; --attempts) + { + int dx = rand->nextInt(16) + 8; + int dz = rand->nextInt(16) + 8; + BlockPos plantPos = pos.offset(dx, 0, dz); + + + int highestY = level->getHeightmap(plantPos.getX(), plantPos.getZ()); + plantPos = BlockPos(plantPos.getX(), highestY, plantPos.getZ()); + + int plantY = rand->nextInt(plantPos.getY() + 32); + BlockPos finalPos(plantPos.getX(), plantY, plantPos.getZ()); + + if (plantFeature.place(level, rand, finalPos.getX(), finalPos.getY(), finalPos.getZ())) + { + break; + } + } + --count; + } while (count > 0); + } + + Biome::decorate(level, rand, xo, zo); +} + +unsigned int ForestBiome::getGrassColor(const BlockPos& pos) const +{ + unsigned int base = Biome::getGrassColor(); + if (biomeType == 3) + { + ColourTable* table = Minecraft::GetInstance()->getColourTable(); + if (table) + { + unsigned int color2 = table->getColour(eMinecraftColour_Grass_Forest); + return ((base & 0xFEFEFE) + (color2 & 0xFEFEFE)) >> 1; + } + } + return base; +} + +Biome* ForestBiome::createMutatedCopy(int id) const +{ + ForestBiome* copy = new ForestBiome(id, 1); + copy->setDepthAndScale(depth, scale + 0.2f); + copy->setName(L"Forest Mutated"); - if (this->biomeType == 2 || random->nextInt(5) == 0) - { - return new BirchFeature(false, false); - } - - - return new TreeFeature(false); + copy->setLeafColor((eMinecraftColour)LEAF_COLOR_MUTATED); + return copy; } -Biome* ForestBiome::setColor(int color, bool b) +// MutatedBirchForestBiome +ForestBiome::MutatedBirchForestBiome::MutatedBirchForestBiome(int id, Biome* baseBiome) + : MutatedBiome(id, baseBiome) {} + +ForestBiome::MutatedBirchForestBiome::~MutatedBirchForestBiome() {} + +Feature* ForestBiome::MutatedBirchForestBiome::getTreeFeature(Random* random) { - - Biome::setColor(color, b); + if (random->nextBoolean()) + return new BirchFeature(false, true); + else + return new BirchFeature(false, false); +} + + +// MutatedForestBiome +ForestBiome::MutatedForestBiome::MutatedForestBiome(int id, Biome* baseBiome) + : MutatedBiome(id, baseBiome) {} + +ForestBiome::MutatedForestBiome::~MutatedForestBiome() {} + +void ForestBiome::MutatedForestBiome::decorate(Level* level, Random* rand, int xo, int zo) +{ + if (m_baseBiome) + m_baseBiome->decorate(level, rand, xo, zo); +} + +Feature* ForestBiome::getFlowerFeature(Random* random, int x, int y, int z) +{ + if (biomeType == 1) // Flower Forest + { + + int fType = random->nextInt(9); + switch (fType) { + case 0: return new FlowerFeature(Tile::flower_Id, 0); + case 1: return new FlowerFeature(Tile::rose_Id, 0); + case 2: return new FlowerFeature(Tile::rose_Id, Rose::ALLIUM); + case 3: return new FlowerFeature(Tile::rose_Id, Rose::AZURE_BLUET); + case 4: return new FlowerFeature(Tile::rose_Id, Rose::RED_TULIP); + case 5: return new FlowerFeature(Tile::rose_Id, Rose::ORANGE_TULIP); + case 6: return new FlowerFeature(Tile::rose_Id, Rose::WHITE_TULIP); + case 7: return new FlowerFeature(Tile::rose_Id, Rose::PINK_TULIP); + case 8: return new FlowerFeature(Tile::rose_Id, Rose::OXEYE_DAISY); + } + } + else if (biomeType == 2 || biomeType == 3) + { + + return nullptr; + } + + + return Biome::getFlowerFeature(random, x, y, z); +} + +int ForestBiome::getRandomDoublePlantType(Random* random) +{ + if (biomeType == 1 || biomeType == 2 || biomeType == 3) + { + + return random->nextInt(3) + 2; + } - return this; + return Biome::getRandomDoublePlantType(random); } \ No newline at end of file diff --git a/Minecraft.World/ForestBiome.h b/Minecraft.World/ForestBiome.h index ce0f6007..51bacc68 100644 --- a/Minecraft.World/ForestBiome.h +++ b/Minecraft.World/ForestBiome.h @@ -1,16 +1,46 @@ #pragma once + #include "Biome.h" +#include "MutatedBiome.h" +#include "BlockPos.h" class ForestBiome : public Biome { +public: + ForestBiome(int id, int type = 0); + virtual ~ForestBiome(); + + virtual Feature* getTreeFeature(Random* random) override; + virtual Biome* setColor(int color, bool b = false) override; + virtual int getRandomFlower(Random* rand, const BlockPos& pos) const; + virtual void decorate(Level* level, Random* rand, int xo, int zo) override; + virtual unsigned int getGrassColor(const BlockPos& pos) const; + + virtual Feature* getFlowerFeature(Random* random, int x, int y, int z) override; + virtual int getRandomDoublePlantType(Random* random) override; + + virtual Biome* createMutatedCopy(int id) const; + + class MutatedBirchForestBiome : public MutatedBiome + { + public: + + MutatedBirchForestBiome(int id, Biome* baseBiome); + virtual ~MutatedBirchForestBiome(); + + virtual Feature* getTreeFeature(Random* random) override; + }; + + class MutatedForestBiome : public MutatedBiome + { + public: + // Rimosso 'const' + MutatedForestBiome(int id, Biome* baseBiome); + virtual ~MutatedForestBiome(); + + virtual void decorate(Level* level, Random* rand, int xo, int zo) override; + }; + private: int biomeType; - -public: - ForestBiome(int id, int type = 0); - - virtual Feature *getTreeFeature(Random *random) override; - - - virtual Biome *setColor(int color, bool b = false) override; }; \ No newline at end of file diff --git a/Minecraft.World/Minecraft.World.vcxproj b/Minecraft.World/Minecraft.World.vcxproj index e0017d26..175a5f7c 100644 --- a/Minecraft.World/Minecraft.World.vcxproj +++ b/Minecraft.World/Minecraft.World.vcxproj @@ -2449,6 +2449,7 @@ + @@ -2461,12 +2462,15 @@ + - + + + @@ -2718,7 +2722,6 @@ - @@ -3540,6 +3543,7 @@ + @@ -3550,12 +3554,15 @@ + - + + + @@ -3662,7 +3669,6 @@ - diff --git a/Minecraft.World/Minecraft.World.vcxproj.filters b/Minecraft.World/Minecraft.World.vcxproj.filters index 153933c0..c7c0a073 100644 --- a/Minecraft.World/Minecraft.World.vcxproj.filters +++ b/Minecraft.World/Minecraft.World.vcxproj.filters @@ -822,14 +822,17 @@ - + - + + + + @@ -1821,14 +1824,17 @@ - + - + + + + diff --git a/Minecraft.World/MutatedBiome.cpp b/Minecraft.World/MutatedBiome.cpp new file mode 100644 index 00000000..31a24f1f --- /dev/null +++ b/Minecraft.World/MutatedBiome.cpp @@ -0,0 +1,84 @@ +#include "stdafx.h" +#include "MutatedBiome.h" +#include "BiomeDecorator.h" +#include "Level.h" +#include "Random.h" +#include "ChunkPrimer.h" + +MutatedBiome::MutatedBiome(int id, Biome* baseBiome) + : Biome(id), m_baseBiome(baseBiome) +{ + if (!baseBiome) return; + + color = baseBiome->color; + topMaterial = baseBiome->topMaterial; + material = baseBiome->material; + leafColor = baseBiome->leafColor; + depth = baseBiome->depth + 0.1f; + scale = baseBiome->scale + 0.2f; + temperature = baseBiome->temperature; + downfall = baseBiome->downfall; + + + friendlies = baseBiome->friendlies; + enemies = baseBiome->enemies; + waterFriendlies = baseBiome->waterFriendlies; + friendlies_chicken = baseBiome->friendlies_chicken; + friendlies_wolf = baseBiome->friendlies_wolf; + friendlies_mushroomcow = baseBiome->friendlies_mushroomcow; + ambientFriendlies = baseBiome->ambientFriendlies; + + m_waterColor = baseBiome->m_waterColor; + m_skyColor = baseBiome->m_skyColor; + 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 + } +} + +MutatedBiome::~MutatedBiome() {} + +Feature* MutatedBiome::getTreeFeature(Random* random) { + return m_baseBiome ? m_baseBiome->getTreeFeature(random) : Biome::getTreeFeature(random); +} + +void MutatedBiome::decorate(Level* level, Random* rand, int xo, int zo) { + if (m_baseBiome) + m_baseBiome->decorate(level, rand, xo, zo); + else + Biome::decorate(level, rand, xo, zo); +} + +int MutatedBiome::getGrassColor() const { + return m_baseBiome ? m_baseBiome->getGrassColor() : Biome::getGrassColor(); +} + +int MutatedBiome::getFoliageColor() const { + return m_baseBiome ? m_baseBiome->getFoliageColor() : Biome::getFoliageColor(); +} + +float MutatedBiome::getCreatureProbability() const +{ + return m_baseBiome ? m_baseBiome->getCreatureProbability() : Biome::getCreatureProbability(); +} + +bool MutatedBiome::isSame(const Biome* other) const { + return m_baseBiome ? m_baseBiome->isSame(other) : Biome::isSame(other); +} + +int MutatedBiome::getTemperatureCategory() const { + return m_baseBiome ? m_baseBiome->getTemperatureCategory() : Biome::getTemperatureCategory(); +} + +void MutatedBiome::buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal) { + if (m_baseBiome) + m_baseBiome->buildSurfaceAt(level, random, primer, x, z, noiseVal); + else + Biome::buildSurfaceAt(level, random, primer, x, z, noiseVal); +} \ No newline at end of file diff --git a/Minecraft.World/MutatedBiome.h b/Minecraft.World/MutatedBiome.h new file mode 100644 index 00000000..52445802 --- /dev/null +++ b/Minecraft.World/MutatedBiome.h @@ -0,0 +1,24 @@ +#pragma once +#include "Biome.h" + +class MutatedBiome : public Biome +{ +public: + + MutatedBiome(int id, Biome* baseBiome); + virtual ~MutatedBiome(); + + virtual Feature* getTreeFeature(Random* random) override; + virtual void decorate(Level* level, Random* rand, int xo, int zo) override; + virtual int getGrassColor() const override; + virtual int getFoliageColor() const override; + virtual float getCreatureProbability() const override; + virtual bool isSame(const Biome* other) const override; + virtual int getTemperatureCategory() const override; + virtual void buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal) override; + + Biome* getBaseBiome() const { return m_baseBiome; } // Rimosso const + +protected: + Biome* m_baseBiome; // Rimosso const +}; \ No newline at end of file diff --git a/Minecraft.World/PlainsBiome.cpp b/Minecraft.World/PlainsBiome.cpp index 22c1e6b3..7d24af5b 100644 --- a/Minecraft.World/PlainsBiome.cpp +++ b/Minecraft.World/PlainsBiome.cpp @@ -9,4 +9,22 @@ PlainsBiome::PlainsBiome(int id) : Biome(id) decorator->treeCount = -999; decorator->flowerCount = 4; decorator->grassCount = 10; +} + +Feature* PlainsBiome::getFlowerFeature(Random* random, int x, int y, int z) +{ + int fType = random->nextInt(3); + if (fType == 0) return new FlowerFeature(Tile::rose_Id, Rose::OXEYE_DAISY); + if (fType == 1) return new FlowerFeature(Tile::rose_Id, Rose::AZURE_BLUET); + + // Tulipani (qualsiasi colore) + int tulipColor = random->nextInt(4); + switch (tulipColor) { + case 0: return new FlowerFeature(Tile::rose_Id, Rose::RED_TULIP); + case 1: return new FlowerFeature(Tile::rose_Id, Rose::ORANGE_TULIP); + case 2: return new FlowerFeature(Tile::rose_Id, Rose::WHITE_TULIP); + case 3: return new FlowerFeature(Tile::rose_Id, Rose::PINK_TULIP); + } + + return Biome::getFlowerFeature(random, x, y, z); } \ No newline at end of file diff --git a/Minecraft.World/PlainsBiome.h b/Minecraft.World/PlainsBiome.h index b49fd032..305e95c9 100644 --- a/Minecraft.World/PlainsBiome.h +++ b/Minecraft.World/PlainsBiome.h @@ -7,4 +7,5 @@ class PlainsBiome : public Biome friend class Biome; protected: PlainsBiome(int id); + virtual Feature* getFlowerFeature(Random* random, int x, int y, int z) override; }; \ No newline at end of file diff --git a/Minecraft.World/RoofTreeFeature.cpp b/Minecraft.World/RoofTreeFeature.cpp new file mode 100644 index 00000000..8b548442 --- /dev/null +++ b/Minecraft.World/RoofTreeFeature.cpp @@ -0,0 +1,199 @@ +#include "stdafx.h" +#include "RoofTreeFeature.h" +#include "net.minecraft.world.level.h" +#include "net.minecraft.world.level.tile.h" +#include "TreeTile2.h" +#include "LeafTile2.h" +#include +#include + +RoofTreeFeature::RoofTreeFeature(bool doUpdate) : Feature(doUpdate) { +} + + +static bool isReplaceable(int tile) { + return tile == 0 || + tile == Tile::tallgrass_Id || + tile == Tile::sapling_Id || + tile == Tile::grass_Id || + tile == Tile::dirt_Id || + tile == Tile::leaves_Id || + tile == Tile::leaves2_Id; +} + + + + +bool RoofTreeFeature::checkSpace(Level *worldIn, int x, int y, int z, int height) { + for (int dy = 0; dy <= height + 1; ++dy) { + int radius = 1; + if (dy == 0) radius = 0; + if (dy >= height - 1) radius = 2; + + for (int dx = -radius; dx <= radius; ++dx) { + for (int dz = -radius; dz <= radius; ++dz) { + + if (dy == 0 && dx == 0 && dz == 0) continue; + + int tile = worldIn->getTile(x + dx, y + dy, z + dz); + + if (tile != 0 && !isReplaceable(tile)) { + return false; + } + + if (tile == Tile::water_Id) { + return false; + } + } + } + } + return true; +} + + + +void RoofTreeFeature::placeLog(Level *worldIn, int x, int y, int z) { + int tile = worldIn->getTile(x, y, z); + if (tile == 0 || tile == Tile::leaves_Id || tile == Tile::leaves2_Id || tile == Tile::tallgrass_Id) { + placeBlock(worldIn, x, y, z, Tile::tree2Trunk_Id, TreeTile2::DARK_TRUNK); + } +} + + + + +void RoofTreeFeature::placeLeaf(Level *worldIn, int x, int y, int z) { + int tile = worldIn->getTile(x, y, z); + if (tile == 0) { + placeBlock(worldIn, x, y, z, Tile::leaves2_Id, 1); + } +} + + + +bool RoofTreeFeature::place(Level *level, Random *rand, int x, int y, int z) { + + int height = rand->nextInt(3) + 6; + int startX = x, startY = y, startZ = z; + + + if (startY < 1 || startY + height + 1 >= Level::maxBuildHeight) return false; + if (level->getTile(startX, startY - 1, startZ) != Tile::grass_Id && + level->getTile(startX, startY - 1, startZ) != Tile::dirt_Id) return false; + if (startY >= Level::maxBuildHeight - height - 1) return false; + if (!checkSpace(level, startX, startY, startZ, height)) return false; + + + if (app.getLevelGenerationOptions() != nullptr) { + LevelGenerationOptions *options = app.getLevelGenerationOptions(); + int radius = 4; + if (options->checkIntersects(x - radius, y - 1, z - radius, + x + radius + 1, y + height, z + radius + 1)) + return false; + } + + + placeBlock(level, startX, startY - 1, startZ, Tile::dirt_Id, 0); + placeBlock(level, startX + 1, startY - 1, startZ, Tile::dirt_Id, 0); + placeBlock(level, startX, startY - 1, startZ + 1, Tile::dirt_Id, 0); + placeBlock(level, startX + 1, startY - 1, startZ + 1, Tile::dirt_Id, 0); + + + int face = rand->nextInt(4); + int dx = 0, dz = 0; + if (face == 0) dz = -1; + else if (face == 1) dx = 1; + else if (face == 2) dz = 1; + else if (face == 3) dx = -1; + + int bendHeight = height - rand->nextInt(2) - 1; + int bendLength = rand->nextInt(2); + int trunkX = startX, trunkZ = startZ; + int topY = startY + height - 1; + + + for (int dy = 0; dy < height; ++dy) { + if (dy >= bendHeight && bendLength > 0) { + trunkX += dx; + trunkZ += dz; + --bendLength; + } + int currentY = startY + dy; + placeLog(level, trunkX, currentY, trunkZ); + placeLog(level, trunkX + 1, currentY, trunkZ); + placeLog(level, trunkX, currentY, trunkZ + 1); + placeLog(level, trunkX + 1, currentY, trunkZ + 1); + } + + + for (int i3 = -2; i3 <= 0; ++i3) { + for (int l3 = -2; l3 <= 0; ++l3) { + int yOffset = -1; + placeLeaf(level, trunkX + i3, topY + yOffset, trunkZ + l3); + placeLeaf(level, trunkX + 1 - i3, topY + yOffset, trunkZ + l3); + placeLeaf(level, trunkX + i3, topY + yOffset, trunkZ + 1 - l3); + placeLeaf(level, trunkX + 1 - i3, topY + yOffset, trunkZ + 1 - l3); + + + if ((i3 > -2 || l3 > -1) && (i3 != -1 || l3 != -2)) { + yOffset = 1; + placeLeaf(level, trunkX + i3, topY + yOffset, trunkZ + l3); + placeLeaf(level, trunkX + 1 - i3, topY + yOffset, trunkZ + l3); + placeLeaf(level, trunkX + i3, topY + yOffset, trunkZ + 1 - l3); + placeLeaf(level, trunkX + 1 - i3, topY + yOffset, trunkZ + 1 - l3); + } + } + } + + + if (rand->nextInt(2) == 0) { + placeLeaf(level, trunkX, topY + 2, trunkZ); + placeLeaf(level, trunkX + 1, topY + 2, trunkZ); + placeLeaf(level, trunkX + 1, topY + 2, trunkZ + 1); + placeLeaf(level, trunkX, topY + 2, trunkZ + 1); + } + + + for (int dxOff = -3; dxOff <= 4; ++dxOff) { + for (int dzOff = -3; dzOff <= 4; ++dzOff) { + + if ((dxOff == -3 || dxOff == 4) && (dzOff == -3 || dzOff == 4)) + continue; + if (std::abs(dxOff) < 3 || std::abs(dzOff) < 3) { + placeLeaf(level, trunkX + dxOff, topY, trunkZ + dzOff); + } + } + } + + + for (int dxOff = -1; dxOff <= 2; ++dxOff) { + for (int dzOff = -1; dzOff <= 2; ++dzOff) { + + if ((dxOff < 0 || dxOff > 1 || dzOff < 0 || dzOff > 1) && rand->nextInt(3) <= 0) { + int branchLength = rand->nextInt(2) + 2; + + + for (int l = 0; l < branchLength; ++l) { + placeLog(level, startX + dxOff, topY - l - 1, startZ + dzOff); + } + + + for (int lx = -1; lx <= 1; ++lx) { + for (int lz = -1; lz <= 1; ++lz) { + placeLeaf(level, trunkX + dxOff + lx, topY, trunkZ + dzOff + lz); + } + } + + for (int lx = -2; lx <= 2; ++lx) { + for (int lz = -2; lz <= 2; ++lz) { + if (std::abs(lx) != 2 || std::abs(lz) != 2) { + placeLeaf(level, trunkX + dxOff + lx, topY - 1, trunkZ + dzOff + lz); + } + } + } + } + } + } + + return true; +} \ No newline at end of file diff --git a/Minecraft.World/DarkOakFeature.h b/Minecraft.World/RoofTreeFeature.h similarity index 85% rename from Minecraft.World/DarkOakFeature.h rename to Minecraft.World/RoofTreeFeature.h index a7e98960..9bdb8d49 100644 --- a/Minecraft.World/DarkOakFeature.h +++ b/Minecraft.World/RoofTreeFeature.h @@ -2,10 +2,10 @@ #pragma once #include "Feature.h" -class DarkOakFeature : public Feature +class RoofTreeFeature : public Feature { public: - DarkOakFeature(bool doUpdate); + RoofTreeFeature(bool doUpdate); virtual bool place(Level *level, Random *random, int x, int y, int z); private: diff --git a/Minecraft.World/RoofedForestBiome.cpp b/Minecraft.World/RoofedForestBiome.cpp deleted file mode 100644 index 1400d007..00000000 --- a/Minecraft.World/RoofedForestBiome.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "stdafx.h" -#include "RoofedForestBiome.h" -#include "BiomeDecorator.h" -#include "DarkOakFeature.h" -#include "HugeMushroomFeature.h" -#include "TreeFeature.h" -#include "BirchFeature.h" -#include "net.minecraft.world.level.tile.h" -#include "..\Level.h" - -RoofedForestBiome::RoofedForestBiome(int id) : Biome(id) -{ - - decorator->treeCount = 35; - decorator->grassCount = 2; - decorator->flowerCount = 1; - decorator->mushroomCount = 1; - decorator->hugeMushrooms = 1; - - temperature = 0.7f; - downfall = 0.8f; - - topMaterial = static_cast(Tile::grass_Id); - material = static_cast(Tile::dirt_Id); - - - setColor(0x28340A); - setLeafColor(0x2D5A27); -} - -Feature* RoofedForestBiome::getTreeFeature(Random* random) -{ - - if (random->nextInt(20) == 0) - { - return new HugeMushroomFeature(); - } - - - if (random->nextInt(3) > 0) - { - return new DarkOakFeature(true); - } - - - { - return new TreeFeature(false); - } - - - return new BirchFeature(false); -} - - - -int RoofedForestBiome::getGrassColor() -{ - return 0x28340A; -} - -int RoofedForestBiome::getFolageColor() -{ - return 0x2D5A27; -} \ No newline at end of file diff --git a/Minecraft.World/RoofedForestBiome.h b/Minecraft.World/RoofedForestBiome.h deleted file mode 100644 index 9b133b9c..00000000 --- a/Minecraft.World/RoofedForestBiome.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "Biome.h" - -class RoofedForestBiome : public Biome -{ -public: - RoofedForestBiome(int id); - virtual Feature* getTreeFeature(Random* random) override; - // virtual void decorate(Level* level, Random* random, int xo, int zo) override; - virtual int getGrassColor() override; - virtual int getFolageColor() override; -}; \ No newline at end of file diff --git a/Minecraft.World/Sapling.cpp b/Minecraft.World/Sapling.cpp index a416b045..3fd2fcc4 100644 --- a/Minecraft.World/Sapling.cpp +++ b/Minecraft.World/Sapling.cpp @@ -6,7 +6,7 @@ #include "Sapling.h" #include "SavannaTreeFeature.h" -#include "DarkOakFeature.h" +#include "RoofTreeFeature.h" int Sapling::SAPLING_NAMES[SAPLING_NAMES_SIZE] = { IDS_TILE_SAPLING_OAK, @@ -133,7 +133,7 @@ void Sapling::growTree(Level *level, int x, int y, int z, Random *random) isSapling(level, x + ox, y, z + oz + 1, TYPE_DARK_OAK) && isSapling(level, x + ox + 1, y, z + oz + 1, TYPE_DARK_OAK)) { - f = new DarkOakFeature(true); + f = new RoofTreeFeature(true); multiblock = true; break; } diff --git a/Minecraft.World/SavannaBiome.cpp b/Minecraft.World/SavannaBiome.cpp index 9d6479eb..8c337e4b 100644 --- a/Minecraft.World/SavannaBiome.cpp +++ b/Minecraft.World/SavannaBiome.cpp @@ -14,7 +14,8 @@ SavannaBiome::SavannaBiome(int id) : Biome(id) decorator->treeCount = 1; decorator->flowerCount = 4; - decorator->grassCount = 20; + decorator->grassCount = 20; + } Feature *SavannaBiome::getTreeFeature(Random *random) @@ -29,12 +30,24 @@ Feature *SavannaBiome::getTreeFeature(Random *random) return new TreeFeature(false); } -int SavannaBiome::getGrassColor() +int SavannaBiome::getGrassColor() const { return 0xBFB755; } -int SavannaBiome::getFolageColor() +int SavannaBiome::getFoliageColor() const { return 0xAEA42A; } + +Feature *SavannaBiome::getFlowerFeature(Random *random, int x, int y, int z) +{ + + return nullptr; +} + +int SavannaBiome::getRandomDoublePlantType(Random *random) +{ + + return 0; +} diff --git a/Minecraft.World/SavannaBiome.h b/Minecraft.World/SavannaBiome.h index e1e99369..6de306a2 100644 --- a/Minecraft.World/SavannaBiome.h +++ b/Minecraft.World/SavannaBiome.h @@ -7,7 +7,9 @@ public: SavannaBiome(int id); virtual Feature *getTreeFeature(Random *random); - virtual int getFolageColor() override; - virtual int getGrassColor() override; + virtual int getFoliageColor() 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; }; \ No newline at end of file diff --git a/Minecraft.World/SwampBiome.h b/Minecraft.World/SwampBiome.h index 2bcdb8ac..0d6483bd 100644 --- a/Minecraft.World/SwampBiome.h +++ b/Minecraft.World/SwampBiome.h @@ -1,5 +1,8 @@ #pragma once #include "Biome.h" +#include "FlowerFeature.h" +#include "Tile.h" +#include "Rose.h" class LevelSource; class SwampBiome : public Biome @@ -11,7 +14,7 @@ public: public: virtual Feature *getTreeFeature(Random *random); - + virtual Feature* getFlowerFeature(Random* random, int x, int y, int z) override{return new FlowerFeature(Tile::rose_Id, Rose::BLUE_ORCHID);} // 4J Stu - Not using these any more //virtual int getGrassColor(); //virtual int getFolageColor(); diff --git a/Minecraft.World/Vec3.cpp b/Minecraft.World/Vec3.cpp index 93a326ce..75619bb0 100644 --- a/Minecraft.World/Vec3.cpp +++ b/Minecraft.World/Vec3.cpp @@ -57,11 +57,11 @@ void Vec3::resetPool() Vec3 *Vec3::newTemp(double x, double y, double z) { - ThreadStorage *tls = static_cast(TlsGetValue(tlsIdx)); - Vec3 *thisVec = &tls->pool[tls->poolPointer]; - thisVec->set(x, y, z); - tls->poolPointer = ( tls->poolPointer + 1 ) % ThreadStorage::POOL_SIZE; - return thisVec; + ThreadStorage *tls = static_cast(TlsGetValue(tlsIdx)); + Vec3 *thisVec = &tls->pool[tls->poolPointer]; + thisVec->set(x, y, z); + tls->poolPointer = ( tls->poolPointer + 1 ) % ThreadStorage::POOL_SIZE; + return thisVec; } Vec3::Vec3(double x, double y, double z) @@ -213,46 +213,26 @@ Vec3 *Vec3::lerp(Vec3 *v, double a) return Vec3::newTemp(x + (v->x - x) * a, y + (v->y - y) * a, z + (v->z - z) * a); } -void Vec3::xRot(float degs) +// Le nuove restituiscono un Vec3* +Vec3* Vec3::xRot(float degs) { - double _cos = cos((double)degs); // Use double for precision + double _cos = cos((double)degs); double _sin = sin((double)degs); - - double xx = x; - double yy = y * _cos + z * _sin; - double zz = z * _cos - y * _sin; - - x = xx; - y = yy; - z = zz; + return Vec3::newTemp(x, y * _cos + z * _sin, z * _cos - y * _sin); } -void Vec3::yRot(float degs) +Vec3* Vec3::yRot(float degs) { - double _cos = cos((double)degs); + double _cos = cos((double)degs); double _sin = sin((double)degs); - - double xx = x * _cos + z * _sin; - double yy = y; - double zz = z * _cos - x * _sin; - - x = xx; - y = yy; - z = zz; + return Vec3::newTemp(x * _cos + z * _sin, y, z * _cos - x * _sin); } -void Vec3::zRot(float degs) +Vec3* Vec3::zRot(float degs) { - double _cos = cos((double)degs); + double _cos = cos((double)degs); double _sin = sin((double)degs); - - double xx = x * _cos + y * _sin; - double yy = y * _cos - x * _sin; - double zz = z; - - x = xx; - y = yy; - z = zz; + return Vec3::newTemp(x * _cos + y * _sin, y * _cos - x * _sin, z); } double Vec3::distanceTo(AABB *box) @@ -278,7 +258,7 @@ Vec3* Vec3::closestPointOnLine(Vec3* p1, Vec3* p2) Vec3* diff = newTemp(x-p1->x, y-p1->y, z-p1->z); Vec3* dir = newTemp(p2->x-p1->x, p2->y-p1->y, p2->z-p1->z); - // Cambiato float in double + double dot1 = diff->dot(dir); if (dot1 <= 0.0) return p1; @@ -297,4 +277,48 @@ double Vec3::distanceFromLine(Vec3* p1, Vec3* p2) Vec3* closestPoint = closestPointOnLine(p1, p2); Vec3* diff = newTemp(x-closestPoint->x, y-closestPoint->y, z-closestPoint->z); return diff->length(); +} + + + +void Vec3::xRotInPlace(float degs) +{ + double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless wasting precision here + double _sin = sin(degs); + + double xx = x; + double yy = y * _cos + z * _sin; + double zz = z * _cos - y * _sin; + + x = xx; + y = yy; + z = zz;; +} + +void Vec3::yRotInPlace(float degs) +{ + double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless wasting precision here + double _sin = sin(degs); + + double xx = x * _cos + z * _sin; + double yy = y; + double zz = z * _cos - x * _sin; + + x = xx; + y = yy; + z = zz; +} + +void Vec3::zRotInPlace(float degs) +{ + double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless wasting precision here + double _sin = sin(degs); + + double xx = x * _cos + y * _sin; + double yy = y * _cos - x * _sin; + double zz = z; + + x = xx; + y = yy; + z = zz; } \ No newline at end of file diff --git a/Minecraft.World/Vec3.h b/Minecraft.World/Vec3.h index 2afc9ea7..6573acdb 100644 --- a/Minecraft.World/Vec3.h +++ b/Minecraft.World/Vec3.h @@ -61,9 +61,12 @@ public: Vec3 *lerp(Vec3 *v, double a); - void xRot(float degs); - void yRot(float degs); - void zRot(float degs); + Vec3* xRot(float degs); + Vec3* yRot(float degs); + Vec3* zRot(float degs); + void xRotInPlace(float degs); + void yRotInPlace(float degs); + void zRotInPlace(float degs); // 4J Added double distanceTo(AABB *box); diff --git a/Minecraft.World/Vec3i.cpp b/Minecraft.World/Vec3i.cpp index 3291bfd6..3da011ae 100644 --- a/Minecraft.World/Vec3i.cpp +++ b/Minecraft.World/Vec3i.cpp @@ -2,29 +2,40 @@ #include "Vec3i.h" #include -Vec3i::Vec3i(int x, int y, int z) : x(x), y(y), z(z) +void Vec3i::cross(Vec3i& result, const Vec3i& a, const Vec3i& b) { + result.set( + a.getY() * b.getZ() - a.getZ() * b.getY(), + a.getZ() * b.getX() - a.getX() * b.getZ(), + a.getX() * b.getY() - a.getY() * b.getX() + ); } -int Vec3i::getX() const +double Vec3i::dist(int x2, int y2, int z2) const { - return this->x; + double dx = x - x2; + double dy = y - y2; + double dz = z - z2; + return std::sqrt(dx*dx + dy*dy + dz*dz); } -int Vec3i::getY() const +double Vec3i::distSqr(double x2, double y2, double z2) const { - return this->y; + double dx = x - x2; + double dy = y - y2; + double dz = z - z2; + return dx*dx + dy*dy + dz*dz; } -int Vec3i::getZ() const +double Vec3i::distSqrToCenter(double x2, double y2, double z2) const { - return this->z; + double dx = (x + 0.5) - x2; + double dy = (y + 0.5) - y2; + double dz = (z + 0.5) - z2; + return dx*dx + dy*dy + dz*dz; } double Vec3i::distSqr(const Vec3i& other) const { - double dx = (double)(this->x - other.getX()); - double dy = (double)(this->y - other.getY()); - double dz = (double)(this->z - other.getZ()); - return dx * dx + dy * dy + dz * dz; + return distSqr(other.getX(), other.getY(), other.getZ()); } \ No newline at end of file diff --git a/Minecraft.World/Vec3i.h b/Minecraft.World/Vec3i.h index 730f3fd8..aff225a1 100644 --- a/Minecraft.World/Vec3i.h +++ b/Minecraft.World/Vec3i.h @@ -1,20 +1,37 @@ #pragma once +#include +#include -class Vec3i -{ -protected: - int x; - int y; - int z; - +class Vec3i { +protected: + int x, y, z; public: - Vec3i(int x, int y, int z); - virtual ~Vec3i() = default; + Vec3i() : x(0), y(0), z(0) {} + Vec3i(int x, int y, int z) : x(x), y(y), z(z) {} + Vec3i(double x, double y, double z) + : x((int)std::floor(x)), y((int)std::floor(y)), z((int)std::floor(z)) {} - int getX() const; - int getY() const; - int getZ() const; + int getX() const { return x; } + int getY() const { return y; } + int getZ() const { return z; } - - double distSqr(const Vec3i& other) const; + void set(int x, int y, int z) { this->x = x; this->y = y; this->z = z; } + + static void cross(Vec3i& result, const Vec3i& a, const Vec3i& b); + + double dist(int x2, int y2, int z2) const; + double distSqr(double x2, double y2, double z2) const; + double distSqrToCenter(double x2, double y2, double z2) const; + double distSqr(const Vec3i& other) const; + + bool equals(const Vec3i& other) const { + return x == other.x && y == other.y && z == other.z; + } + + Vec3i above() const { return Vec3i(x, y + 1, z); } + Vec3i below() const { return Vec3i(x, y - 1, z); } + Vec3i north() const { return Vec3i(x, y, z - 1); } + Vec3i south() const { return Vec3i(x, y, z + 1); } + Vec3i east() const { return Vec3i(x + 1, y, z); } + Vec3i west() const { return Vec3i(x - 1, y, z); } }; \ No newline at end of file diff --git a/Minecraft.World/net.minecraft.world.level.biome.h b/Minecraft.World/net.minecraft.world.level.biome.h index fb99fc1a..8339e462 100644 --- a/Minecraft.World/net.minecraft.world.level.biome.h +++ b/Minecraft.World/net.minecraft.world.level.biome.h @@ -32,5 +32,4 @@ #include "JungleBiome.h" //TU31 -#include "SavannaBiome.h" -#include "RoofedForestBiome.h" \ No newline at end of file +#include "SavannaBiome.h" \ No newline at end of file diff --git a/Minecraft.World/net.minecraft.world.level.levelgen.feature.h b/Minecraft.World/net.minecraft.world.level.levelgen.feature.h index f00041c1..768b8ca4 100644 --- a/Minecraft.World/net.minecraft.world.level.levelgen.feature.h +++ b/Minecraft.World/net.minecraft.world.level.levelgen.feature.h @@ -22,6 +22,7 @@ #include "SpringFeature.h" #include "SpruceFeature.h" #include "TallGrassFeature.h" +#include "DoublePlantFeature.h" #include "TreeFeature.h" #include "HugeMushroomFeature.h" @@ -31,9 +32,9 @@ #include "SpikeFeature.h" #include "EndPodiumFeature.h" #include "SavannaTreeFeature.h" -#include "DarkOakFeature.h" +#include "RoofTreeFeature.h" #include "DesertWellFeature.h" #include "MegaTreeFeature.h" #include "VinesFeature.h" -#include "GroundBushFeature.h" \ No newline at end of file +#include "GroundBushFeature.h" diff --git a/Minecraft.World/net.minecraft.world.level.tile.h b/Minecraft.World/net.minecraft.world.level.tile.h index 5a6bb482..462cef37 100644 --- a/Minecraft.World/net.minecraft.world.level.tile.h +++ b/Minecraft.World/net.minecraft.world.level.tile.h @@ -138,4 +138,6 @@ #include "LeafTile2.h" #include "PrismarineTile.h" -#include "PackedIceTile.h" \ No newline at end of file +#include "PackedIceTile.h" + +#include "Tallgrass2.h"