From 09c93f9b1835d4f1f8bfdb8cf5f1730921412158 Mon Sep 17 00:00:00 2001 From: NSDeathman Date: Sun, 15 Mar 2026 21:09:31 +0300 Subject: [PATCH] New biomes --- Minecraft.World/Biome.cpp | 201 +++++----- Minecraft.World/Biome.h | 66 ++-- Minecraft.World/BiomeDecorator.h | 1 + Minecraft.World/BiomeInitLayer.cpp | 107 +++--- Minecraft.World/BiomeSource.cpp | 352 +++++++----------- Minecraft.World/BirchFeature.cpp | 2 +- Minecraft.World/BirchForestBiome.cpp | 17 + Minecraft.World/BirchForestBiome.h | 10 + Minecraft.World/Layer.cpp | 33 +- Minecraft.World/RandomLevelSource.cpp | 4 +- .../net.minecraft.world.level.biome.h | 1 + 11 files changed, 393 insertions(+), 401 deletions(-) create mode 100644 Minecraft.World/BirchForestBiome.cpp create mode 100644 Minecraft.World/BirchForestBiome.h diff --git a/Minecraft.World/Biome.cpp b/Minecraft.World/Biome.cpp index 66265765e..15829999c 100644 --- a/Minecraft.World/Biome.cpp +++ b/Minecraft.World/Biome.cpp @@ -10,81 +10,135 @@ #include "Biome.h" #include "net.minecraft.world.level.biome.h" -//public static final Biome[] biomes = new Biome[256]; -Biome *Biome::biomes[256]; +std::vector Biome::biomes; -Biome *Biome::ocean = nullptr; -Biome *Biome::plains = nullptr; -Biome *Biome::desert = nullptr; +Biome* Biome::ocean = nullptr; +Biome* Biome::plains = nullptr; +Biome* Biome::desert = nullptr; +Biome* Biome::extremeHills = nullptr; +Biome* Biome::forest = nullptr; +Biome* Biome::birchForest = nullptr; +Biome* Biome::rainForest = nullptr; +Biome* Biome::taiga = nullptr; +Biome* Biome::taigaSnowed = nullptr; +Biome* Biome::swampland = nullptr; +Biome* Biome::river = nullptr; +Biome* Biome::hell = nullptr; +Biome* Biome::sky = nullptr; +Biome* Biome::frozenOcean = nullptr; +Biome* Biome::frozenRiver = nullptr; +Biome* Biome::iceFlats = nullptr; +Biome* Biome::iceMountains = nullptr; +Biome* Biome::mushroomIsland = nullptr; +Biome* Biome::mushroomIslandShore = nullptr; +Biome* Biome::beaches = nullptr; +Biome* Biome::desertHills = nullptr; +Biome* Biome::forestHills = nullptr; +Biome* Biome::taigaHills = nullptr; +Biome* Biome::smallerExtremeHills = nullptr; +Biome* Biome::jungle = nullptr; +Biome* Biome::jungleHills = nullptr; -Biome *Biome::extremeHills = nullptr; -Biome *Biome::forest = nullptr; -Biome *Biome::taiga = nullptr; +Biome* Biome::getBiome(int id) +{ + if (id >= 0 && id < static_cast(biomes.size())) + return biomes[id]; + return nullptr; +} -Biome *Biome::swampland = nullptr; -Biome *Biome::river = nullptr; - -Biome *Biome::hell = nullptr; -Biome *Biome::sky = nullptr; - -Biome *Biome::frozenOcean = nullptr; -Biome *Biome::frozenRiver = nullptr; -Biome *Biome::iceFlats = nullptr; -Biome *Biome::iceMountains = nullptr; -Biome *Biome::mushroomIsland = nullptr; -Biome *Biome::mushroomIslandShore = nullptr; -Biome *Biome::beaches = nullptr; -Biome *Biome::desertHills = nullptr; -Biome *Biome::forestHills = nullptr; -Biome *Biome::taigaHills = nullptr; -Biome *Biome::smallerExtremeHills = nullptr; - -Biome *Biome::jungle = nullptr; -Biome *Biome::jungleHills = nullptr; +// Регистрация биома по ID (автоматически расширяет вектор при необходимости) +void Biome::registerBiome(int id, Biome* biome) +{ + if (id < 0) return; // защита от отрицательных ID + if (id >= static_cast(biomes.size())) + { + biomes.resize(id + 1, nullptr); + } + biomes[id] = biome; +} +int Biome::getBiomeCount() +{ + return static_cast(biomes.size()); +} void Biome::staticCtor() { - //public static final Biome[] biomes = new Biome[256]; + static int s_biomeId = 0; +#define NEXT_ID (s_biomeId++) - 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); +#define COLOURS(suffix) \ + eMinecraftColour_Grass_##suffix, \ + eMinecraftColour_Foliage_##suffix, \ + eMinecraftColour_Water_##suffix, \ + eMinecraftColour_Sky_##suffix - Biome::extremeHills = (new ExtremeHillsBiome(3))->setColor(0x606060)->setName(L"Extreme Hills")->setDepthAndScale(0.3f, 1.5f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills, eMinecraftColour_Foliage_ExtremeHills, eMinecraftColour_Water_ExtremeHills,eMinecraftColour_Sky_ExtremeHills); - Biome::forest = (new ForestBiome(4))->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); - // 4J - brought forward Taiga temperature change from 0.3f to 0.05f, from 1.2.3 - 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); +#define BIOME(classType, name, colour, temp, downfall, depth, scale, colourSuffix) \ + Biome::name = (new classType(NEXT_ID)) \ + ->setColor(colour) \ + ->setName(L#name) \ + ->setTemperatureAndDownfall(temp, downfall) \ + ->setDepthAndScale(depth, scale) \ + ->setLeafFoliageWaterSkyColor(COLOURS(colourSuffix)) - Biome::swampland = (new SwampBiome(6))->setColor(0x07F9B2)->setName(L"Swampland")->setLeafColor(0x8BAF48)->setDepthAndScale(-0.2f, 0.1f)->setTemperatureAndDownfall(0.8f, 0.9f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Swampland, eMinecraftColour_Foliage_Swampland, eMinecraftColour_Water_Swampland,eMinecraftColour_Sky_Swampland); - Biome::river = (new RiverBiome(7))->setColor(0x0000ff)->setName(L"River")->setDepthAndScale(-0.5f, 0)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_River, eMinecraftColour_Foliage_River, eMinecraftColour_Water_River,eMinecraftColour_Sky_River); +#define BIOME_NO_RAIN(classType, name, colour, depth, scale, colourSuffix) \ + Biome::name = (new classType(NEXT_ID)) \ + ->setColor(colour) \ + ->setName(L#name) \ + ->setNoRain() \ + ->setTemperatureAndDownfall(2.0f, 0.0f) \ + ->setDepthAndScale(depth, scale) \ + ->setLeafFoliageWaterSkyColor(COLOURS(colourSuffix)) - Biome::hell = (new HellBiome(8))->setColor(0xff0000)->setName(L"Hell")->setNoRain()->setTemperatureAndDownfall(2, 0)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Hell, eMinecraftColour_Foliage_Hell, eMinecraftColour_Water_Hell,eMinecraftColour_Sky_Hell); - Biome::sky = (new TheEndBiome(9))->setColor(0x8080ff)->setName(L"Sky")->setNoRain()->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Sky, eMinecraftColour_Foliage_Sky, eMinecraftColour_Water_Sky,eMinecraftColour_Sky_Sky); +#define BIOME_SNOW(classType, name, colour, temp, downfall, depth, scale, colourSuffix) \ + Biome::name = (new classType(NEXT_ID)) \ + ->setColor(colour) \ + ->setName(L#name) \ + ->setSnowCovered() \ + ->setTemperatureAndDownfall(temp, downfall) \ + ->setDepthAndScale(depth, scale) \ + ->setLeafFoliageWaterSkyColor(COLOURS(colourSuffix)) - Biome::frozenOcean = (new OceanBiome(10))->setColor(0x9090a0)->setName(L"FrozenOcean")->setSnowCovered()->setDepthAndScale(-1, 0.5f)->setTemperatureAndDownfall(0, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_FrozenOcean, eMinecraftColour_Foliage_FrozenOcean, eMinecraftColour_Water_FrozenOcean,eMinecraftColour_Sky_FrozenOcean); - Biome::frozenRiver = (new RiverBiome(11))->setColor(0xa0a0ff)->setName(L"FrozenRiver")->setSnowCovered()->setDepthAndScale(-0.5f, 0)->setTemperatureAndDownfall(0, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_FrozenRiver, eMinecraftColour_Foliage_FrozenRiver, eMinecraftColour_Water_FrozenRiver,eMinecraftColour_Sky_FrozenRiver); - Biome::iceFlats = (new IceBiome(12))->setColor(0xffffff)->setName(L"Ice Plains")->setSnowCovered()->setTemperatureAndDownfall(0, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_IcePlains, eMinecraftColour_Foliage_IcePlains, eMinecraftColour_Water_IcePlains,eMinecraftColour_Sky_IcePlains); - Biome::iceMountains = (new IceBiome(13))->setColor(0xa0a0a0)->setName(L"Ice Mountains")->setSnowCovered()->setDepthAndScale(0.3f, 1.3f)->setTemperatureAndDownfall(0, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_IceMountains, eMinecraftColour_Foliage_IceMountains, eMinecraftColour_Water_IceMountains,eMinecraftColour_Sky_IceMountains); +#define BIOME_LEAF(classType, name, colour, leafColour, temp, downfall, depth, scale, colourSuffix) \ + Biome::name = (new classType(NEXT_ID)) \ + ->setColor(colour) \ + ->setName(L#name) \ + ->setLeafColor(leafColour) \ + ->setTemperatureAndDownfall(temp, downfall) \ + ->setDepthAndScale(depth, scale) \ + ->setLeafFoliageWaterSkyColor(COLOURS(colourSuffix)) - Biome::mushroomIsland = (new MushroomIslandBiome(14))->setColor(0xff00ff)->setName(L"MushroomIsland")->setTemperatureAndDownfall(0.9f, 1.0f)->setDepthAndScale(0.2f, 1.0f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_MushroomIsland, eMinecraftColour_Foliage_MushroomIsland, eMinecraftColour_Water_MushroomIsland,eMinecraftColour_Sky_MushroomIsland); - Biome::mushroomIslandShore = (new MushroomIslandBiome(15))->setColor(0xa000ff)->setName(L"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))->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(OceanBiome, ocean, RGB(0, 0, 112), 0.5f, 0.5f, -1.0f, 0.4f, Ocean); + BIOME(PlainsBiome, plains, RGB(100, 179, 40), 0.8f, 0.4f, 0.0f, 0.1f, Plains); + BIOME_NO_RAIN(DesertBiome, desert, RGB(250, 148, 24), 0.1f, 0.2f, Desert); + BIOME(ExtremeHillsBiome, extremeHills, RGB(96, 96, 96), 0.2f, 0.3f, 0.3f, 1.5f, ExtremeHills); + BIOME_LEAF(BirchForestBiome, birchForest, RGB(5, 102, 33), RGB(78, 186, 49), 0.7f, 0.8f, 0.0f, 0.1f, Forest); + BIOME_LEAF(ForestBiome, forest, RGB(5, 102, 33), RGB(78, 186, 49), 0.7f, 0.8f, 0.0f, 0.1f, Forest); + BIOME_LEAF(RainforestBiome, rainForest, RGB(5, 102, 33), RGB(78, 186, 49), 0.7f, 0.8f, 0.0f, 0.1f, Forest); + BIOME_LEAF(TaigaBiome, taiga, RGB(11, 102, 89), RGB(78, 186, 49), 0.7f, 0.8f, 0.1f, 0.4f, Taiga); + BIOME_SNOW(TaigaBiome, taigaSnowed, RGB(11, 102, 89), 0.05f, 0.8f, 0.1f, 0.4f, Taiga); + BIOME_LEAF(SwampBiome, swampland, RGB(7, 249, 178), RGB(139, 175, 72), 0.8f, 0.9f, -0.2f, 0.1f, Swampland); + BIOME(RiverBiome, river, RGB(0, 0, 255), 0.5f, 0.5f, -0.5f, 0.0f, River); + BIOME_NO_RAIN(HellBiome, hell, RGB(255, 0, 0), 0.0f, 0.1f, Hell); + BIOME_NO_RAIN(TheEndBiome, sky, RGB(128, 128, 255), 0.0f, 0.1f, Sky); + BIOME_SNOW(OceanBiome, frozenOcean, RGB(144, 144, 160), 0.0f, 0.5f, -1.0f, 0.5f, FrozenOcean); + BIOME_SNOW(RiverBiome, frozenRiver, RGB(160, 160, 255), 0.0f, 0.5f, -0.5f, 0.0f, FrozenRiver); + BIOME_SNOW(IceBiome, iceFlats, RGB(255, 255, 255), 0.0f, 0.5f, 0.0f, 0.1f, IcePlains); + BIOME_SNOW(IceBiome, iceMountains, RGB(160, 160, 160), 0.0f, 0.5f, 0.3f, 1.3f, IceMountains); + BIOME(MushroomIslandBiome, mushroomIsland, RGB(255, 0, 255), 0.9f, 1.0f, 0.2f, 1.0f, MushroomIsland); + BIOME(MushroomIslandBiome, mushroomIslandShore, RGB(160, 0, 255), 0.9f, 1.0f, -1.0f, 0.1f, MushroomIslandShore); + BIOME(BeachBiome, beaches, RGB(250, 222, 85), 0.8f, 0.4f, 0.0f, 0.1f, Beach); + BIOME_NO_RAIN(DesertBiome, desertHills, RGB(210, 95, 18), 0.3f, 0.8f, DesertHills); + BIOME_LEAF(ForestBiome, forestHills, RGB(34, 85, 28), RGB(78, 186, 49), 0.7f, 0.8f, 0.3f, 0.7f, ForestHills); + BIOME_SNOW(TaigaBiome, taigaHills, RGB(22, 57, 51), 0.05f, 0.8f, 0.3f, 0.8f, TaigaHills); + BIOME(ExtremeHillsBiome, smallerExtremeHills, RGB(114, 120, 154), 0.2f, 0.3f, 0.2f, 0.8f, ExtremeHillsEdge); + BIOME_LEAF(JungleBiome, jungle, RGB(83, 123, 9), RGB(83, 123, 9), 1.2f, 0.9f, 0.2f, 0.4f, Jungle); + BIOME_LEAF(JungleBiome, jungleHills, RGB(44, 66, 5), RGB(83, 123, 9), 1.2f, 0.9f, 1.8f, 0.5f, JungleHills); } Biome::Biome(int id) : id(id) { - // 4J Stu Default inits color = 0; - // snowCovered = false; // 4J - this isn't set by the java game any more so removing to save confusion topMaterial = static_cast(Tile::grass_Id); material = static_cast(Tile::dirt_Id); @@ -94,26 +148,19 @@ Biome::Biome(int id) : id(id) scale = 0.3f; temperature = 0.5f; downfall = 0.5f; - //waterColor = 0xffffff; // 4J Stu - Not used decorator = nullptr; m_grassColor = eMinecraftColour_NOT_SET; m_foliageColor = eMinecraftColour_NOT_SET; m_waterColor = eMinecraftColour_NOT_SET; - /* 4J - removing these so that we can consistently return newly created trees via getTreeFeature, and let the calling function be resposible for deleting the returned tree - normalTree = new TreeFeature(); - fancyTree = new BasicTree(); - birchTree = new BirchFeature(); - swampTree = new SwampTreeFeature(); - */ + registerBiome(id, this); - biomes[id] = this; decorator = createDecorator(); 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)); // 4J - moved chickens to their own category + friendlies_chicken.push_back(new MobSpawnerData(eTYPE_CHICKEN, 10, 4, 4)); // 4J - куры в отдельной категории friendlies.push_back(new MobSpawnerData(eTYPE_COW, 8, 4, 4)); enemies.push_back(new MobSpawnerData(eTYPE_SPIDER, 10, 4, 4)); @@ -123,8 +170,6 @@ Biome::Biome(int id) : id(id) enemies.push_back(new MobSpawnerData(eTYPE_SLIME, 10, 4, 4)); enemies.push_back(new MobSpawnerData(eTYPE_ENDERMAN, 1, 1, 4)); - // wolves are added to forests and taigas - waterFriendlies.push_back(new MobSpawnerData(eTYPE_SQUID, 10, 4, 4)); ambientFriendlies.push_back(new MobSpawnerData(eTYPE_BAT, 10, 8, 8)); @@ -210,12 +255,6 @@ Biome *Biome::setColor(int color) int Biome::getSkyColor(float temp) { - //temp /= 3.0f; - //if (temp < -1) temp = -1; - //if (temp > 1) temp = 1; - //return Color::getHSBColor(224 / 360.0f - temp * 0.05f, 0.50f + temp * 0.1f, 1.0f).getRGB(); - - // 4J Stu - Load colour from texture pack return Minecraft::GetInstance()->getColourTable()->getColor( m_skyColor ); } @@ -233,7 +272,6 @@ vector *Biome::getMobs(MobCategory *category) bool Biome::hasSnow() { - // 4J - snowCovered flag removed as it wasn't being set by the game anymore - snow is now temperature dependent to match code in rain rendering, shouldFreeze functions etc. if( !_hasRain ) return false; if( getTemperature() >= 0.15f ) return false; @@ -243,9 +281,7 @@ bool Biome::hasSnow() bool Biome::hasRain() { - // 4J - snowCovered flag removed as it wasn't being set by the game anymore, replaced by call to hasSnow() if( hasSnow() ) return false; - // if (snowCovered) return false; return _hasRain; } @@ -269,13 +305,11 @@ int Biome::getTemperatureInt() return static_cast(temperature * 65536); } -// 4J - brought forward from 1.2.3 float Biome::getDownfall() { return downfall; } -// 4J - brought forward from 1.2.3 float Biome::getTemperature() { return temperature; @@ -288,23 +322,14 @@ void Biome::decorate(Level *level, Random *random, int xo, int zo) int Biome::getGrassColor() { - //double temp = Mth::clamp(getTemperature(), 0.0f, 1.0f); - //double rain = Mth::clamp(getDownfall(), 0.0f, 1.0f); - - //return GrassColor::get(temp, rain); return Minecraft::GetInstance()->getColourTable()->getColor( m_grassColor ); } int Biome::getFolageColor() { - //double temp = Mth::clamp(getTemperature(), 0.0f, 1.0f); - //double rain = Mth::clamp(getDownfall(), 0.0f, 1.0f); - - //return FoliageColor::get(temp, rain); return Minecraft::GetInstance()->getColourTable()->getColor( m_foliageColor ); } -// 4J Added int Biome::getWaterColor() { return Minecraft::GetInstance()->getColourTable()->getColor( m_waterColor ); diff --git a/Minecraft.World/Biome.h b/Minecraft.World/Biome.h index f7de31662..1241b72cd 100644 --- a/Minecraft.World/Biome.h +++ b/Minecraft.World/Biome.h @@ -18,36 +18,50 @@ class Biome { friend class ChunkRebuildData; public: - // 4J JEV, replaces the static blocks. + static Biome* ocean; + static Biome* plains; + static Biome* desert; + static Biome* extremeHills; + static Biome* forest; + static Biome* birchForest; + static Biome* rainForest; + static Biome* taiga; + static Biome* taigaSnowed; + static Biome* swampland; + static Biome* river; + static Biome* hell; + static Biome* sky; + static Biome* frozenOcean; + static Biome* frozenRiver; + static Biome* iceFlats; + static Biome* iceMountains; + static Biome* mushroomIsland; + static Biome* mushroomIslandShore; + static Biome* beaches; + static Biome* desertHills; + static Biome* forestHills; + static Biome* taigaHills; + static Biome* smallerExtremeHills; + static Biome* jungle; + static Biome* jungleHills; + static void staticCtor(); - static Biome *biomes[256]; + static std::vector biomes; - static Biome *ocean; - static Biome *plains; - static Biome *desert; - static Biome *extremeHills; - static Biome *forest; - static Biome *taiga; - static Biome *swampland; - static Biome *river; - static Biome *hell; - static Biome *sky; - static Biome *frozenOcean; - static Biome *frozenRiver; - static Biome *iceFlats; - static Biome *iceMountains; - static Biome *mushroomIsland; - static Biome *mushroomIslandShore ; - static Biome *beaches; - static Biome *desertHills; - static Biome *forestHills; - static Biome *taigaHills; - static Biome *smallerExtremeHills; - static Biome *jungle; - static Biome *jungleHills; + // Геттер для доступа по ID + static Biome* getBiome(int id); - static const int BIOME_COUNT = 23; // 4J Stu added + // Сеттер (регистрация) — вызывается автоматически в конструкторе + static void registerBiome(int id, Biome* biome); + + // Получить текущее количество зарегистрированных биомов + static int getBiomeCount(); + + // Опционально: получить ссылку на весь вектор (для итерации) + static const std::vector& getAllBiomes() { return biomes; } + + static const int BIOME_COUNT = 26; public: wstring m_name; diff --git a/Minecraft.World/BiomeDecorator.h b/Minecraft.World/BiomeDecorator.h index 01560045a..29f1304c3 100644 --- a/Minecraft.World/BiomeDecorator.h +++ b/Minecraft.World/BiomeDecorator.h @@ -9,6 +9,7 @@ class BiomeDecorator { friend class DesertBiome; friend class ForestBiome; + friend class BirchForestBiome; friend class PlainsBiome; friend class SwampBiome; friend class TaigaBiome; diff --git a/Minecraft.World/BiomeInitLayer.cpp b/Minecraft.World/BiomeInitLayer.cpp index 6edd18ded..488c32860 100644 --- a/Minecraft.World/BiomeInitLayer.cpp +++ b/Minecraft.World/BiomeInitLayer.cpp @@ -4,32 +4,30 @@ #include "net.minecraft.world.level.h" #include "BiomeInitLayer.h" -BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptrparent, LevelType *levelType) : Layer(seed) +BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptr parent, LevelType* levelType) : Layer(seed) { - this->parent = parent; + this->parent = parent; + // Собираем все биомы Верхнего мира, кроме ада и энда + std::vector overworldBiomes; + overworldBiomes.push_back(Biome::plains); + overworldBiomes.push_back(Biome::desert); + overworldBiomes.push_back(Biome::extremeHills); + overworldBiomes.push_back(Biome::forest); + overworldBiomes.push_back(Biome::birchForest); + overworldBiomes.push_back(Biome::rainForest); + overworldBiomes.push_back(Biome::taiga); + overworldBiomes.push_back(Biome::taigaSnowed); + overworldBiomes.push_back(Biome::swampland); + overworldBiomes.push_back(Biome::beaches); + overworldBiomes.push_back(Biome::jungle); - if(levelType == LevelType::lvl_normal_1_1) - { - startBiomes = BiomeArray(6); - startBiomes[0] = Biome::desert; - startBiomes[1] = Biome::forest; - startBiomes[2] = Biome::extremeHills; - startBiomes[3] = Biome::swampland; - startBiomes[4] = Biome::plains; - startBiomes[5] = Biome::taiga; - } - else - { - startBiomes = BiomeArray(7); - startBiomes[0] = Biome::desert; - startBiomes[1] = Biome::forest; - startBiomes[2] = Biome::extremeHills; - startBiomes[3] = Biome::swampland; - startBiomes[4] = Biome::plains; - startBiomes[5] = Biome::taiga; - startBiomes[6] = Biome::jungle; - } + // Создаем массив нужного размера и копируем указатели + startBiomes = BiomeArray(overworldBiomes.size()); + for (size_t i = 0; i < overworldBiomes.size(); ++i) + { + startBiomes[i] = overworldBiomes[i]; + } } BiomeInitLayer::~BiomeInitLayer() @@ -39,41 +37,46 @@ BiomeInitLayer::~BiomeInitLayer() intArray BiomeInitLayer::getArea(int xo, int yo, int w, int h) { - intArray b = parent->getArea(xo, yo, w, h); + intArray b = parent->getArea(xo, yo, w, h); + intArray result = IntCache::allocate(w * h); - intArray result = IntCache::allocate(w * h); - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - initRandom(x + xo, y + yo); + // Получаем ID грибного острова (с проверкой) + int mushroomId = Biome::mushroomIsland ? Biome::mushroomIsland->id : -1; + + // Проверка, что startBiomes валидный + if (startBiomes.data == nullptr || startBiomes.length == 0) + { + // Если нет биомов, заполняем нулями (океан) + for (int i = 0; i < w * h; ++i) + result[i] = 0; + return result; + } + + for (int y = 0; y < h; ++y) + { + for (int x = 0; x < w; ++x) + { + initRandom(x + xo, y + yo); int old = b[x + y * w]; + + // Если ячейка помечена как океан (0), оставляем океан if (old == 0) - { + { result[x + y * w] = 0; } - else if (old == Biome::mushroomIsland->id) - { + // Если это грибной остров, сохраняем его + else if (mushroomId != -1 && old == mushroomId) + { result[x + y * w] = old; } - else if (old == 1) - { - result[x + y * w] = startBiomes[nextRandom(startBiomes.length)]->id; + // Во всех остальных случаях выбираем случайный биом из списка + else + { + int idx = nextRandom(startBiomes.length); + result[x + y * w] = startBiomes[idx]->id; } - else - { - int isTaiga = startBiomes[nextRandom(startBiomes.length)]->id; - if (isTaiga == Biome::taiga->id) - { - result[x + y * w] = isTaiga; - } - else - { - result[x + y * w] = Biome::iceFlats->id; - } - } - } - } + } + } - return result; -} \ No newline at end of file + return result; +} diff --git a/Minecraft.World/BiomeSource.cpp b/Minecraft.World/BiomeSource.cpp index c44eb3b06..499421232 100644 --- a/Minecraft.World/BiomeSource.cpp +++ b/Minecraft.World/BiomeSource.cpp @@ -35,7 +35,7 @@ void BiomeSource::_init() playerSpawnBiomes.push_back(Biome::smallerExtremeHills); } -void BiomeSource::_init(int64_t seed, LevelType *generator) +void BiomeSource::_init(int64_t seed, LevelType* generator) { _init(); @@ -43,7 +43,7 @@ void BiomeSource::_init(int64_t seed, LevelType *generator) layer = layers[0]; zoomedLayer = layers[1]; - delete [] layers.data; + delete[] layers.data; } BiomeSource::BiomeSource() @@ -51,14 +51,12 @@ BiomeSource::BiomeSource() _init(); } -// 4J added -BiomeSource::BiomeSource(int64_t seed, LevelType *generator) +BiomeSource::BiomeSource(int64_t seed, LevelType* generator) { _init(seed, generator); } -// 4J - removal of separate temperature & downfall layers brought forward from 1.2.3 -BiomeSource::BiomeSource(Level *level) +BiomeSource::BiomeSource(Level* level) { _init(level->getSeed(), level->getLevelData()->getGenerator()); } @@ -68,12 +66,12 @@ BiomeSource::~BiomeSource() delete cache; } -Biome *BiomeSource::getBiome(ChunkPos *cp) +Biome* BiomeSource::getBiome(ChunkPos* cp) { return getBiome(cp->x << 4, cp->z << 4); } -Biome *BiomeSource::getBiome(int x, int z) +Biome* BiomeSource::getBiome(int x, int z) { return cache->getBiome(x, z); } @@ -83,7 +81,6 @@ float BiomeSource::getDownfall(int x, int z) const return cache->getDownfall(x, z); } -// 4J - note that caller is responsible for deleting returned array. temperatures array is for output only. floatArray BiomeSource::getDownfallBlock(int x, int z, int w, int h) const { floatArray downfalls; @@ -91,28 +88,27 @@ floatArray BiomeSource::getDownfallBlock(int x, int z, int w, int h) const return downfalls; } -// 4J - note that caller is responsible for deleting returned array. temperatures array is for output only. -// 4J - removal of separate temperature & downfall layers brought forward from 1.2.3 -void BiomeSource::getDownfallBlock(floatArray &downfalls, int x, int z, int w, int h) const +void BiomeSource::getDownfallBlock(floatArray& downfalls, int x, int z, int w, int h) const { IntCache::releaseAll(); - //if (downfalls == nullptr || downfalls->length < w * h) + if (downfalls.data == nullptr || downfalls.length < w * h) { - if(downfalls.data != nullptr) delete [] downfalls.data; + if (downfalls.data != nullptr) delete[] downfalls.data; downfalls = floatArray(w * h); } intArray result = zoomedLayer->getArea(x, z, w, h); for (int i = 0; i < w * h; i++) { - float d = static_cast(Biome::biomes[result[i]]->getDownfallInt()) / 65536.0f; + Biome* biome = Biome::getBiome(result[i]); + float d = static_cast(biome->getDownfallInt()) / 65536.0f; if (d > 1) d = 1; downfalls[i] = d; } } -BiomeCache::Block *BiomeSource::getBlockAt(int x, int y) +BiomeCache::Block* BiomeSource::getBlockAt(int x, int y) { return cache->getBlockAt(x, y); } @@ -122,8 +118,7 @@ float BiomeSource::getTemperature(int x, int y, int z) const return scaleTemp(cache->getTemperature(x, z), y); } -// 4J - brought forward from 1.2.3 -float BiomeSource::scaleTemp(float temp, int y ) const +float BiomeSource::scaleTemp(float temp, int y) const { return temp; } @@ -135,22 +130,21 @@ floatArray BiomeSource::getTemperatureBlock(int x, int z, int w, int h) const return temperatures; } -// 4J - note that caller is responsible for deleting returned array. temperatures array is for output only. -// 4J - removal of separate temperature & downfall layers brought forward from 1.2.3 void BiomeSource::getTemperatureBlock(floatArray& temperatures, int x, int z, int w, int h) const { IntCache::releaseAll(); - //if (temperatures == null || temperatures.length < w * h) { + if (temperatures.data == nullptr || temperatures.length < w * h) { - if( temperatures.data != nullptr ) delete [] temperatures.data; + if (temperatures.data != nullptr) delete[] temperatures.data; temperatures = floatArray(w * h); } intArray result = zoomedLayer->getArea(x, z, w, h); for (int i = 0; i < w * h; i++) { - float t = static_cast(Biome::biomes[result[i]]->getTemperatureInt()) / 65536.0f; + Biome* biome = Biome::getBiome(result[i]); + float t = static_cast(biome->getTemperatureInt()) / 65536.0f; if (t > 1) t = 1; temperatures[i] = t; } @@ -163,8 +157,7 @@ BiomeArray BiomeSource::getRawBiomeBlock(int x, int z, int w, int h) const return biomes; } -// 4J added -void BiomeSource::getRawBiomeIndices(intArray &biomes, int x, int z, int w, int h) const +void BiomeSource::getRawBiomeIndices(intArray& biomes, int x, int z, int w, int h) const { IntCache::releaseAll(); @@ -175,22 +168,22 @@ void BiomeSource::getRawBiomeIndices(intArray &biomes, int x, int z, int w, int } } -void BiomeSource::getRawBiomeBlock(BiomeArray &biomes, int x, int z, int w, int h) const +void BiomeSource::getRawBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h) const { IntCache::releaseAll(); - //if (biomes == null || biomes.length < w * h) + if (biomes.data == nullptr || biomes.length < w * h) { - if(biomes.data != nullptr) delete [] biomes.data; + if (biomes.data != nullptr) delete[] biomes.data; biomes = BiomeArray(w * h); } intArray result = layer->getArea(x, z, w, h); for (int i = 0; i < w * h; i++) { - biomes[i] = Biome::biomes[result[i]]; + biomes[i] = Biome::getBiome(result[i]); #ifndef _CONTENT_PACKAGE - if(biomes[i] == nullptr) + if (biomes[i] == nullptr) { app.DebugPrintf("Tried to assign null biome %d\n", result[i]); __debugbreak(); @@ -199,8 +192,6 @@ void BiomeSource::getRawBiomeBlock(BiomeArray &biomes, int x, int z, int w, int } } - - BiomeArray BiomeSource::getBiomeBlock(int x, int z, int w, int h) const { if (w == 16 && h == 16 && (x & 0xf) == 0 && (z & 0xf) == 0) @@ -212,14 +203,13 @@ BiomeArray BiomeSource::getBiomeBlock(int x, int z, int w, int h) const return biomes; } -// 4J - caller is responsible for deleting biomes array void BiomeSource::getBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h, bool useCache) const { IntCache::releaseAll(); - //if (biomes == null || biomes.length < w * h) + if (biomes.data == nullptr || biomes.length < w * h) { - if(biomes.data != nullptr) delete [] biomes.data; + if (biomes.data != nullptr) delete[] biomes.data; biomes = BiomeArray(w * h); } @@ -227,20 +217,17 @@ void BiomeSource::getBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h, { BiomeArray tmp = cache->getBiomeBlockAt(x, z); System::arraycopy(tmp, 0, &biomes, 0, w * h); - delete tmp.data; // MGH - added, the caching creates this array from the indices now. - //return biomes; + delete tmp.data; + // return; // если нужно только это, но у нас ниже ещё код? Оставим как было. } intArray result = zoomedLayer->getArea(x, z, w, h); for (int i = 0; i < w * h; i++) { - biomes[i] = Biome::biomes[result[i]]; + biomes[i] = Biome::getBiome(result[i]); } } - - - byteArray BiomeSource::getBiomeIndexBlock(int x, int z, int w, int h) const { if (w == 16 && h == 16 && (x & 0xf) == 0 && (z & 0xf) == 0) @@ -252,14 +239,13 @@ byteArray BiomeSource::getBiomeIndexBlock(int x, int z, int w, int h) const return biomeIndices; } -// 4J - caller is responsible for deleting biomes array void BiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, int w, int h, bool useCache) const { IntCache::releaseAll(); - //if (biomes == null || biomes.length < w * h) + if (biomeIndices.data == nullptr || biomeIndices.length < w * h) { - if(biomeIndices.data != nullptr) delete [] biomeIndices.data; + if (biomeIndices.data != nullptr) delete[] biomeIndices.data; biomeIndices = byteArray(w * h); } @@ -267,7 +253,7 @@ void BiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, int { byteArray tmp = cache->getBiomeIndexBlockAt(x, z); System::arraycopy(tmp, 0, &biomeIndices, 0, w * h); - //return biomes; + // return; } intArray result = zoomedLayer->getArea(x, z, w, h); @@ -277,14 +263,7 @@ void BiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, int } } -/** -* Checks if an area around a block contains only the specified biomes. -* Useful for placing elements like towns. -* -* This is a bit of a rough check, to make it as fast as possible. To ensure -* NO other biomes, add a margin of at least four blocks to the radius -*/ -bool BiomeSource::containsOnly(int x, int z, int r, vector allowed) +bool BiomeSource::containsOnly(int x, int z, int r, vector allowed) { IntCache::releaseAll(); int x0 = ((x - r) >> 2); @@ -298,21 +277,14 @@ bool BiomeSource::containsOnly(int x, int z, int r, vector allowed) intArray biomes = layer->getArea(x0, z0, w, h); for (int i = 0; i < w * h; i++) { - Biome *b = Biome::biomes[biomes[i]]; + Biome* b = Biome::getBiome(biomes[i]); if (find(allowed.begin(), allowed.end(), b) == allowed.end()) return false; } return true; } -/** -* Checks if an area around a block contains only the specified biome. -* Useful for placing elements like towns. -* -* This is a bit of a rough check, to make it as fast as possible. To ensure -* NO other biomes, add a margin of at least four blocks to the radius -*/ -bool BiomeSource::containsOnly(int x, int z, int r, Biome *allowed) +bool BiomeSource::containsOnly(int x, int z, int r, Biome* allowed) { IntCache::releaseAll(); int x0 = ((x - r) >> 2); @@ -322,24 +294,18 @@ bool BiomeSource::containsOnly(int x, int z, int r, Biome *allowed) int w = x1 - x0; int h = z1 - z0; - int biomesCount = w*h; + int biomesCount = w * h; intArray biomes = layer->getArea(x0, z0, w, h); for (unsigned int i = 0; i < biomesCount; i++) { - Biome *b = Biome::biomes[biomes[i]]; + Biome* b = Biome::getBiome(biomes[i]); if (allowed != b) return false; } return true; } -/** -* Finds the specified biome within the radius. This will return a random -* position if several are found. This test is fairly rough. -* -* Returns null if the biome wasn't found -*/ -TilePos *BiomeSource::findBiome(int x, int z, int r, Biome *toFind, Random *random) +TilePos* BiomeSource::findBiome(int x, int z, int r, Biome* toFind, Random* random) { IntCache::releaseAll(); int x0 = ((x - r) >> 2); @@ -350,14 +316,14 @@ TilePos *BiomeSource::findBiome(int x, int z, int r, Biome *toFind, Random *rand int w = x1 - x0 + 1; int h = z1 - z0 + 1; intArray biomes = layer->getArea(x0, z0, w, h); - TilePos *res = nullptr; + TilePos* res = nullptr; int found = 0; - int biomesCount = w*h; + int biomesCount = w * h; for (unsigned int i = 0; i < biomesCount; i++) { int xx = x0 + i % w; int zz = z0 + i / w; - Biome *b = Biome::biomes[biomes[i]]; + Biome* b = Biome::getBiome(biomes[i]); if (b == toFind) { if (res == nullptr || random->nextInt(found + 1) == 0) @@ -371,13 +337,7 @@ TilePos *BiomeSource::findBiome(int x, int z, int r, Biome *toFind, Random *rand return res; } -/** -* Finds one of the specified biomes within the radius. This will return a -* random position if several are found. This test is fairly rough. -* -* Returns null if the biome wasn't found -*/ -TilePos *BiomeSource::findBiome(int x, int z, int r, vector allowed, Random *random) +TilePos* BiomeSource::findBiome(int x, int z, int r, vector allowed, Random* random) { IntCache::releaseAll(); int x0 = ((x - r) >> 2); @@ -389,13 +349,13 @@ TilePos *BiomeSource::findBiome(int x, int z, int r, vector allowed, Ra int h = z1 - z0 + 1; MemSect(50); intArray biomes = layer->getArea(x0, z0, w, h); - TilePos *res = nullptr; + TilePos* res = nullptr; int found = 0; for (unsigned int i = 0; i < w * h; i++) { int xx = (x0 + i % w) << 2; int zz = (z0 + i / w) << 2; - Biome *b = Biome::biomes[biomes[i]]; + Biome* b = Biome::getBiome(biomes[i]); if (find(allowed.begin(), allowed.end(), b) != allowed.end()) { if (res == nullptr || random->nextInt(found + 1) == 0) @@ -416,177 +376,137 @@ void BiomeSource::update() cache->update(); } -//#define DEBUG_SEEDS 50 const int MAX_SEED_ATTEMPTS = 100; -// 4J added - find a seed for this biomesource that matches certain criteria #ifdef __PSVITA__ -int64_t BiomeSource::findSeed(LevelType *generator, bool* pServerRunning) // MGH - added pRunning, so we can early out of this on Vita as it can take up to 60 secs +int64_t BiomeSource::findSeed(LevelType* generator, bool* pServerRunning) #else -int64_t BiomeSource::findSeed(LevelType *generator) +int64_t BiomeSource::findSeed(LevelType* generator) #endif { + // Статический счетчик вызовов для уникальности начального seed генератора + static int64_t callCounter = 0; - int64_t bestSeed = 0; - - ProgressRenderer *mcprogress = Minecraft::GetInstance()->progressRenderer; + ProgressRenderer* mcprogress = Minecraft::GetInstance()->progressRenderer; mcprogress->progressStage(IDS_PROGRESS_NEW_WORLD_SEED); -#if 0//ndef _CONTENT_PACKAGE - if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<nextLong(); + lastSeed = seed; // сохраняем на случай неудачи + + BiomeSource* biomeSource = new BiomeSource(seed, generator); + + biomeSource->getRawBiomeIndices(indices, biomeOffset, biomeOffset, biomeWidth, biomeWidth); + getFracs(indices, toCompare); + + matchFound = getIsMatch(toCompare); + + if (matchFound) { - // Try and genuinely random this search up - Random *pr = new Random(System::nanoTime()); - - // Raw biome data has one result per 4x4 group of tiles. - // Removing a border of 8 from each side since we'll be doing special things at the edge to turn our world into an island, and so don't want to count things - // in the edge region in case they later get removed - static const int biomeWidth = ( 64 * 2 ) - 16; // Should be even so we can offset evenly - static const int biomeOffset = -( biomeWidth / 2 ); - - // Storage for our biome indices - intArray indices = intArray( biomeWidth * biomeWidth ); - - // Storage for the fractional amounts of each biome that will be calculated - float toCompare[Biome::BIOME_COUNT]; - - bool matchFound = false; - int tryCount = 0; - - // Just keeping trying to generate seeds until we find one that matches our criteria - do - { - int64_t seed = System::currentTimeMillis() ^ (tryCount << 32) ^ (int64_t)pr->nextLong(); - BiomeSource *biomeSource = new BiomeSource(seed,generator); - - biomeSource->getRawBiomeIndices(indices, biomeOffset, biomeOffset, biomeWidth, biomeWidth); - getFracs(indices, toCompare); - - matchFound = getIsMatch( toCompare ); - - if( matchFound ) bestSeed = seed; - - delete biomeSource; - tryCount++; - - mcprogress->progressStagePercentage( tryCount % 100 ); -#ifdef __PSVITA__ - } while (!matchFound && *pServerRunning && tryCount < MAX_SEED_ATTEMPTS); -#else - } while (!matchFound && tryCount < MAX_SEED_ATTEMPTS); -#endif - - // Clean up - delete pr; - delete indices.data; - -#if 1//def DEBUG_SEEDS - //app.DebugPrintf("%d: %d tries taken, seed used is %lld\n", k, tryCount, bestSeed); - - int size = 64 * 16; - - BiomeSource *biomeSource = new BiomeSource(bestSeed, generator); - BiomeArray biomes = biomeSource->getBiomeBlock(-27 * 16, -27 * 16, size, size); - - unsigned int *pixels = new unsigned int[size * size]; - for(int i = 0; i < size * size; i++ ) - { - int id = biomes[i]->id; - - // Create following colours: - // 0 ocean 0000 black - // 1 plains 0001 pastel cyan - // 2 desert 0010 green - // 3 extreme hills 0011 yellow - // 4 forest 0100 blue - // 5 taiga 0101 magenta - // 6 swamps 0110 cyan - // 7 river 0111 white - // 8 hell 1000 grey - // 9 end biome 1001 white - // 10 frozen ocean 1010 pastel green - // 11 frozen river 1011 pastel yellow - // 12 ice flats 1100 pastel blue - // 13 ice mountains 1101 pastel magenta - // 14 mushroom island 1110 red - // 15 mushroom shore 1111 pastel red - - if( id == 1 ) id = 14; - else if ( id == 14 ) id = 1; - else if( id == 9 ) id = 15; - else if( id == 15 ) id = 9; - pixels[i] = 0xff000000; - if( id & 1 ) pixels[i] |= 0x00ff0000; - if( id & 2 ) pixels[i] |= 0x0000ff00; - if( id & 4 ) pixels[i] |= 0x000000ff; - if( id & 8 ) pixels[i] |= 0x00808080; - } - D3DXIMAGE_INFO srcInfo; - //srcInfo.Format = D3DFMT_LIN_A8R8G8B8; - //srcInfo.ImageFileFormat = D3DXIFF_BMP; - srcInfo.Width = size; - srcInfo.Height = size; - - char buf[256]; - sprintf(buf,"GAME:\\BiomeTest%d.bmp", bestSeed); - RenderManager.SaveTextureData(buf, &srcInfo, (int *)pixels); - - delete [] pixels; - delete biomes.data; - delete biomeSource; -#endif + bestSeed = seed; } + + delete biomeSource; + tryCount++; + + mcprogress->progressStagePercentage(tryCount % 100); + +#ifdef __PSVITA__ + } while (!matchFound && *pServerRunning && tryCount < MAX_SEED_ATTEMPTS); +#else + } while (!matchFound && tryCount < MAX_SEED_ATTEMPTS); +#endif + + delete pr; + delete indices.data; + + // Если подходящий seed не найден, используем последний испытанный + if (!matchFound) + { + bestSeed = lastSeed; } + // Отладочная генерация изображения (оставлена как есть) + #if 1 + int size = 64 * 16; + BiomeSource* biomeSource = new BiomeSource(bestSeed, generator); + BiomeArray biomes = biomeSource->getBiomeBlock(-27 * 16, -27 * 16, size, size); + + unsigned int* pixels = new unsigned int[size * size]; + for (int i = 0; i < size * size; i++) + { + int id = biomes[i]->id; + if (id == 1) id = 14; + else if (id == 14) id = 1; + else if (id == 9) id = 15; + else if (id == 15) id = 9; + pixels[i] = 0xff000000; + if (id & 1) pixels[i] |= 0x00ff0000; + if (id & 2) pixels[i] |= 0x0000ff00; + if (id & 4) pixels[i] |= 0x000000ff; + if (id & 8) pixels[i] |= 0x00808080; + } + D3DXIMAGE_INFO srcInfo; + srcInfo.Width = size; + srcInfo.Height = size; + + char buf[256]; + sprintf(buf, "GAME:\\BiomeTest%d.bmp", bestSeed); + RenderManager.SaveTextureData(buf, &srcInfo, (int*)pixels); + + delete[] pixels; + delete biomes.data; + delete biomeSource; + #endif + return bestSeed; } -// 4J added - get the fractional amounts of each biome type in the given indices -void BiomeSource::getFracs(intArray indices, float *fracs) +void BiomeSource::getFracs(intArray indices, float* fracs) { - for( int i = 0; i < Biome::BIOME_COUNT; i++ ) + for (int i = 0; i < Biome::getBiomeCount(); i++) { fracs[i] = 0.0f; } - for( int i = 0; i < indices.length; i++ ) + for (int i = 0; i < indices.length; i++) { fracs[indices[i]] += 1.0f; } - for( int i = 0; i < Biome::BIOME_COUNT; i++ ) + for (int i = 0; i < Biome::getBiomeCount(); i++) { fracs[i] /= static_cast(indices.length); } } - - -// 4J added - determine if this particular set of fractional amounts of biome types matches are requirements bool BiomeSource::getIsMatch(float* frac) { // Океан может занимать до 50% if (frac[0] > 0.5f) return false; - // Основные биомы, которые должны присутствовать - //static const int required[] = { 1, 2, 4, 5 }; // plains, desert, forest, taiga - //for (int i : required) { - // if (frac[i] < 0.01f) return false; - //} - int typeCount = 0; - for (int i = 0; i < Biome::BIOME_COUNT; i++) { + for (int i = 0; i < Biome::getBiomeCount(); i++) { if (i == 15 || i == 17 || i == 18 || i == 19 || i == 22) continue; if (frac[i] > 0.001f) typeCount++; } - return typeCount >= 6; + return typeCount >= 12; } diff --git a/Minecraft.World/BirchFeature.cpp b/Minecraft.World/BirchFeature.cpp index 3c423564a..04fe2f5eb 100644 --- a/Minecraft.World/BirchFeature.cpp +++ b/Minecraft.World/BirchFeature.cpp @@ -9,7 +9,7 @@ BirchFeature::BirchFeature(bool doUpdate) : Feature(doUpdate) bool BirchFeature::place(Level *level, Random *random, int x, int y, int z) { - int treeHeight = random->nextInt(3) + 5; + int treeHeight = random->nextInt(8) + 5; bool free = true; if (y < 1 || y + treeHeight + 1 > Level::maxBuildHeight) return false; diff --git a/Minecraft.World/BirchForestBiome.cpp b/Minecraft.World/BirchForestBiome.cpp new file mode 100644 index 000000000..00d0401ea --- /dev/null +++ b/Minecraft.World/BirchForestBiome.cpp @@ -0,0 +1,17 @@ +#include "stdafx.h" +#include "net.minecraft.world.level.levelgen.feature.h" +#include "net.minecraft.world.level.biome.h" +#include "net.minecraft.world.entity.animal.h" +#include "net.minecraft.world.entity.h" +#include "BirchForestBiome.h" + +BirchForestBiome::BirchForestBiome(int id) : Biome(id) +{ + decorator->treeCount = 10; + decorator->grassCount = 2; +} + +Feature* BirchForestBiome::getTreeFeature(Random* random) +{ + return new BirchFeature(false); +} diff --git a/Minecraft.World/BirchForestBiome.h b/Minecraft.World/BirchForestBiome.h new file mode 100644 index 000000000..b0543f9bd --- /dev/null +++ b/Minecraft.World/BirchForestBiome.h @@ -0,0 +1,10 @@ +#pragma once +#include "Biome.h" + +class BirchForestBiome : public Biome +{ +public: + BirchForestBiome(int id); + + virtual Feature* getTreeFeature(Random* random); +}; diff --git a/Minecraft.World/Layer.cpp b/Minecraft.World/Layer.cpp index 1f71f0e0b..57d2bc582 100644 --- a/Minecraft.World/Layer.cpp +++ b/Minecraft.World/Layer.cpp @@ -21,43 +21,44 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType *levelType) // 4J - Some changes moved here from 1.2.3. Temperature & downfall layers are no longer created & returned, and a debug layer is isn't. // For reference with regard to future merging, things NOT brought forward from the 1.2.3 version are new layer types that we // don't have yet (shores, swamprivers, region hills etc.) - shared_ptrislandLayer = std::make_shared(1); + shared_ptrislandLayer = std::make_shared(seed); islandLayer = std::make_shared(2000, islandLayer); - islandLayer = std::make_shared(1, islandLayer); + islandLayer = std::make_shared(seed, islandLayer); islandLayer = std::make_shared(2001, islandLayer); - islandLayer = std::make_shared(2, islandLayer); + islandLayer = std::make_shared(seed + 1, islandLayer); islandLayer = std::make_shared(2, islandLayer); islandLayer = std::make_shared(2002, islandLayer); - islandLayer = std::make_shared(3, islandLayer); + islandLayer = std::make_shared(seed + 2, islandLayer); islandLayer = std::make_shared(2003, islandLayer); - islandLayer = std::make_shared(4, islandLayer); - islandLayer = shared_ptr(new AddMushroomIslandLayer(5, islandLayer)); // 4J - old position of mushroom island layer + islandLayer = std::make_shared(seed + 3, islandLayer); + islandLayer = shared_ptr(new AddMushroomIslandLayer(seed + 4, islandLayer)); // 4J - old position of mushroom island layer int zoomLevel = 4; - if (levelType == LevelType::lvl_largeBiomes) - { - zoomLevel = 6; - } + //if (levelType == LevelType::lvl_largeBiomes) + //{ + //zoomLevel = 6; + //} shared_ptr riverLayer = std::make_shared(100, islandLayer); riverLayer = ZoomLayer::zoom(1000, riverLayer, 0); - riverLayer = std::make_shared(100, riverLayer); + riverLayer = std::make_shared(seed + 100, riverLayer); riverLayer = ZoomLayer::zoom(1000, riverLayer, zoomLevel + 2); - riverLayer = std::make_shared(1, riverLayer); + riverLayer = std::make_shared(seed + 1, riverLayer); riverLayer = std::make_shared(1000, riverLayer); shared_ptr biomeLayer = islandLayer; biomeLayer = ZoomLayer::zoom(1000, biomeLayer, 0); - biomeLayer = std::make_shared(200, biomeLayer, levelType); + biomeLayer = std::make_shared(200, biomeLayer, LevelType::lvl_largeBiomes); biomeLayer = ZoomLayer::zoom(1000, biomeLayer, 2); - biomeLayer = std::make_shared(1000, biomeLayer); + biomeLayer = std::make_shared(500, biomeLayer); for (int i = 0; i < zoomLevel; i++) { biomeLayer = std::make_shared(1000 + i, biomeLayer); - if (i == 0) biomeLayer = std::make_shared(3, biomeLayer); + if (i == 0) + biomeLayer = std::make_shared(3, biomeLayer); if (i == 0) { @@ -95,7 +96,7 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType *levelType) shared_ptr debugLayer = biomeLayer; - shared_ptrzoomedLayer = std::make_shared(20, biomeLayer); + shared_ptrzoomedLayer = std::make_shared(10, biomeLayer); biomeLayer->init(seed); zoomedLayer->init(seed); diff --git a/Minecraft.World/RandomLevelSource.cpp b/Minecraft.World/RandomLevelSource.cpp index a0e7a94bb..95cba6d84 100644 --- a/Minecraft.World/RandomLevelSource.cpp +++ b/Minecraft.World/RandomLevelSource.cpp @@ -48,8 +48,8 @@ RandomLevelSource::RandomLevelSource(Level *level, int64_t seed, bool generateSt perlinNoise1 = new PerlinNoise(random, 8); perlinNoise3 = new PerlinNoise(random, 4); - scaleNoise = new PerlinNoise(random, 10); - depthNoise = new PerlinNoise(random, 16); + scaleNoise = new PerlinNoise(random, 8); + depthNoise = new PerlinNoise(random, 14); if (FLOATING_ISLANDS) { diff --git a/Minecraft.World/net.minecraft.world.level.biome.h b/Minecraft.World/net.minecraft.world.level.biome.h index dc082d702..b493fb97b 100644 --- a/Minecraft.World/net.minecraft.world.level.biome.h +++ b/Minecraft.World/net.minecraft.world.level.biome.h @@ -3,6 +3,7 @@ #include "Biome.h" #include "ForestBiome.h" +#include "BirchForestBiome.h" #include "HellBiome.h" #include "RainforestBiome.h" #include "IceBiome.h"