mfeat(TU31): add new biomes and fix existing ones.

This commit is contained in:
piebot 2026-04-26 17:13:42 +03:00
commit 349b98640f
32 changed files with 1273 additions and 855 deletions

View file

@ -0,0 +1,33 @@
#pragma once
#include "Feature.h"
#include "Level.h"
#include "Tile.h"
class AbstractTreeFeature : public Feature
{
public:
AbstractTreeFeature(bool doUpdate) : Feature(doUpdate) {}
virtual ~AbstractTreeFeature() {}
static bool isFree(Level* level, int x, int y, int z)
{
int tile = level->getTile(x, y, z);
return tile == 0
|| tile == Tile::leaves_Id
|| tile == Tile::leaves2_Id
|| tile == Tile::treeTrunk_Id
|| tile == Tile::tree2Trunk_Id
|| tile == Tile::vine_Id
|| tile == Tile::tallgrass_Id
|| tile == Tile::flower_Id;
}
void setDirtAt(Level* level, int x, int y, int z)
{
if (level->getTile(x, y, z) != Tile::dirt_Id)
{
placeBlock(level, x, y, z, Tile::dirt_Id, 0);
}
}
virtual void postPlaceTree() {}
};

View file

@ -14,7 +14,7 @@ intArray AddIslandLayer::getArea(int xo, int yo, int w, int h)
int pw = w + 2;
int ph = h + 2;
intArray p = parent->getArea(px, py, pw, ph);
PIXBeginNamedEvent(0.0, "AddIslandLayer::getArea");
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
{
@ -40,7 +40,7 @@ intArray AddIslandLayer::getArea(int xo, int yo, int w, int h)
}
else
{
if (swap == Biome::iceFlats->id) result[x + y * w] = Biome::frozenOcean->id;
if (swap == 4) result[x + y * w] = Biome::frozenOcean->id;
else result[x + y * w] = 0;
}
}
@ -48,7 +48,7 @@ intArray AddIslandLayer::getArea(int xo, int yo, int w, int h)
{
if (nextRandom(5) == 0)
{
if (c == Biome::iceFlats->id) result[x + y * w] = Biome::frozenOcean->id;
if (c == 4) result[x + y * w] = Biome::frozenOcean->id;
else result[x + y * w] = 0;
}
else result[x + y * w] = c;
@ -59,6 +59,6 @@ intArray AddIslandLayer::getArea(int xo, int yo, int w, int h)
}
}
}
PIXEndNamedEvent();
return result;
}

View file

@ -28,8 +28,9 @@ intArray AddSnowLayer::getArea(int xo, int yo, int w, int h)
}
else
{
int r = nextRandom(5);
if (r == 0) r = Biome::iceFlats->id;
int r = nextRandom(6);
if (r == 0) r = 4;
else if (r <= 1) r = 3;
else r = 1;
result[x + y * w] = r;
}

View file

@ -12,7 +12,7 @@
#include "PerlinNoise.h"
Biome *Biome::biomes[256];
Biome *Biome::biomes[257];
Biome *Biome::ocean = nullptr;//0
Biome *Biome::plains = nullptr;//1
@ -120,6 +120,8 @@ void Biome::staticCtor()
Biome::coldTaigaHills = (new TaigaBiome(31))->setColor(0x163933)->setName(L"Cold Taiga Hills")->setLeafColor(0x4EBA31)->setSnowCovered()->setTemperatureAndDownfall(-0.5f, 0.4f)->setDepthAndScale(0.3f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_TaigaHills, eMinecraftColour_Foliage_TaigaHills, eMinecraftColour_Water_TaigaHills,eMinecraftColour_Sky_TaigaHills);
Biome::megaTaiga = (new TaigaBiome(32,1))->setColor(0x0b6659)->setName(L"Mega Taiga")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.3f, 0.8f)->setDepthAndScale(0.1f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga);
Biome::megaTaigaHills = (new TaigaBiome(33,2))->setColor(0x0b6659)->setName(L"Mega Taiga Hills")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.3f, 0.8f)->setDepthAndScale(0.3f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_TaigaHills, eMinecraftColour_Foliage_TaigaHills, eMinecraftColour_Water_TaigaHills,eMinecraftColour_Sky_TaigaHills);
Biome::extremeHills_plus = (new ExtremeHillsBiome(34, true))->setColor(0x507050)->setName(L"Extreme Hills+")->setDepthAndScale(0.3f, 1.5f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills,eMinecraftColour_Foliage_ExtremeHills,eMinecraftColour_Water_ExtremeHills, eMinecraftColour_Sky_ExtremeHills);
Biome::savanna = (new SavannaBiome(35))->setColor(0xbda235)->setName(L"Savanna")->setNoRain()->setTemperatureAndDownfall(1.2f, 0.0f) ->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Savanna, eMinecraftColour_Foliage_Savanna, eMinecraftColour_Sky_Desert, eMinecraftColour_Sky_Desert);
Biome::savannaPlateau = (new SavannaBiome(36))->setColor(0xa79d64)->setName(L"Savanna Plateau")->setNoRain()->setTemperatureAndDownfall(1.0f, 0.0f)->setDepthAndScale(1.5f, 0.025f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Savanna, eMinecraftColour_Foliage_Savanna, eMinecraftColour_Sky_Desert, eMinecraftColour_Sky_Desert);
@ -128,16 +130,25 @@ void Biome::staticCtor()
Biome::mesaPlateau = (new MesaBiome(39, true, false))->setColor(0xca5936)->setName(L"Mesa Plateau")->setDepthAndScale(1.5f, 0.025f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert);
Biome::sunflowersPlains = (new PlainsBiome(129,true))->setColor(0x8db360)->setName(L"Sunflowers Plains")->setTemperatureAndDownfall(0.8f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Plains, eMinecraftColour_Foliage_Plains, eMinecraftColour_Water_Plains,eMinecraftColour_Sky_Plains);
Biome::extremeHillsM = static_cast<ExtremeHillsBiome*>(Biome::biomes[3])->createMutatedBiome(131)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills, eMinecraftColour_Foliage_ExtremeHills, eMinecraftColour_Water_ExtremeHills,eMinecraftColour_Sky_ExtremeHills);
Biome::flowerForest = (new ForestBiome(132, 1))->setColor(0x056621)->setName(L"Flower Forest")->setTemperatureAndDownfall(0.7f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Forest, eMinecraftColour_Water_Forest,eMinecraftColour_Sky_Forest);
Biome::desertM = (new DesertBiome(130))->setColor(0xFA9418)->setName(L"Desert M")->setNoRain()->setTemperatureAndDownfall(2, 0)->setDepthAndScale(0.225f, 0.25f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Desert, eMinecraftColour_Foliage_Desert, eMinecraftColour_Water_Desert,eMinecraftColour_Sky_Desert);
Biome::taigaM = (new TaigaBiome(133))->setColor(0x0b6659)->setName(L"Taiga M")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.25f, 0.8f)->setDepthAndScale(0.3f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga);
Biome::swamplandM = (new SwampBiome(134))->setColor(0x07F9B2)->setName(L"Swampland M")->setLeafColor(0x8BAF48)->setDepthAndScale(-0.1f, 0.3f)->setTemperatureAndDownfall(0.8f, 0.9f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Swampland, eMinecraftColour_Foliage_Swampland, eMinecraftColour_Water_Swampland,eMinecraftColour_Sky_Swampland);
Biome::iceSpikes = (new IceBiome(140,true))->setColor(0xffffff)->setName(L"Ice Spikes")->setSnowCovered()->setTemperatureAndDownfall(0, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_IcePlains, eMinecraftColour_Foliage_IcePlains, eMinecraftColour_Water_IcePlains,eMinecraftColour_Sky_IcePlains);
Biome::jungleM = (new JungleBiome(149, false))->setColor(0x537b09)->setName(L"Jungle M")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(0.2f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_Jungle,eMinecraftColour_Sky_Jungle);
Biome::jungleEdgeM = (new JungleBiome(151, true))->setColor(0x6458135)->setName(L"Jungle Edge M")->setLeafColor(0x5470985)->setTemperatureAndDownfall(0.95F, 0.8F);
Biome::birchForestM=(new ForestBiome::MutatedBirchForestBiome(155, biomes[27]))->setColor(0x47875a)->setName(L"Birch Forest M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest);
Biome::birchForestHillsM=(new ForestBiome::MutatedBirchForestBiome(156, biomes[28]))->setColor(0x47875a)->setName(L"Birch Forest Hills M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_ForestHills);
Biome::roofedForestM=(new ForestBiome::MutatedForestBiome(157, biomes[29]))->setColor(0x177a35)->setName(L"Roofed Forest M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_RoofedForest, eMinecraftColour_Foliage_RoofedForest, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest);
Biome::coldTaigaM = (new TaigaBiome(158))->setColor(0x0b6659)->setName(L"Cold Taiga M")->setLeafColor(0x4EBA31)->setSnowCovered()->setTemperatureAndDownfall(-0.5f, 0.4f)->setDepthAndScale(0.3f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga);
Biome::redwoodTaiga = (new TaigaBiome(160, 1))->setColor(0x0b6659)->setName(L"Mega Spruce Taiga")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.3f, 0.8f)->setDepthAndScale(0.2f, 0.2f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga);
Biome::redwoodTaigaHills = (new TaigaBiome(161, 2))->setColor(0x0b6659)->setName(L"Mega Spruce Taiga Hills")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.3f, 0.8f)->setDepthAndScale(0.2f, 0.2f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga);
Biome::extremeHills_plusM = static_cast<ExtremeHillsBiome*>(Biome::biomes[34])->createMutatedBiome(162)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills,eMinecraftColour_Foliage_ExtremeHills,eMinecraftColour_Water_ExtremeHills, eMinecraftColour_Sky_ExtremeHills);
Biome::savannaM = (new MutatedSavannaBiome(163, biomes[35]))->setColor(0xe5da87)->setName(L"Savanna M")->setNoRain()->setTemperatureAndDownfall(1.1f, 0.0f)->setDepthAndScale(0.35f, 1.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Savanna, eMinecraftColour_Foliage_Savanna, eMinecraftColour_Sky_Desert, eMinecraftColour_Sky_Desert);
Biome::savannaPlateauM = (new MutatedSavannaBiome(164, biomes[36]))->setColor(0xd1c890)->setName(L"Savanna Plateau M")->setNoRain()->setTemperatureAndDownfall(1.0f, 0.0f)->setDepthAndScale(1.05f, 1.2125f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Savanna, eMinecraftColour_Foliage_Savanna, eMinecraftColour_Sky_Desert, eMinecraftColour_Sky_Desert);
Biome::mesaBryce = (new MesaBiome(165, false, false))->setColor(0xd94515)->setName(L"Mesa (Bryce)")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert);
Biome::mesaBryce = (new MesaBiome(165, true, false))->setColor(0xd94515)->setName(L"Mesa (Bryce)")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert);
Biome::mesaPlateauFM = (new MesaBiome(166, true, true))->setColor(0xb09765)->setName(L"Mesa Plateau F M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert);
Biome::mesaPlateauM = (new MesaBiome(167, true, false))->setColor(0xca5936)->setName(L"Mesa Plateau M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Mesa, eMinecraftColour_Foliage_Mesa, eMinecraftColour_Water_Mesa, eMinecraftColour_Sky_Desert);
@ -381,23 +392,25 @@ float Biome::getTemperature(int x, int y, int z)
void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal)
{
byte topState = this->topMaterial;
byte fillerState = this->material;
int runDepth = -1;
byte topState = this->topMaterial;
byte topStateData = this->topMaterialData;
byte fillerState = this->material;
byte fillerStateData = this->materialData;
int runDepth = -1;
int noiseDepth = (int)(noiseVal / 3.0 + 3.0 + random->nextDouble() * 0.25);
int localX = x & 15;
int localZ = z & 15;
int seaLevel = level->seaLevel;
for (int y = Level::genDepthMinusOne; y >= 0; --y)
const int SEA_LEVEL = 63;
for (int y = 127; y >= 0; --y)
{
int index = (localZ * 16 + localX) * Level::genDepth + y;
if (y <= 1 + random->nextInt(2))
if (y <= 1 + random->nextInt(2))
{
chunkBlocks[index] = static_cast<byte>(Tile::unbreakable_Id);
chunkBlocks[index] = static_cast<byte>(Tile::unbreakable_Id);
continue;
}
@ -409,41 +422,47 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock
}
else if (currentBlockId == static_cast<byte>(Tile::stone_Id))
{
if (runDepth == -1)
if (runDepth == -1)
{
if (noiseDepth <= 0)
{
topState = 0;
fillerState = static_cast<byte>(Tile::stone_Id);
topState = 0;
topStateData = 0;
fillerState = static_cast<byte>(Tile::stone_Id);
fillerStateData = 0;
}
else if (y >= seaLevel - 4 && y <= seaLevel + 1)
else if (y >= SEA_LEVEL - 7 - noiseDepth && y < SEA_LEVEL - 1)
{
topState = this->topMaterial;
fillerState = this->material;
topState = this->topMaterial;
topStateData = this->topMaterialData;
fillerState = this->material;
fillerStateData = this->materialData;
}
if (y < seaLevel && topState == 0)
if (y < SEA_LEVEL && topState == 0)
{
if (this->getTemperature(x, y, z) < 0.15f) {
if (this->getTemperature(x, y, z) < 0.15f)
topState = static_cast<byte>(Tile::ice_Id);
} else {
topState = static_cast<byte>(Tile::calmWater_Id);
}
else
topState = static_cast<byte>(Tile::calmWater_Id);
topStateData = 0;
}
runDepth = noiseDepth;
if (y >= seaLevel - 1)
if (y >= SEA_LEVEL - 1)
{
chunkBlocks[index] = topState;
}
else if (y < seaLevel - 7 - noiseDepth)
else if (y < SEA_LEVEL - 7 - noiseDepth)
{
topState = 0;
fillerState = static_cast<byte>(Tile::stone_Id);
topState = 0;
topStateData = 0;
fillerState = static_cast<byte>(Tile::stone_Id);
fillerStateData = 0;
chunkBlocks[index] = static_cast<byte>(Tile::gravel_Id);
}
else
else
{
chunkBlocks[index] = fillerState;
}
@ -455,8 +474,17 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock
if (runDepth == 0 && fillerState == static_cast<byte>(Tile::sand_Id))
{
runDepth = random->nextInt(4) + (y - 63 > 0 ? y - 63 : 0);
fillerState = static_cast<byte>(Tile::sandStone_Id);
runDepth = random->nextInt(4);
if (fillerStateData == 1)
{
fillerState = static_cast<byte>(Tile::red_sandstone_Id);
fillerStateData = 0;
}
else
{
fillerState = static_cast<byte>(Tile::sandStone_Id);
fillerStateData = 0;
}
}
}
}

View file

@ -27,7 +27,7 @@ class Biome
public:
static void staticCtor();
static Biome *biomes[256];
static Biome *biomes[257];
static Biome *ocean;
static Biome *plains;
@ -227,6 +227,6 @@ public:
virtual int getGrassColor() const;
virtual Feature *getFlowerFeature(Random *random, int x, int y, int z);
virtual int getRandomDoublePlantType(Random *random);
Biome* getBiome(uint32_t id);
Biome* getBiome(uint32_t id, Biome* fallback);
static Biome* getBiome(uint32_t id);
static Biome* getBiome(uint32_t id, Biome* fallback);
};

View file

@ -3,69 +3,72 @@
#include "net.minecraft.world.level.newbiome.layer.h"
#include "net.minecraft.world.level.h"
#include "BiomeInitLayer.h"
#include "Biome.h"
struct CustomizableSourceSettings {
char pad[100];
int biome;
};
BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup, LevelType *levelType, void* superflatConfig) : Layer(seedMixup)
{
this->parent = parent;
bLegacy1_1 = (levelType == LevelType::lvl_normal_1_1);
if (bLegacy1_1)
{
// 1.1 mode: flat list
startBiomes = BiomeArray(6);
startBiomes[0] = Biome::desert;
startBiomes[1] = Biome::forest;
startBiomes[2] = Biome::extremeHills;
startBiomes[3] = Biome::swampland;
startBiomes[4] = Biome::plains;
startBiomes[5] = Biome::taiga;
}
else
{
//
// RareBiomeLayer encodes a flag by setting k = plains->id + 128
// When rareBit is set and we would pick plains -> pick sunflowersPlains
// desert biomes (Java: desert 30, savanna 20, plains 10 -> total 60)
desertBiomes = BiomeArray(6);
desertBiomes[0] = Biome::desert;
this->parent = parent;
this->customSettings = nullptr;
desertBiomes = BiomeArray(6);
warmBiomes = BiomeArray(6);
coolBiomes = BiomeArray(4);
icyBiomes = BiomeArray(4);
if (levelType == LevelType::lvl_normal_1_1)
{
desertBiomes[0] = Biome::desert;
desertBiomes[1] = Biome::forest;
desertBiomes[2] = Biome::extremeHills;
desertBiomes[3] = Biome::swampland;
desertBiomes[4] = Biome::plains;
desertBiomes[5] = Biome::taiga;
}
else
{
desertBiomes[0] = Biome::desert;
desertBiomes[1] = Biome::desert;
desertBiomes[2] = Biome::desert;
desertBiomes[3] = Biome::savanna;
desertBiomes[4] = Biome::savanna;
desertBiomes[5] = Biome::plains;
}
// warm biomes (Java: forest, swamp, jungle, roofedForest, birchForest, plains...)
warmBiomes = BiomeArray(7);
warmBiomes[0] = Biome::forest;
warmBiomes[1] = Biome::swampland;
warmBiomes[2] = Biome::jungle;
warmBiomes[3] = Biome::roofedForest;
warmBiomes[0] = Biome::forest;
warmBiomes[1] = Biome::roofedForest;
warmBiomes[2] = Biome::extremeHills;
warmBiomes[3] = Biome::plains;
warmBiomes[4] = Biome::birchForest;
warmBiomes[5] = Biome::plains;
warmBiomes[6] = Biome::mesaPlateauF;
warmBiomes[5] = Biome::swampland;
// cool (Java: extremeHills, taiga, megaTaiga, forest, birchForest)
coolBiomes = BiomeArray(5);
coolBiomes[0] = Biome::extremeHills;
coolBiomes[1] = Biome::taiga;
coolBiomes[2] = Biome::megaTaiga;
coolBiomes[3] = Biome::forest;
coolBiomes[4] = Biome::birchForest;
// icy (Java: iceFlats, coldTaiga)
icyBiomes = BiomeArray(3);
coolBiomes[0] = Biome::forest;
coolBiomes[1] = Biome::extremeHills;
coolBiomes[2] = Biome::taiga;
coolBiomes[3] = Biome::plains;
icyBiomes[0] = Biome::iceFlats;
icyBiomes[1] = Biome::iceFlats;
icyBiomes[2] = Biome::coldTaiga;
}
icyBiomes[2] = Biome::iceFlats;
icyBiomes[3] = Biome::coldTaiga;
if (levelType != LevelType::lvl_normal_1_1 && levelType == LevelType::lvl_customized)
{
this->customSettings = (CustomizableSourceSettings*)superflatConfig;
}
}
BiomeInitLayer::~BiomeInitLayer()
{
delete [] startBiomes.data;
delete [] desertBiomes.data;
delete [] warmBiomes.data;
delete [] coolBiomes.data;
@ -74,103 +77,98 @@ BiomeInitLayer::~BiomeInitLayer()
intArray BiomeInitLayer::getArea(int xo, int yo, int w, int h)
{
intArray b = parent->getArea(xo, yo, w, h);
intArray b = parent->getArea(xo, yo, w, h);
intArray result = IntCache::allocate(w * h);
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
initRandom(x + xo, y + yo);
int k = b[x + y * w];
if (h > 0)
{
for (int y = 0; y < h; y++)
{
if (w > 0)
{
for (int x = 0; x < w; x++)
{
initRandom(x + xo, y + yo);
// flat list
if (bLegacy1_1)
{
if (k == 0)
{
result[x + y * w] = 0;
}
else if (k == Biome::mushroomIsland->id)
{
result[x + y * w] = k;
}
else if (k == 1)
{
result[x + y * w] = startBiomes[nextRandom(startBiomes.length)]->id;
}
else // icy / cold
{
int picked = startBiomes[nextRandom(startBiomes.length)]->id;
if (picked == Biome::taiga->id || picked == Biome::coldTaiga->id ||
picked == Biome::megaTaiga->id || picked == Biome::iceSpikes->id)
{
result[x + y * w] = picked;
}
else
{
result[x + y * w] = Biome::iceFlats->id;
}
}
continue;
}
int val = b[x + y * w];
int v18 = (val >> 8) & 0xF;
int v19 = val & 0xFFFFF0FF;
if (customSettings && customSettings->biome >= 0)
{
result[x + y * w] = customSettings->biome;
continue;
}
// RareBiomeLayer sets k = plains->id + 128 when it picks a rare slot.
// plains->id = 1, so a rare plains = 129. We extract the high bits flag.
int rareBit = (k & 3840) >> 8; // Java: (k & 0xF00) >> 8
k = k & ~3840;
if (isOcean(v19) || v19 == Biome::mushroomIsland->id)
{
result[x + y * w] = v19;
continue;
}
if (k == 0 || k == Biome::ocean->id || k == Biome::deepOcean->id ||
k == Biome::frozenOcean->id || k == Biome::frozenRiver->id)
{
result[x + y * w] = k;
}
else if (k == Biome::mushroomIsland->id || k == Biome::mushroomIslandShore->id)
{
result[x + y * w] = k;
}
// Climate 1 & 2 & 3
else if (k == 1 || k == 2 || k == 3)
{
if (rareBit > 0)
{
// If rare: pick from high-value variants
int r = nextRandom(3);
if (r == 0) result[x + y * w] = Biome::jungle->id;
else if (r == 1) result[x + y * w] = Biome::megaTaiga->id;
else result[x + y * w] = Biome::desertHills->id;
}
else
{
int r = nextRandom(20);
if (r < 6) result[x + y * w] = desertBiomes[nextRandom(desertBiomes.length)]->id;
else if (r < 13) result[x + y * w] = warmBiomes[nextRandom(warmBiomes.length)]->id;
else result[x + y * w] = coolBiomes[nextRandom(coolBiomes.length)]->id;
}
}
// Climate 4
else if (k == 4 || k == Biome::iceFlats->id)
{
result[x + y * w] = icyBiomes[nextRandom(icyBiomes.length)]->id;
}
// Rare variant from RareBiomeLayer
else if (k == Biome::plains->id + 128)
{
result[x + y * w] = Biome::sunflowersPlains->id;
}
else
{
result[x + y * w] = k;
}
}
}
if (v19 == 1)
{
if (v18 <= 0)
{
result[x + y * w] = desertBiomes[nextRandom(desertBiomes.length)]->id;
}
else if (nextRandom(3) != 0)
{
result[x + y * w] = Biome::mesaPlateauF->id;
}
else
{
result[x + y * w] = Biome::mesaPlateau->id;
}
}
else if (v19 == 2)
{
if (v18 <= 0)
{
result[x + y * w] = warmBiomes[nextRandom(warmBiomes.length)]->id;
}
else
{
result[x + y * w] = Biome::jungle->id;
}
}
else if (v19 == 3)
{
if (v18 <= 0)
{
result[x + y * w] = coolBiomes[nextRandom(coolBiomes.length)]->id;
}
else
{
result[x + y * w] = Biome::megaTaiga->id;
}
}
return result;
else if (v19 == 4)
{
result[x + y * w] = icyBiomes[nextRandom(icyBiomes.length)]->id;
}
else
{
result[x + y * w] = v19;
}
}
}
}
}
return result;
}

View file

@ -1,25 +1,24 @@
#pragma once
#include "Layer.h"
#include <vector>
class LevelType;
class Biome;
struct CustomizableSourceSettings;
class BiomeInitLayer : public Layer
{
private:
BiomeArray startBiomes;
// matching Java GenLayerBiome
BiomeArray desertBiomes;
BiomeArray warmBiomes;
BiomeArray coolBiomes;
BiomeArray icyBiomes;
bool bLegacy1_1;
BiomeArray desertBiomes;
BiomeArray warmBiomes;
BiomeArray coolBiomes;
BiomeArray icyBiomes;
CustomizableSourceSettings* customSettings;
public:
BiomeInitLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup, LevelType *levelType, void* superflatConfig);
virtual ~BiomeInitLayer();
intArray getArea(int xo, int yo, int w, int h);
};
BiomeInitLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup, LevelType *levelType, void* superflatConfig);
virtual ~BiomeInitLayer();
intArray getArea(int xo, int yo, int w, int h) override;
};

View file

@ -15,11 +15,11 @@ void BiomeSource::_init()
generatorOptions = L"";
cache = new BiomeCache(this);
playerSpawnBiomes.push_back(Biome::plains);
playerSpawnBiomes.push_back(Biome::forest);
playerSpawnBiomes.push_back(Biome::taiga);
playerSpawnBiomes.push_back(Biome::plains);
playerSpawnBiomes.push_back(Biome::taigaHills);
playerSpawnBiomes.push_back(Biome::forestHills);
playerSpawnBiomes.push_back(Biome::taigaHills);
playerSpawnBiomes.push_back(Biome::jungle);
playerSpawnBiomes.push_back(Biome::jungleHills);
}

View file

@ -15,6 +15,7 @@ intArray DeepOceanLayer::getArea(int xo, int yo, int w, int h)
int k = w + 2;
int l = h + 2;
intArray aint = this->parent->getArea(i, j, k, l);
PIXBeginNamedEvent(0.0, "AddDeepOceanLayer::getArea");
intArray aint1 = IntCache::allocate(w * h);
for (int i1 = 0; i1 < h; ++i1)
@ -58,6 +59,6 @@ intArray DeepOceanLayer::getArea(int xo, int yo, int w, int h)
}
}
}
PIXEndNamedEvent();
return aint1;
}

View file

@ -54,4 +54,22 @@ public:
return 0;
}
};
class Plane
{
public:
static int getRandomFace(Random* random)
{
static const int horizontal[4] = {
Direction::SOUTH,
Direction::WEST,
Direction::NORTH,
Direction::EAST
};
return horizontal[random->nextInt(4)];
}
};
};

View file

@ -1,85 +1,98 @@
#include "stdafx.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.tile.h"
#include "net.minecraft.world.level.levelgen.feature.h"
#include "ExtremeHillsBiome.h"
#include "BiomeDecorator.h"
#include "SpruceFeature.h"
#include "TreeFeature.h"
ExtremeHillsBiome::ExtremeHillsBiome(int id) : ExtremeHillsBiome(id, false)
{
}
ExtremeHillsBiome::ExtremeHillsBiome(int id, bool extraTrees) : Biome(id)
{
silverfishFeature = new OreFeature(Tile::monsterStoneEgg_Id, 8);
taigaFeature = new SpruceFeature(false);
friendlies.clear();
type = 0;
if (extraTrees)
{
decorator->treeCount = 3;
type = 1;
}
silverfishFeature = new OreFeature(Tile::monsterStoneEgg_Id, 9);
taigaFeature = new SpruceFeature(false);
friendlies.clear();
type = TYPE_NORMAL;
if (extraTrees)
{
decorator->treeCount = 3;
type = TYPE_TREES;
}
}
ExtremeHillsBiome::~ExtremeHillsBiome()
{
delete silverfishFeature;
delete taigaFeature;
delete silverfishFeature;
delete taigaFeature;
}
Feature *ExtremeHillsBiome::getTreeFeature(Random *random)
Feature* ExtremeHillsBiome::getTreeFeature(Random* random)
{
if (random->nextInt(3) > 0)
{
return new SpruceFeature(false);
}
return Biome::getTreeFeature(random);
if (random->nextInt(3) > 0)
{
return new SpruceFeature(false);
}
return Biome::getTreeFeature(random);
}
void ExtremeHillsBiome::decorate(Level *level, Random *random, int xo, int zo) {
Biome::decorate(level, random, xo, zo);
if (GENERATE_EMERALD_ORE)
{
int emeraldCount = 3 + random->nextInt(6);
for (int d = 0; d < emeraldCount; d++)
{
int x = xo + random->nextInt(16);
int y = random->nextInt((Level::genDepth / 4) - 4) + 4;
int z = zo + random->nextInt(16);
int tile = level->getTile(x, y, z);
if (tile == Tile::stone_Id)
{
level->setTileAndData(x, y, z, Tile::emeraldOre_Id, 0, Tile::UPDATE_CLIENTS);
}
}
}
for (int i = 0; i < 7; i++)
{
int x = xo + random->nextInt(16);
int y = random->nextInt(64);
int z = zo + random->nextInt(16);
silverfishFeature->place(level, random, x, y, z);
}
}
void ExtremeHillsBiome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal)
void ExtremeHillsBiome::decorate(Level* level, Random* random, int xo, int zo)
{
topMaterial = static_cast<byte>(Tile::grass_Id);
material = static_cast<byte>(Tile::dirt_Id);
Biome::decorate(level, random, xo, zo);
if ((noiseVal < -1.0 || noiseVal > 2.0) && type == 2)
if (GENERATE_EMERALD_ORE)
{
int emeraldCount = 3 + random->nextInt(6);
for (int d = 0; d < emeraldCount; d++)
{
int x = xo + random->nextInt(16);
int y = random->nextInt(28) + 4;
int z = zo + random->nextInt(16);
int tile = level->getTile(x, y, z);
if (tile == Tile::stone_Id)
{
level->setTileAndData(x, y, z, Tile::emeraldOre_Id, 0, Tile::UPDATE_CLIENTS);
}
}
}
for (int i = 0; i < 7; i++)
{
int x = xo + random->nextInt(16);
int y = random->nextInt(64);
int z = zo + random->nextInt(16);
silverfishFeature->place(level, random, x, y, z);
}
}
void ExtremeHillsBiome::buildSurfaceAtDefault(Level* level, Random* random, byte* chunkBlocks, int x, int z, double noiseVal)
{
topMaterial = static_cast<byte>(Tile::grass_Id);
topMaterialData = 0;
material = static_cast<byte>(Tile::dirt_Id);
materialData = 0;
if ((noiseVal < -1.0 || noiseVal > 2.0) && type == TYPE_MUTATED)
{
topMaterial = static_cast<byte>(Tile::gravel_Id);
material = static_cast<byte>(Tile::gravel_Id);
material = static_cast<byte>(Tile::gravel_Id);
}
else if (noiseVal > 1.0 && type != 1)
else if (noiseVal > 1.0 && type != TYPE_TREES)
{
topMaterial = static_cast<byte>(Tile::stone_Id);
topMaterial = static_cast<byte>(Tile::stone_Id);
topMaterialData = 0;
material = static_cast<byte>(Tile::stone_Id);
materialData = 0;
material = static_cast<byte>(Tile::stone_Id);
materialData = 0;
}
Biome::buildSurfaceAtDefault(level, random, chunkBlocks, x, z, noiseVal);
@ -87,10 +100,17 @@ void ExtremeHillsBiome::buildSurfaceAtDefault(Level *level, Random *random, byte
Biome* ExtremeHillsBiome::mutateHills(Biome* baseBiome)
{
this->type = 2; // Mutated type
this->setColor(baseBiome->color, true);
this->setName(baseBiome->m_name + L" M");
this->setDepthAndScale(baseBiome->depth, baseBiome->scale);
this->setTemperatureAndDownfall(baseBiome->temperature, baseBiome->downfall);
return this;
this->type = TYPE_MUTATED;
this->setColor(baseBiome->color, true);
this->setName(baseBiome->m_name + L" M");
this->setDepthAndScale(baseBiome->depth, baseBiome->scale);
this->setTemperatureAndDownfall(baseBiome->temperature, baseBiome->downfall);
this->setWaterSkyColor(baseBiome->getWaterColor(), baseBiome->getSkyColor());
return this;
}
Biome* ExtremeHillsBiome::createMutatedBiome(int id)
{
return (new ExtremeHillsBiome(id, false))->mutateHills(this);
}

View file

@ -1,23 +1,32 @@
#pragma once
#pragma once
#include "Biome.h"
#include "OreFeature.h"
#include "SpruceFeature.h"
class ExtremeHillsBiome : public Biome
{
friend class Biome;
private:
static const bool GENERATE_EMERALD_ORE = true;
static const bool GENERATE_EMERALD_ORE = true;
Feature *silverfishFeature;
int type;
Feature *taigaFeature;
protected:
ExtremeHillsBiome(int id, bool extraTrees = false);
~ExtremeHillsBiome();
static constexpr int TYPE_NORMAL = 0;
static constexpr int TYPE_TREES = 1;
static constexpr int TYPE_MUTATED = 2;
public:
virtual void decorate(Level *level, Random *random, int xo, int zo) override;
virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal) override;
virtual Feature *getTreeFeature(Random *random) override;
Biome* mutateHills(Biome* baseBiome);
ExtremeHillsBiome(int id);
ExtremeHillsBiome(int id, bool extraTrees);
~ExtremeHillsBiome();
Feature* getTreeFeature(Random* random) override;
void decorate(Level* level, Random* random, int xo, int zo) override;
void buildSurfaceAtDefault(Level* level, Random* random, byte* chunkBlocks, int x, int z, double noiseVal) override;
Biome* mutateHills(Biome* baseBiome);
Biome* createMutatedBiome(int id);
};

View file

@ -1,201 +1,249 @@
#include "stdafx.h"
#include "net.minecraft.world.level.newbiome.layer.h"
#include "RiverInitLayer.h"
#include "RareBiomeSpotLayer.h"
#include "net.minecraft.world.level.h"
#include "BiomeOverrideLayer.h"
#include "CustomizableSourceSettings.h"
#include "stdafx.h"
#include "net.minecraft.world.level.newbiome.layer.h"
#include "RiverInitLayer.h"
#include "RareBiomeSpotLayer.h"
#include "net.minecraft.world.level.h"
#include "BiomeOverrideLayer.h"
#include "CustomizableSourceSettings.h"
#ifdef __PSVITA__
// AP - this is used to perform fast 64bit divides of known values
#include "../Minecraft.Client/PSVita/PSVitaExtras/libdivide.h"
#ifdef __PSVITA__
#include "../Minecraft.Client/PSVita/PSVitaExtras/libdivide.h"
#include <ImposeContinentsLayer.h>
libdivide::divider<long long> fast_d2(2);
libdivide::divider<long long> fast_d3(3);
libdivide::divider<long long> fast_d4(4);
libdivide::divider<long long> fast_d5(5);
libdivide::divider<long long> fast_d6(6);
libdivide::divider<long long> fast_d7(7);
libdivide::divider<long long> fast_d10(10);
#endif
libdivide::divider<long long> fast_d2(2);
libdivide::divider<long long> fast_d3(3);
libdivide::divider<long long> fast_d4(4);
libdivide::divider<long long> fast_d5(5);
libdivide::divider<long long> fast_d6(6);
libdivide::divider<long long> fast_d7(7);
libdivide::divider<long long> fast_d10(10);
#endif
LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* superflatConfig) {
LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* superflatConfig)
{
shared_ptr<Layer> islandLayer = std::make_shared<IslandLayer>(seed, 1);
islandLayer = std::make_shared<FuzzyZoomLayer>(seed, islandLayer, 0x7D0);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 1);
islandLayer = std::make_shared<ZoomLayer>(seed, islandLayer, 0x7D1);
islandLayer = std::make_shared<ZoomLayer>(seed, islandLayer, 0x7D1);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 2);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 0x32);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 0x46);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 0x32);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 0x46);
islandLayer = std::make_shared<RemoveTooMuchOceanLayer>(seed, islandLayer, 2);
islandLayer = std::make_shared<AddSnowLayer>(seed, islandLayer, 2);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 3);
islandLayer = std::make_shared<AddEdgeLayer>(seed, islandLayer, 2, 0);
islandLayer = std::make_shared<AddEdgeLayer>(seed, islandLayer, 2, 1);
islandLayer = std::make_shared<AddEdgeLayer>(seed, islandLayer, 2, 0);
islandLayer = std::make_shared<AddEdgeLayer>(seed, islandLayer, 2, 1);
islandLayer = std::make_shared<AddEdgeLayer>(seed, islandLayer, 3, 2);
islandLayer = std::make_shared<ZoomLayer>(seed, islandLayer, 0x7D2);
islandLayer = std::make_shared<ZoomLayer>(seed, islandLayer, 0x7D3);
islandLayer = std::make_shared<ZoomLayer>(seed, islandLayer, 0x7D2);
islandLayer = std::make_shared<ZoomLayer>(seed, islandLayer, 0x7D3);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 4);
islandLayer = std::make_shared<AddMushroomIslandLayer>(seed, islandLayer, 5);
islandLayer = std::make_shared<DeepOceanLayer>(seed, islandLayer, 4);
shared_ptr<Layer> baseLayer = ZoomLayer::zoom(seed, islandLayer, 0x3E8, 0);
shared_ptr<Layer> baseLayer = ZoomLayer::zoom(seed, islandLayer, 0x3E8, 0);
int zoomLevel = 4;
int riverZoomCount = 4;
if (levelType == LevelType::lvl_customized && superflatConfig != nullptr) {
if (levelType == LevelType::lvl_customized && superflatConfig != nullptr)
{
auto settings = CustomizableSourceSettings::Builder::build(
CustomizableSourceSettings::Builder::fromString(superflatConfig));
zoomLevel = settings->getBiomeSize();
riverZoomCount = settings->getRiverSize();
}
if (levelType == LevelType::lvl_largeBiomes) {
zoomLevel = 6;
}
shared_ptr<Layer> riverInit = make_shared<RiverInitLayer>(seed, baseLayer, 0x64);
shared_ptr<Layer> hillsNoise = ZoomLayer::zoom(seed, riverInit, 0x3E8, 2);
if (levelType == LevelType::lvl_largeBiomes)
zoomLevel = 6;
shared_ptr<Layer> riverInit = make_shared<RiverInitLayer>(seed, baseLayer, 0x64);
shared_ptr<Layer> hillsNoise = ZoomLayer::zoom(seed, riverInit, 0x3E8, 2);
shared_ptr<Layer> riverLayerFinal = ZoomLayer::zoom(seed, riverInit, 0x3E8, 2);
riverLayerFinal = ZoomLayer::zoom(seed, riverLayerFinal, 0x3E8, riverZoomCount);
riverLayerFinal = make_shared<RiverLayer>(seed, riverLayerFinal, 1);
riverLayerFinal = make_shared<SmoothLayer>(seed, riverLayerFinal, 0x3E8);
shared_ptr<Layer> biomeLayer = make_shared<BiomeInitLayer>(seed, baseLayer, 0xC8, levelType, superflatConfig);
shared_ptr<Layer> biomeLayer = make_shared<BiomeInitLayer>(seed, baseLayer, 0xC8, levelType, superflatConfig);
biomeLayer = ZoomLayer::zoom(seed, biomeLayer, 0x3E8, 2);
biomeLayer = make_shared<BiomeEdgeLayer>(seed, biomeLayer, 0x3E8);
biomeLayer = make_shared<RegionHillsLayer>(seed, biomeLayer, hillsNoise, 0x3E8);
biomeLayer = make_shared<RareBiomeSpotLayer>(seed, biomeLayer, 0x3E9);
biomeLayer = make_shared<RareBiomeSpotLayer>(seed, biomeLayer, 0x3E9);
for (int i = 0; i < zoomLevel; ++i) {
for (int i = 0; i < zoomLevel; ++i)
{
biomeLayer = make_shared<ZoomLayer>(seed, biomeLayer, 0x3E8 + i);
if (i == 0) {
if (i == 0)
{
biomeLayer = make_shared<AddIslandLayer>(seed, biomeLayer, 3);
biomeLayer = make_shared<AddMushroomIslandLayer>(seed, biomeLayer, 5);
}
if (i == 1 || zoomLevel == 1) {
if (zoomLevel == 1||i == 1)
{
biomeLayer = make_shared<GrowMushroomIslandLayer>(seed, biomeLayer, 5);
biomeLayer = make_shared<ShoreLayer>(seed, biomeLayer, 0x3E8);
}
}
biomeLayer = make_shared<SmoothLayer>(seed, biomeLayer, 0x3E8);
shared_ptr<Layer> mixed = make_shared<RiverMixerLayer>(seed, biomeLayer, riverLayerFinal, 0x64);
shared_ptr<Layer> voronoi = make_shared<VoronoiZoom>(seed, mixed, 0xA);
shared_ptr<Layer> mixed = make_shared<RiverMixerLayer>(seed, biomeLayer, riverLayerFinal, 0x64);
shared_ptr<Layer> voronoi = make_shared<VoronoiZoom>(seed, mixed, 0xA);
mixed->init(seed);
voronoi->init(seed);
LayerArray result(3, false);
result[0] = mixed;
result[1] = voronoi;
result[2] = mixed;
result[0] = mixed;
result[1] = voronoi;
result[2] = mixed;
return result;
}
Layer::Layer(int64_t seedMixup)
{
parent = nullptr;
Layer::Layer(int64_t seedMixup)
{
parent = nullptr;
this->seedMixup = seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
}
this->seedMixup = seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
}
void Layer::initRandom(int64_t x, int64_t y)
{
rval = seed;
rval *= rval * 6364136223846793005L + 1442695040888963407L;
rval += x;
rval *= rval * 6364136223846793005L + 1442695040888963407L;
rval += y;
rval *= rval * 6364136223846793005L + 1442695040888963407L;
rval += x;
rval *= rval * 6364136223846793005L + 1442695040888963407L;
rval += y;
}
int Layer::nextRandom(int max)
{
#ifdef __PSVITA__
int result;
long long temp = rval;
temp >>= 24;
if (max == 2)
result = temp - (temp / fast_d2) * 2;
else if (max == 3)
result = temp - (temp / fast_d3) * 3;
else if (max == 4)
result = temp - (temp / fast_d4) * 4;
else if (max == 5)
result = temp - (temp / fast_d5) * 5;
else if (max == 6)
result = temp - (temp / fast_d6) * 6;
else if (max == 7)
result = temp - (temp / fast_d7) * 7;
else if (max == 10)
result = temp - (temp / fast_d10) * 10;
else
result = temp - (temp / max) * max;
#else
int result = static_cast<int>((rval >> 24) % max);
#endif
if (result < 0) result += max;
rval *= rval * 6364136223846793005L + 1442695040888963407L;
rval += seed;
return result;
}
void Layer::initRandom(int64_t x, int64_t y)
{
rval = seed;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += x;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += y;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += x;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += y;
}
int Layer::nextRandom(int max)
{
#ifdef __PSVITA__
// AP - 64bit mods are very slow on Vita. Replaced with a divide/mult for general case and a fast divide library for specific numbers
// todo - this can sometimes yield a different number to the original. There's a strange bug sometimes with Vita where if the line
// "result = (int) ((rval >> 24) % max);" is done twice in a row 'result' will not be the same. Need to speak to Sony about that
// Also need to compare level against a different platform using the same seed
int result;
long long temp = rval;
temp >>= 24;
if( max == 2 )
{
result = temp-(temp/fast_d2)*2;
}
else if( max == 3 )
{
result = temp-(temp/fast_d3)*3;
}
else if( max == 4 )
{
result = temp-(temp/fast_d4)*4;
}
else if( max == 5 )
{
result = temp-(temp/fast_d5)*5;
}
else if( max == 6 )
{
result = temp-(temp/fast_d6)*6;
}
else if( max == 7 )
{
result = temp-(temp/fast_d7)*7;
}
else if( max == 10 )
{
result = temp-(temp/fast_d10)*10;
}
else
{
result = temp-(temp/max)*max;
}
#else
int result = static_cast<int>((rval >> 24) % max);
#endif
if (result < 0) result += max;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += seed;
return result;
}
void Layer::init(int64_t seed)
void Layer::init(int64_t seed)
{
this->seed = seed;
if (parent != nullptr) parent->init(seed);
this->seed *= this->seed * 6364136223846793005LL + 1442695040888963407LL;
this->seed *= this->seed * 6364136223846793005L + 1442695040888963407L;
this->seed += seedMixup;
this->seed *= this->seed * 6364136223846793005LL + 1442695040888963407LL;
this->seed *= this->seed * 6364136223846793005L + 1442695040888963407L;
this->seed += seedMixup;
this->seed *= this->seed * 6364136223846793005LL + 1442695040888963407LL;
this->seed *= this->seed * 6364136223846793005L + 1442695040888963407L;
this->seed += seedMixup;
}
bool Layer::isOcean(int biomeId)
{
return biomeId == Biome::ocean->id ||
biomeId == Biome::deepOcean->id ||
biomeId == Biome::frozenOcean->id;
}
bool Layer::isSame(int biomeIdA, int biomeIdB) {
if (biomeIdA == biomeIdB) {
return true;
} else {
Biome* biome = Biome::getBiome(biomeIdA);
Biome* biome2 = Biome::getBiome(biomeIdB);
if (biome != nullptr && biome2 != nullptr) {
if (biome != Biome::mesaPlateauF && biome != Biome::mesaPlateau) {
return biome == biome2 || biome->getBaseBiomeId() == biome2->getBaseBiomeId();
} else {
return biome2 == Biome::mesaPlateauF || biome2 == Biome::mesaPlateau;
}
} else {
return false;
}
}
}
int Layer::random(int i, int j, int k, int l) {
int random = nextRandom(4);
int ret = (random != 2 ? i : k);
if (random == 3)
ret = l;
if (random == 1)
ret = j;
return ret;
}
int Layer::random(int i, int j) {
if (nextRandom(2)) {
return j;
}
return i;
}
int Layer::modeOrRandom(int i, int j, int k, int l) {
if (j == k && k == l) {
return j;
} else if (i == j && i == k) {
return i;
} else if (i == j && i == l) {
return i;
} else if (i == k && i == l) {
return i;
} else if (i == j && k != l) {
return i;
} else if (i == k && j != l) {
return i;
} else if (i == l && j != k) {
return i;
} else if (j == k && i != l) {
return j;
} else if (j == l && i != k) {
return j;
} else {
return k == l && i != j ? k : random(i, j, k, l);
}
}

View file

@ -26,11 +26,15 @@ public:
Layer(int64_t seedMixup);
virtual void init(int64_t seed);
bool isOcean(int biomeId);
bool isSame(int biomeIdA, int biomeIdB);
virtual void initRandom(int64_t x, int64_t y);
protected:
int nextRandom(int max);
int random(int i, int j, int k, int l);
int random(int i, int j);
int modeOrRandom(int i, int j, int k, int l);
public:
virtual intArray getArea(int xo, int yo, int w, int h) = 0;
};

View file

@ -1,4 +1,4 @@
#include "stdafx.h"
#include "stdafx.h"
#include "System.h"
#include "BasicTypeContainers.h"
#include "File.h"
@ -4790,4 +4790,24 @@ bool Level::canCreateMore(eINSTANCEOF type, ESPAWN_TYPE spawnType)
}
// 4J: Interpret 0 as no limit
return max == 0 || count < max;
}
BlockPos Level::getHeightmapPos(int x, int z)
{
if (x < -MAX_LEVEL_SIZE || z < -MAX_LEVEL_SIZE ||
x >= MAX_LEVEL_SIZE || z >= MAX_LEVEL_SIZE)
{
return BlockPos(x, 64, z);
}
if (hasChunk(x >> 4, z >> 4))
{
LevelChunk* lc = getChunk(x >> 4, z >> 4);
int y = lc->getHeightmap(x & 0xF, z & 0xF);
return BlockPos(x, y, z);
}
return BlockPos(x, 0, z);
}

View file

@ -209,7 +209,7 @@ public:
bool reallyHasChunkAt(int x, int y, int z); // 4J added
bool reallyHasChunksAt(int x, int y, int z, int r); // 4J added
bool reallyHasChunksAt(int x0, int y0, int z0, int x1, int y1, int z1); // 4J added
BlockPos getHeightmapPos(int x, int z);
public:
bool hasChunk(int x, int z);
bool reallyHasChunk(int x, int z ); // 4J added

View file

@ -1,26 +1,23 @@
#include "stdafx.h"
#include "stdafx.h"
#define _USE_MATH_DEFINES
#include <cmath>
#include <algorithm>
#include "MesaBiome.h"
#include "BiomeDecorator.h"
#include "BiomeDecorator.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.tile.h"
#include "ColoredTile.h"
#include "SandTile.h"
#include "DirtTile.h"
#include "DyePowderItem.h"
#include "PerlinNoise.h"
#include "PerlinSimplexNoise.h"
#include "Random.h"
#include "TreeFeature.h"
#undef max
#undef min
MesaBiome::MesaBiome(int id, bool mesaPlateau, bool hasTrees) : Biome(id)
{
this->isMesaPlateau = mesaPlateau;
@ -29,31 +26,22 @@ MesaBiome::MesaBiome(int id, bool mesaPlateau, bool hasTrees) : Biome(id)
this->setNoRain();
this->setTemperatureAndDownfall(2.0f, 0.0f);
// Red Sand (id=12, data=1)
// Orange Stained Hardened Clay (id=159, data=1)
this->topMaterial = static_cast<byte>(Tile::sand_Id);
this->topMaterialData = static_cast<byte>(SandTile::RED_SAND); // 1
this->topMaterialData = static_cast<byte>(SandTile::RED_SAND);
this->material = static_cast<byte>(Tile::clayHardened_colored_Id);
this->materialData = static_cast<byte>(BAND_ORANGE); // 1
this->materialData = static_cast<byte>(orangeColoredClayState);
this->lastSeed = INVALID_SEED;
this->clayBands = nullptr;
this->pillarNoise = nullptr;
this->pillarRoofNoise = nullptr;
this->clayBandsOffsetNoise = nullptr;
/*friendlies.clear();
friendlies_chicken.clear();
enemies.clear();
waterFriendlies.clear();
ambientFriendlies.clear();*/
if (decorator)
{
decorator->treeCount = hasTrees ? 5 : -999;
decorator->treeCount = hasTrees ? 5 : -999;
decorator->deadBushCount = 20;
decorator->reedsCount = 3;
decorator->reedsCount = 3;
decorator->cactusCount = 5;
decorator->flowerCount = 0;
}
@ -61,31 +49,135 @@ MesaBiome::MesaBiome(int id, bool mesaPlateau, bool hasTrees) : Biome(id)
MesaBiome::~MesaBiome()
{
delete[] clayBands;
clayBands = nullptr;
delete pillarNoise;
pillarNoise = nullptr;
delete pillarRoofNoise;
pillarRoofNoise = nullptr;
delete clayBandsOffsetNoise;
clayBandsOffsetNoise = nullptr;
}
void MesaBiome::initBands(int64_t /*seed*/) {}
int MesaBiome::getBandColor(int x, int y, int z)
void MesaBiome::generateBands(int64_t seed)
{
if (!clayBandsOffsetNoise)
return BAND_ORANGE;
double noiseX = static_cast<double>(x) / 512.0;
int offset = static_cast<int>(std::round(
clayBandsOffsetNoise->getValue(noiseX, noiseX) * 2.0));
delete[] clayBands;
clayBands = new BandEntry[BAND_COUNT];
int index = ((y + offset) % 64 + 64) % 64;
return static_cast<int>(static_cast<unsigned char>(clayBands[index]));
for (int i = 0; i < BAND_COUNT; ++i)
{
clayBands[i].blockId = Tile::clayHardened_Id;
clayBands[i].blockData = defaultHardenedClayState;
}
Random r(seed);
delete clayBandsOffsetNoise;
clayBandsOffsetNoise = new PerlinSimplexNoise(&r, 1);
{
int i = 0;
while (i < BAND_COUNT)
{
i += r.nextInt(5) + 1;
if (i < BAND_COUNT)
{
clayBands[i].blockId = Tile::clayHardened_colored_Id;
clayBands[i].blockData = orangeColoredClayState;
}
}
}
{
int groupCount = r.nextInt(4) + 2;
for (int g = 0; g < groupCount; ++g)
{
int len = r.nextInt(3) + 1;
int start = r.nextInt(BAND_COUNT);
for (int k = 0; start + k < BAND_COUNT && k < len; ++k)
{
clayBands[start + k].blockId = Tile::clayHardened_colored_Id;
clayBands[start + k].blockData = yellowColoredClayState;
}
}
}
{
int groupCount = r.nextInt(4) + 2;
for (int g = 0; g < groupCount; ++g)
{
int len = r.nextInt(3) + 2;
int start = r.nextInt(BAND_COUNT);
for (int k = 0; start + k < BAND_COUNT && k < len; ++k)
{
clayBands[start + k].blockId = Tile::clayHardened_colored_Id;
clayBands[start + k].blockData = brownColoredClayState;
}
}
}
{
int groupCount = r.nextInt(4) + 2;
for (int g = 0; g < groupCount; ++g)
{
int len = r.nextInt(3) + 1;
int start = r.nextInt(BAND_COUNT);
for (int k = 0; start + k < BAND_COUNT && k < len; ++k)
{
clayBands[start + k].blockId = Tile::clayHardened_colored_Id;
clayBands[start + k].blockData = redColoredClayState;
}
}
}
{
int stripeCount = r.nextInt(3) + 3;
int cursor = 0;
for (int g = 0; g < stripeCount; ++g)
{
cursor += r.nextInt(16) + 4;
if (cursor >= BAND_COUNT) break;
clayBands[cursor].blockId = Tile::clayHardened_colored_Id;
clayBands[cursor].blockData = whiteColoredClayState;
if (cursor > 1 && r.nextBoolean())
{
clayBands[cursor - 1].blockId = Tile::clayHardened_colored_Id;
clayBands[cursor - 1].blockData = silverColoredClayState;
}
if (cursor < 63 && r.nextBoolean())
{
clayBands[cursor + 1].blockId = Tile::clayHardened_colored_Id;
clayBands[cursor + 1].blockData = silverColoredClayState;
}
}
}
}
BandEntry MesaBiome::getBand(int x, int y, int z)
{
if (!clayBandsOffsetNoise || !clayBands)
return { Tile::clayHardened_Id, 0 };
double noiseVal = clayBandsOffsetNoise->getValue(
static_cast<double>(x) * 0.001953125,
static_cast<double>(x) * 0.001953125);
int offset = static_cast<int>(std::round(noiseVal + noiseVal));
int index = ((y + offset) + BAND_COUNT) % BAND_COUNT;
return clayBands[index];
}
void MesaBiome::decorate(Level* level, Random* random, int xo, int zo)
{
@ -94,203 +186,214 @@ void MesaBiome::decorate(Level* level, Random* random, int xo, int zo)
Feature* MesaBiome::getTreeFeature(Random* random)
{
return Biome::getTreeFeature(random);
return new TreeFeature(false);
}
int MesaBiome::getFolageColor() const
{
return 0x9E814D;
}
int MesaBiome::getGrassColor() const
{
return 0x90814D;
}
void MesaBiome::buildSurfaceAtDefault(Level* level, Random* random,
byte* chunkBlocks, byte* chunkData,
int x, int z, double noiseVal)
{
int64_t seed = level->getSeed();
if (lastSeed != seed)
if (!clayBands || lastSeed != seed)
generateBands(seed);
if (!pillarNoise || !pillarRoofNoise || lastSeed != seed)
{
lastSeed = seed;
std::fill(std::begin(clayBands), std::end(clayBands),
static_cast<byte>(BAND_HARDENED_CLAY));
{
Random r(seed);
delete clayBandsOffsetNoise;
clayBandsOffsetNoise = new PerlinNoise(&r, 1);
// Orange sparse
for (int i = 0; i < 64; )
{
i += r.nextInt(5) + 1;
if (i < 64) clayBands[i] = static_cast<byte>(BAND_ORANGE);
}
// Yellow groups
int yg = r.nextInt(4) + 2;
for (int g = 0; g < yg; ++g) {
int t = r.nextInt(3) + 1, s = r.nextInt(64);
for (int k = 0; s + k < 64 && k < t; ++k)
clayBands[s + k] = static_cast<byte>(BAND_YELLOW);
}
// Brown groups
int bg = r.nextInt(4) + 2;
for (int g = 0; g < bg; ++g) {
int t = r.nextInt(3) + 2, s = r.nextInt(64);
for (int k = 0; s + k < 64 && k < t; ++k)
clayBands[s + k] = static_cast<byte>(BAND_BROWN);
}
// Red groups
int rg = r.nextInt(4) + 2;
for (int g = 0; g < rg; ++g) {
int t = r.nextInt(3) + 1, s = r.nextInt(64);
for (int k = 0; s + k < 64 && k < t; ++k)
clayBands[s + k] = static_cast<byte>(BAND_RED);
}
// White stripes
int ws = r.nextInt(3) + 3, cursor = 0;
for (int g = 0; g < ws; ++g) {
cursor += r.nextInt(16) + 4;
if (cursor >= 64) break;
clayBands[cursor] = static_cast<byte>(BAND_WHITE);
if (cursor > 1 && r.nextBoolean()) clayBands[cursor - 1] = static_cast<byte>(BAND_SILVER);
if (cursor < 63 && r.nextBoolean()) clayBands[cursor + 1] = static_cast<byte>(BAND_SILVER);
}
}
Random noiseRand(seed);
delete pillarNoise;
delete pillarRoofNoise;
delete pillarNoise; pillarNoise = nullptr;
delete pillarRoofNoise; pillarRoofNoise = nullptr;
{
Random r(seed);
pillarNoise = new PerlinNoise(&r, 4); // field_150623_aE
pillarRoofNoise = new PerlinNoise(&r, 1); // field_150624_aF
}
pillarNoise = new PerlinSimplexNoise(&noiseRand, 4);
pillarRoofNoise = new PerlinSimplexNoise(&noiseRand, 1);
}
const int seaLevel = level->seaLevel;
const int localX = x & 15;
const int localZ = z & 15;
lastSeed = seed;
int noiseDepth = (int)(noiseVal / 3.0 + 3.0 + random->nextDouble() * 0.25);
bool flag = (cos(noiseVal / 3.0 * PI) > 0.0);
const int localX = x & 0xF;
const int localZ = z & 0xF;
int run = -1;
bool flag1 = false;
double pillarHeight = 0.0;
for (int y = Level::genDepthMinusOne; y >= 0; --y)
if (isMesaPlateau&& id == Biome::mesaBryce->id)
{
double nx = static_cast<double>((x & ~0xF) + localZ);
double nz = static_cast<double>((z & ~0xF) + localX);
double roofVal = pillarNoise->getValue(nx * 0.25, nz * 0.25);
double d0 = std::abs(noiseVal) - roofVal;
if (d0 > 0.0)
{
int index = (localX * 16 + localZ) * Level::genDepth + y;
double pillarScale = pillarRoofNoise->getValue(
nx * 0.001953125,
nz * 0.001953125);
if (y <= 1 + random->nextInt(2))
double scaled = std::ceil(std::abs(pillarScale) * 50.0);
double height = d0 * d0 * 2.5;
double cap = scaled + 14.0;
if (height > cap) height = cap;
pillarHeight = height + 64.0;
}
}
const int localX2 = x & 0xF;
const int localZ2 = z & 0xF;
const int seaLevel = level->getSeaLevel();
int noiseDepth = static_cast<int>(noiseVal / 3.0 + 3.0 + random->nextDouble() * 0.25);
bool cosFlag = (std::cos(noiseVal / 3.0 * PI) > 0.0);
int run = -1;
bool underRedSand = false;
for (int y = 0x7F; y >= 0; --y)
{
int idx = (localZ2 * 16 + localX2) * 128 + y;
byte cur = chunkBlocks[idx];
if (cur == 0 && pillarHeight > 0.0 && y < static_cast<int>(pillarHeight))
{
chunkBlocks[index] = static_cast<byte>(Tile::unbreakable_Id);
chunkBlocks[idx] = static_cast<byte>(Tile::stone_Id);
cur = static_cast<byte>(Tile::stone_Id);
}
if (y <= random->nextInt(5))
{
chunkBlocks[idx] = static_cast<byte>(Tile::unbreakable_Id);
continue;
}
byte cur = chunkBlocks[index];
cur = chunkBlocks[idx];
if (cur == 0)
if (cur == 0)
{
run = -1;
continue;
}
else if (cur == static_cast<byte>(Tile::stone_Id))
if (cur != static_cast<byte>(Tile::stone_Id))
continue;
if (run == -1)
{
if (run == -1)
underRedSand = false;
run = noiseDepth + std::max(0, y - seaLevel);
if (y < seaLevel - 1)
{
flag1 = false;
run = noiseDepth + (y > seaLevel ? (y - seaLevel) : 0);
if (y < seaLevel - 1)
if (noiseDepth <= 0)
{
if (noiseDepth <= 0)
{
chunkBlocks[index] = static_cast<byte>(Tile::stone_Id);
}
else
{
chunkBlocks[index] = static_cast<byte>(Tile::clayHardened_colored_Id);
chunkData[index] = static_cast<byte>(BAND_ORANGE);
}
}
else if (hasTrees && y > 86 + noiseDepth * 2)
{
if (flag)
{
chunkBlocks[index] = static_cast<byte>(Tile::grass_Id);
}
else
{
chunkBlocks[index] = static_cast<byte>(Tile::dirt_Id);
chunkData[index] = static_cast<byte>(DirtTile::COARSE_DIRT);
}
}
else if (y <= seaLevel + 3 + noiseDepth)
{
chunkBlocks[index] = static_cast<byte>(Tile::sand_Id);
chunkData[index] = static_cast<byte>(SandTile::RED_SAND); // 1
flag1 = true;
chunkBlocks[idx] = static_cast<byte>(Tile::stone_Id);
}
else
{
if (y >= 64)
{
if (flag)
{
chunkBlocks[index] = static_cast<byte>(Tile::clayHardened_Id);
}
else
{
int band = getBandColor(x, y, z);
if (band == BAND_HARDENED_CLAY)
{
chunkBlocks[index] = static_cast<byte>(Tile::clayHardened_Id);
}
else
{
chunkBlocks[index] = static_cast<byte>(Tile::clayHardened_colored_Id);
chunkData[index] = static_cast<byte>(band);
}
}
}
else
{
chunkBlocks[index] = static_cast<byte>(Tile::clayHardened_colored_Id);
chunkData[index] = static_cast<byte>(BAND_ORANGE);
}
}
if (y < seaLevel && chunkBlocks[index] == 0)
{
chunkBlocks[index] = (getTemperature(x, y, z) < 0.15f)
? static_cast<byte>(Tile::ice_Id)
: static_cast<byte>(Tile::calmWater_Id);
chunkBlocks[idx] = static_cast<byte>(Tile::clayHardened_colored_Id);
chunkData[idx] = static_cast<byte>(BAND_ORANGE);
}
}
else if (run > 0)
else if (hasTrees && y > 86 + noiseDepth * 2)
{
--run;
if (flag1)
if (cosFlag)
{
chunkBlocks[index] = static_cast<byte>(Tile::clayHardened_colored_Id);
chunkData[index] = static_cast<byte>(BAND_ORANGE);
chunkBlocks[idx] = static_cast<byte>(Tile::dirt_Id);
chunkData[idx] = static_cast<byte>(DirtTile::COARSE_DIRT);
}
else
{
int band = getBandColor(x, y, z);
if (band == BAND_HARDENED_CLAY)
chunkBlocks[index] = static_cast<byte>(Tile::clayHardened_Id);
chunkBlocks[idx] = static_cast<byte>(Tile::grass_Id);
}
}
else if (y <= seaLevel + 3 + noiseDepth)
{
chunkBlocks[idx] = static_cast<byte>(Tile::sand_Id);
chunkData[idx] = static_cast<byte>(SandTile::RED_SAND);
underRedSand = true;
}
else
{
if (y >= 64 && y <= 127)
{
if (cosFlag)
{
chunkBlocks[idx] = static_cast<byte>(Tile::clayHardened_Id);
}
else
{
chunkBlocks[index] = static_cast<byte>(Tile::clayHardened_colored_Id);
chunkData[index] = static_cast<byte>(band);
BandEntry band = getBand(x, y, z);
chunkBlocks[idx] = static_cast<byte>(band.blockId);
if (band.blockId == Tile::clayHardened_colored_Id)
chunkData[idx] = static_cast<byte>(band.blockData);
}
}
else
{
chunkBlocks[idx] = static_cast<byte>(Tile::clayHardened_colored_Id);
chunkData[idx] = static_cast<byte>(BAND_ORANGE);
}
}
if (y < seaLevel && chunkBlocks[idx] == 0)
chunkBlocks[idx] = static_cast<byte>(Tile::calmWater_Id);
}
else if (run > 0)
{
--run;
if (underRedSand)
{
chunkBlocks[idx] = static_cast<byte>(Tile::clayHardened_colored_Id);
chunkData[idx] = static_cast<byte>(BAND_ORANGE);
}
else
{
BandEntry band = getBand(x, y, z);
chunkBlocks[idx] = static_cast<byte>(band.blockId);
if (band.blockId == Tile::clayHardened_colored_Id)
chunkData[idx] = static_cast<byte>(band.blockData);
}
}
}
}
MesaBiome* MesaBiome::createMutatedCopy(int newId)
{
bool isMesaBase = (this->id == Biome::mesa->id);
MesaBiome* copy = new MesaBiome(newId, isMesaBase, this->hasTrees);
if (!isMesaBase)
{
copy->setDepthAndScale(0.1f, 0.2f);
}
copy->setWaterSkyColor(this->getWaterColor(), this->getSkyColor());
return copy;
}

View file

@ -1,62 +1,62 @@
#pragma once
#include "Biome.h"
#include "PerlinNoise.h"
#include "PerlinSimplexNoise.h"
#include "Random.h"
#include "Level.h"
#include "Feature.h"
#include <cstdint>
struct BandEntry {
int blockId;
int blockData;
};
class MesaBiome : public Biome
{
public:
static constexpr int BAND_HARDENED_CLAY = 255;
static constexpr int BAND_WHITE = 0;
static constexpr int BAND_ORANGE = 1;
static constexpr int BAND_YELLOW = 4;
static constexpr int BAND_COUNT = 64;
static constexpr int BAND_WHITE = 0;
static constexpr int BAND_ORANGE = 1;
static constexpr int BAND_YELLOW = 4;
static constexpr int BAND_BROWN = 12;
static constexpr int BAND_RED = 14;
static constexpr int BAND_SILVER = 8;
static constexpr int BAND_SILVER = 8;
static constexpr int64_t INVALID_SEED = -1LL;
static constexpr int defaultHardenedClayState = 0;
static constexpr int orangeColoredClayState = BAND_ORANGE;
static constexpr int yellowColoredClayState = BAND_YELLOW;
static constexpr int brownColoredClayState = BAND_BROWN;
static constexpr int redColoredClayState = BAND_RED;
static constexpr int whiteColoredClayState = BAND_WHITE;
static constexpr int silverColoredClayState = BAND_SILVER;
MesaBiome(int id, bool mesaPlateau, bool hasTrees);
static constexpr int64_t INVALID_SEED = 0LL;
MesaBiome(int id, bool isMesaPlateau, bool hasTrees);
virtual ~MesaBiome();
virtual void decorate(Level* level, Random* random,
int xo, int zo) override;
virtual Feature* getTreeFeature(Random* random) override;
virtual void buildSurfaceAtDefault(Level* level, Random* random,
byte* chunkBlocks, byte* chunkData,
int x, int z, double noiseVal) override;
virtual void decorate(Level* level, Random* random, int xo, int zo) override;
virtual Feature* getTreeFeature(Random* random) override;
virtual void buildSurfaceAtDefault(Level* level, Random* random,
byte* chunkBlocks, byte* chunkData,
int x, int z, double noiseVal) override;
virtual int getFolageColor() const override;
virtual int getGrassColor() const override;
MesaBiome* createMutatedCopy(int newId);
private:
void initBands(int64_t seed);
void generateBands(int64_t seed);
BandEntry getBand(int x, int y, int z);
int getBandColor(int x, int y, int z);
bool isMesaPlateau; //0x104
bool hasTrees; //0x105
bool isMesaPlateau;
bool hasTrees;
int64_t lastSeed; //0xF0/0xF4
int64_t lastSeed;
byte clayBands[64];
PerlinNoise* clayBandsOffsetNoise;
PerlinNoise* pillarNoise;
PerlinNoise* pillarRoofNoise;
BandEntry* clayBands; //0xE8
PerlinSimplexNoise* pillarNoise; //0xF8
PerlinSimplexNoise* pillarRoofNoise; //0xFC
PerlinSimplexNoise* clayBandsOffsetNoise; //0x100
};

View file

@ -20,7 +20,8 @@ MutatedBiome::MutatedBiome(int id, Biome* baseBiome)
scale = baseBiome->scale + 0.2f;
temperature = baseBiome->temperature;
downfall = baseBiome->downfall;
_hasRain = baseBiome->_hasRain;
snowCovered = baseBiome->snowCovered;
friendlies = baseBiome->friendlies;
enemies = baseBiome->enemies;
@ -32,15 +33,17 @@ MutatedBiome::MutatedBiome(int id, Biome* baseBiome)
m_waterColor = baseBiome->m_waterColor;
m_skyColor = baseBiome->m_skyColor;
m_grassColor = baseBiome->m_grassColor;
m_foliageColor = baseBiome->m_foliageColor;
m_name = baseBiome->m_name + L" Mutated";
// Copia parametri del decorator
if (decorator && baseBiome->decorator) {
decorator->treeCount = baseBiome->decorator->treeCount;
decorator->grassCount = baseBiome->decorator->grassCount;
decorator->flowerCount = baseBiome->decorator->flowerCount;
decorator->hugeMushrooms = baseBiome->decorator->hugeMushrooms;
// ... altri campi se necessari
}
}

View file

@ -13,4 +13,8 @@ public:
topMaterial = Tile::gravel_Id; // surfaceblock
material = Tile::gravel_Id;
}
int OceanBiome::getTemperatureCategory() const override
{
return 0;
}
};

View file

@ -10,7 +10,7 @@ PerlinSimplexNoise::PerlinSimplexNoise(int levels)
PerlinSimplexNoise::PerlinSimplexNoise(Random *random, int levels)
{
init(random,levels);
delete random;
//delete random;
}
void PerlinSimplexNoise::init(Random *random, int levels)

View file

@ -22,14 +22,29 @@ intArray RareBiomeLayer::getArea(int xo, int yo, int w, int h)
if (this->nextRandom(57) == 0)
{
if (k == Biome::plains->id)
{
aint1[j + i * w] = Biome::plains->id + 128;
}
else
{
aint1[j + i * w] = k;
}
int mutated = k;
if (k == Biome::plains->id) mutated = Biome::sunflowersPlains->id; // 1 -> 129
else if (k == Biome::desert->id) mutated = Biome::desertM->id; // 2 -> 130
else if (k == Biome::extremeHills->id) mutated = Biome::extremeHillsM->id; // 3 -> 131
else if (k == Biome::forest->id) mutated = Biome::flowerForest->id; // 4 -> 132
else if (k == Biome::taiga->id) mutated = Biome::taigaM->id; // 5 -> 133
else if (k == Biome::swampland->id) mutated = Biome::swamplandM->id; // 6 -> 134
else if (k == Biome::iceFlats->id) mutated = Biome::iceSpikes->id; // 12 -> 140
else if (k == Biome::jungle->id) mutated = Biome::jungleM->id; // 21 -> 149
else if (k == Biome::jungleEdge->id) mutated = Biome::jungleEdgeM->id; // 23 -> 151
else if (k == Biome::birchForest->id) mutated = Biome::birchForestM->id; // 27 -> 155
else if (k == Biome::birchForestHills->id) mutated = Biome::birchForestHillsM->id; // 28 -> 156
else if (k == Biome::roofedForest->id) mutated = Biome::roofedForestM->id; // 29 -> 157
else if (k == Biome::coldTaiga->id) mutated = Biome::coldTaigaM->id; // 30 -> 158
else if (k == Biome::megaTaiga->id) mutated = Biome::redwoodTaiga->id; // 32 -> 160
else if (k == Biome::megaTaigaHills->id) mutated = Biome::redwoodTaigaHills->id; // 33 -> 161
else if (k == Biome::extremeHills_plus->id) mutated = Biome::extremeHills_plusM->id; // 34 -> 162
else if (k == Biome::savanna->id) mutated = Biome::savannaM->id; // 35 -> 163
else if (k == Biome::savannaPlateau->id) mutated = Biome::savannaPlateauM->id; // 36 -> 164
else if (k == Biome::mesa->id) mutated = Biome::mesaBryce->id; // 37 -> 165
else if (k == Biome::mesaPlateauF->id) mutated = Biome::mesaPlateauFM->id; // 38 -> 166
else if (k == Biome::mesaPlateau->id) mutated = Biome::mesaPlateauM->id; // 39 -> 167
aint1[j + i * w] = mutated;
}
else
{
@ -39,4 +54,4 @@ intArray RareBiomeLayer::getArea(int xo, int yo, int w, int h)
}
return aint1;
}
}

View file

@ -1,6 +1,7 @@
#include "stdafx.h"
#include "RareBiomeSpotLayer.h"
#include "IntCache.h"
#include "net.minecraft.world.level.biome.h"
RareBiomeSpotLayer::RareBiomeSpotLayer(int64_t seed, std::shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
@ -9,6 +10,22 @@ RareBiomeSpotLayer::RareBiomeSpotLayer(int64_t seed, std::shared_ptr<Layer> pare
intArray RareBiomeSpotLayer::getArea(int xo, int yo, int w, int h)
{
return parent->getArea(xo, yo, w, h);
intArray b = parent->getArea(xo, yo, w, h);
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
initRandom(x + xo, y + yo);
int biomeId = b[x + y * w];
if (nextRandom(57) == 0 && biomeId == Biome::plains->id)
result[x + y * w] = biomeId + 128;
else
result[x + y * w] = biomeId;
}
}
return result;
}

View file

@ -55,8 +55,14 @@ intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h)
if (riverNoise != nullptr && k != 0 && l >= 2 && (l - 2) % 29 == 1 && k < 128)
{
result[x + y * w] = k;
if (Biome::biomes[k + 128] != nullptr)
{
result[x + y * w] = k + 128;
}
else
{
result[x + y * w] = k;
}
}
else if (nextRandom(3) != 0 && !flag)
{
@ -135,6 +141,18 @@ intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h)
if (flag && i1 != k)
{
if (Biome::biomes[i1 + 128] != nullptr)
{
i1 += 128;
}
else
{
i1 = k;
}
}
if (i1 == k)
{
result[x + y * w] = k;

View file

@ -5,40 +5,39 @@
RemoveTooMuchOceanLayer::RemoveTooMuchOceanLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
this->parent = parent;
}
intArray RemoveTooMuchOceanLayer::getArea(int xo, int yo, int w, int h)
{
int i = xo - 1;
int j = yo - 1;
int k = w + 2;
int l = h + 2;
intArray aint = this->parent->getArea(i, j, k, l);
intArray aint1 = IntCache::allocate(w * h);
int i = xo - 1;
int j = yo - 1;
int k = w + 2;
int l = h + 2;
intArray aint = this->parent->getArea(i, j, k, l);
intArray aint1 = IntCache::allocate(w * h);
for (int i1 = 0; i1 < h; ++i1)
{
for (int j1 = 0; j1 < w; ++j1)
{
int k1 = aint[j1 + 1 + (i1 + 1 - 1) * (w + 2)];
int l1 = aint[j1 + 1 + 1 + (i1 + 1) * (w + 2)];
int i2 = aint[j1 + 1 - 1 + (i1 + 1) * (w + 2)];
int j2 = aint[j1 + 1 + (i1 + 1 + 1) * (w + 2)];
int k2 = aint[j1 + 1 + (i1 + 1) * k];
aint1[j1 + i1 * w] = k2;
this->initRandom((int64_t)(j1 + xo), (int64_t)(i1 + yo));
for (int i1 = 0; i1 < h; ++i1)
{
for (int j1 = 0; j1 < w; ++j1)
{
int k1 = aint[(j1 + 1) + (i1) * k];
int l1 = aint[(j1 + 2) + (i1 + 1) * k];
int i2 = aint[(j1) + (i1 + 1) * k];
int j2 = aint[(j1 + 1) + (i1 + 2) * k];
int k2 = aint[(j1 + 1) + (i1 + 1) * k];
if (k2 == 0 && k1 == 0 && l1 == 0 && i2 == 0 && j2 == 0)
{
if (this->nextRandom(2) == 0)
{
aint1[j1 + i1 * w] = 1;
}
}
}
}
this->initRandom((int64_t)(j1 + xo), (int64_t)(i1 + yo));
aint1[j1 + i1 * w] = k2;
return aint1;
if (k2 == 0 && k1 == 0 && l1 == 0 && i2 == 0 && j2 == 0)
{
if (this->nextRandom(2) == 0)
{
aint1[j1 + i1 * w] = 1;
}
}
}
}
return aint1;
}

View file

@ -23,18 +23,20 @@ intArray RiverMixerLayer::getArea(int xo, int yo, int w, int h)
intArray result = IntCache::allocate(w * h);
for (int i = 0; i < w * h; i++)
{
if (b[i] == Biome::ocean->id || b[i] == Biome::deepOcean->id)
if (b[i] == Biome::ocean->id || b[i] == Biome::deepOcean->id || b[i] == Biome::frozenOcean->id)
{
result[i] = b[i];
}
else
{
if (r[i] >= 0)
{
if (b[i] == Biome::iceFlats->id) result[i] = Biome::frozenRiver->id;
else if (b[i] == Biome::mushroomIsland->id || b[i] == Biome::mushroomIslandShore->id) result[i] = Biome::mushroomIsland->id; // 4J - don't make mushroom island shores as we don't have any island left once we do this as our islands are small (this used to change to mushroomIslandShore)
else result[i] = r[i];
if (b[i] == Biome::iceFlats->id || b[i] == Biome::iceSpikes->id || b[i] == Biome::coldTaiga->id || b[i] == Biome::coldTaigaHills->id)
result[i] = Biome::frozenRiver->id;
else if (b[i] == Biome::mushroomIsland->id || b[i] == Biome::mushroomIslandShore->id)
result[i] = Biome::mushroomIsland->id; // 4J - don't make mushroom island shores as we don't have any island left once we do this as our islands are small (this used to change to mushroomIslandShore)
else
result[i] = r[i];
}
else
{

View file

@ -1,61 +1,55 @@
#include "stdafx.h"
#include "stdafx.h"
#include "net.minecraft.world.level.levelgen.feature.h"
#include "net.minecraft.world.level.biome.h"
#include "net.minecraft.world.entity.animal.h"
#include "net.minecraft.world.entity.h"
#include "SavannaBiome.h"
#include "SavannaTreeFeature.h"
#include "SavannaTreeFeature.h"
#include "DoublePlantFeature.h"
#include "TallGrass2.h"
#include "Level.h"
#include "Random.h"
SavannaBiome::SavannaBiome(int id) : Biome(id)
{
friendlies.push_back(new MobSpawnerData(eTYPE_HORSE, 1, 2, 6));
decorator->treeCount = 1;
decorator->treeCount = 1;
decorator->flowerCount = 4;
decorator->grassCount = 20;
decorator->grassCount = 20;
}
Feature *SavannaBiome::getTreeFeature(Random *random)
Feature* SavannaBiome::getTreeFeature(Random* random)
{
if (random->nextInt(5) > 0)
{
return new SavannaTreeFeature(false);
}
return new TreeFeature(false);
}
int SavannaBiome::getGrassColor() const
{
return 0xBFB755;
return 0xBFB755;
}
int SavannaBiome::getFolageColor() const
{
return 0xAEA42A;
return 0xAEA42A;
}
Feature *SavannaBiome::getFlowerFeature(Random *random, int x, int y, int z)
Feature* SavannaBiome::getFlowerFeature(Random* random, int x, int y, int z)
{
return nullptr;
return nullptr;
}
int SavannaBiome::getRandomDoublePlantType(Random *random)
int SavannaBiome::getRandomDoublePlantType(Random* random)
{
return 0;
return 0;
}
void SavannaBiome::decorate(Level *level, Random *random, int xo, int zo)
void SavannaBiome::decorate(Level* level, Random* random, int xo, int zo)
{
DOUBLE_PLANT_GENERATOR->setPlantType(TallGrass2::TALL_GRASS);
@ -63,51 +57,68 @@ void SavannaBiome::decorate(Level *level, Random *random, int xo, int zo)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
int y = random->nextInt(level->getHeightmap(x, z) + 32);
int surfaceY = level->getHeightmapPos(x, z).getY();
int y = random->nextInt(surfaceY + 32);
DOUBLE_PLANT_GENERATOR->place(level, random, x, y, z);
}
Biome::decorate(level, random, xo, zo);
}
MutatedSavannaBiome::MutatedSavannaBiome(int id, Biome* baseBiome) : MutatedBiome(id, baseBiome)
Biome* SavannaBiome::createMutatedCopy(int newId)
{
decorator->treeCount = 2;
decorator->flowerCount = 2;
decorator->grassCount = 5;
MutatedSavannaBiome* mutated = new MutatedSavannaBiome(newId, this);
mutated->scale = (this->scale + 1.0f) * 0.5f;
mutated->depth = (this->depth * 0.5f) + 0.3f;
mutated->temperature = (this->temperature * 0.5f) + 1.2f;
return mutated;
}
void MutatedSavannaBiome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal)
MutatedSavannaBiome::MutatedSavannaBiome(int id, Biome* baseBiome)
: MutatedBiome(id, baseBiome)
{
topMaterial = static_cast<byte>(Tile::grass_Id);
material = static_cast<byte>(Tile::dirt_Id);
decorator->treeCount = 2;
decorator->flowerCount = 2;
decorator->grassCount = 5;
}
void MutatedSavannaBiome::buildSurfaceAt(Level* level, Random* random,
ChunkPrimer* primer,
int x, int z, double noiseVal)
{
topMaterial = static_cast<byte>(Tile::grass_Id);
topMaterialData = 0;
material = static_cast<byte>(Tile::dirt_Id);
materialData = 0;
if (noiseVal > 1.75)
{
topMaterial = static_cast<byte>(Tile::stone_Id);
topMaterial = static_cast<byte>(Tile::stone_Id);
topMaterialData = 0;
material = static_cast<byte>(Tile::stone_Id);
materialData = 0;
material = static_cast<byte>(Tile::stone_Id);
materialData = 0;
}
else if (noiseVal > -0.5)
{
topMaterial = static_cast<byte>(Tile::dirt_Id);
topMaterialData = 0;
material = static_cast<byte>(Tile::dirt_Id);
materialData = 0;
}
else
{
topMaterial = static_cast<byte>(Tile::grass_Id);
topMaterialData = 0;
material = static_cast<byte>(Tile::dirt_Id);
materialData = 0;
topMaterial = static_cast<byte>(Tile::dirt_Id);
topMaterialData = 1;
material = static_cast<byte>(Tile::dirt_Id);
materialData = 0;
}
Biome::buildSurfaceAtDefault(level, random, chunkBlocks, x, z, noiseVal);
Biome::buildSurfaceAt(level, random, primer, x, z, noiseVal);
}
void MutatedSavannaBiome::decorate(Level *level, Random *random, int xo, int zo)
void MutatedSavannaBiome::decorate(Level* level, Random* random, int xo, int zo)
{
MutatedBiome::decorate(level, random, xo, zo);
}
decorator->decorate(level, random, xo, zo);
}

View file

@ -1,3 +1,4 @@
#pragma once
#include "Biome.h"
#include "MutatedBiome.h"
@ -6,21 +7,22 @@ class SavannaBiome : public Biome
{
public:
SavannaBiome(int id);
virtual Feature *getTreeFeature(Random *random);
virtual int getFolageColor() const override;
virtual int getGrassColor() const override;
//virtual int getWaterColor() override;
virtual Feature *getFlowerFeature(Random *random, int x, int y, int z) override;
virtual int getRandomDoublePlantType(Random *random) override;
virtual void decorate(Level *level, Random *random, int xo, int zo) override;
virtual Feature* getTreeFeature(Random* random) override;
virtual int getFolageColor() const override;
virtual int getGrassColor() const override;
virtual Feature* getFlowerFeature(Random* random, int x, int y, int z) override;
virtual int getRandomDoublePlantType(Random* random) override;
virtual void decorate(Level* level, Random* random, int xo, int zo) override;
virtual Biome* createMutatedCopy(int newId);
};
class MutatedSavannaBiome : public MutatedBiome
{
public:
MutatedSavannaBiome(int id, Biome* baseBiome);
virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal) override;
virtual void decorate(Level *level, Random *random, int xo, int zo) override;
virtual void buildSurfaceAt(Level* level, Random* random,
ChunkPrimer* primer, int x, int z,
double noiseVal) override;
virtual void decorate(Level* level, Random* random, int xo, int zo) override;
};

View file

@ -1,122 +1,188 @@
#include "stdafx.h"
#include "SavannaTreeFeature.h"
#include "net.minecraft.world.level.tile.h"
#include "TreeTile2.h"
#include "LeafTile2.h"
#include "Level.h"
#include "Random.h"
#include "Direction.h"
SavannaTreeFeature::SavannaTreeFeature(bool doUpdate) : Feature(doUpdate) {
this->baseHeight = 5;
SavannaTreeFeature::SavannaTreeFeature(bool doUpdate) : AbstractTreeFeature(doUpdate)
{
}
bool SavannaTreeFeature::place(Level* level, Random* random, int x, int y, int z) {
int height = random->nextInt(3) + baseHeight;
int ground = level->getTile(x, y - 1, z);
if (ground != Tile::grass_Id && ground != Tile::dirt_Id) return false;
if (random->nextBoolean()) {
generateForkingTree(level, random, x, y, z, height);
} else {
generateBendingTree(level, random, x, y, z, height);
}
return true;
void SavannaTreeFeature::placeLog(Level* level, int x, int y, int z)
{
placeBlock(level, x, y, z, Tile::tree2Trunk_Id, 0);
}
void SavannaTreeFeature::generateForkingTree(Level* level, Random* random, int x, int y, int z, int height) {
int curX = x;
int curZ = z;
int forkH = height - random->nextInt(4) - 1;
int dx1 = random->nextInt(3) - 1;
int dz1 = (dx1 == 0) ? (random->nextBoolean() ? 1 : -1) : (random->nextInt(3) - 1);
for (int h = 0; h < height; h++) {
if (h >= forkH) { curX += dx1; curZ += dz1; }
placeBlock(level, curX, y + h, curZ, Tile::tree2Trunk_Id, TreeTile2::ACACIA_TRUNK);
if (h == height - 1) generateLeafCap(level, curX, y + h, curZ);
void SavannaTreeFeature::placeLeafAt(Level* level, int x, int y, int z)
{
int tile = level->getTile(x, y, z);
if (tile == 0 || tile == Tile::leaves_Id || tile == Tile::leaves2_Id)
{
placeBlock(level, x, y, z, Tile::leaves2_Id, 0);
}
}
int dx2 = random->nextInt(3) - 1;
int dz2 = random->nextInt(3) - 1;
if (dx2 != dx1 || dz2 != dz1) {
int curX2 = x;
int curZ2 = z;
int forkH2 = forkH - random->nextInt(2) - 1;
for (int h = forkH2; h < height; h++) {
if (h >= 1) {
curX2 += dx2; curZ2 += dz2;
placeBlock(level, curX2, y + h, curZ2, Tile::tree2Trunk_Id, TreeTile2::ACACIA_TRUNK);
if (h == height - 1) generateLeafCap(level, curX2, y + h, curZ2);
void SavannaTreeFeature::placeLeavesLayer3(Level* level, int cx, int cy, int cz)
{
for (int dx = -3; dx <= 3; ++dx)
{
for (int dz = -3; dz <= 3; ++dz)
{
if (abs(dx) != 3 || abs(dz) != 3)
{
placeLeafAt(level, cx + dx, cy, cz + dz);
}
}
}
}
void SavannaTreeFeature::placeLeavesLayer1(Level* level, int cx, int cy, int cz)
{
for (int dx = -1; dx <= 1; ++dx)
{
for (int dz = -1; dz <= 1; ++dz)
{
placeLeafAt(level, cx + dx, cy, cz + dz);
}
}
placeLeafAt(level, cx + 2, cy, cz);
placeLeafAt(level, cx - 2, cy, cz);
placeLeafAt(level, cx, cy, cz + 2);
placeLeafAt(level, cx, cy, cz - 2);
}
bool SavannaTreeFeature::place(Level* level, Random* random, int x, int y, int z)
{
int height = random->nextInt(3) + random->nextInt(3) + 5;
if (y <= 0 || y + height + 1 > 256)
return false;
bool canPlace = true;
for (int j = y; j <= y + 1 + height && canPlace; ++j)
{
int radius = 1;
if (j == y) radius = 0;
if (j >= y + 1 + height - 2) radius = 2;
for (int lx = x - radius; lx <= x + radius && canPlace; ++lx)
{
for (int lz = z - radius; lz <= z + radius && canPlace; ++lz)
{
if (j >= 0 && j < 256)
{
if (!AbstractTreeFeature::isFree(level, lx, j, lz))
canPlace = false;
}
else
{
canPlace = false;
}
}
}
}
if (!canPlace)
return false;
int belowTile = level->getTile(x, y - 1, z);
if (belowTile != Tile::grass_Id && belowTile != Tile::dirt_Id)
return false;
if (y >= 255 - height)
return false;
setDirtAt(level, x, y - 1, z);
void SavannaTreeFeature::generateBendingTree(Level* level, Random* random, int x, int y, int z, int height) {
int facing1 = Direction::Plane::getRandomFace(random);
int branchStart = height - random->nextInt(4) - 1;
int branchLen = 3 - random->nextInt(3);
int curX = x;
int curZ = z;
int curY = y;
int topY = y;
int dirX = 0, dirZ = 0;
int roll = random->nextInt(4);
if (roll == 0) dirX = 1; else if (roll == 1) dirX = -1; else if (roll == 2) dirZ = 1; else dirZ = -1;
for (int l1 = 0; l1 < height; ++l1)
{
int curY = y + l1;
int straightHeight = 2 + random->nextInt(3);
for (int i = 0; i < straightHeight; i++) {
placeBlock(level, curX, curY, curZ, Tile::tree2Trunk_Id, TreeTile2::ACACIA_TRUNK);
curY++;
}
if (l1 >= branchStart && branchLen > 0)
{
curX += Direction::getStepX(facing1);
curZ += Direction::getStepZ(facing1);
--branchLen;
}
int diagonalSteps = 2 + random->nextInt(2);
for (int i = 0; i < diagonalSteps; i++) {
curX += dirX;
curZ += dirZ;
placeBlock(level, curX, curY, curZ, Tile::tree2Trunk_Id, TreeTile2::ACACIA_TRUNK);
if (i < diagonalSteps - 1) {
curY++;
int tile = level->getTile(curX, curY, curZ);
if (tile == 0 || tile == Tile::leaves_Id || tile == Tile::leaves2_Id)
{
placeLog(level, curX, curY, curZ);
topY = curY;
}
}
generateLeafCap(level, curX, curY, curZ);
}
placeLeavesLayer3(level, curX, topY, curZ);
placeLeavesLayer1(level, curX, topY + 1, curZ);
void SavannaTreeFeature::generateLeafCap(Level* level, int x, int y, int z) {
for (int lx = -3; lx <= 3; lx++) {
for (int lz = -3; lz <= 3; lz++) {
int curX2 = x;
int curZ2 = z;
int facing2 = Direction::Plane::getRandomFace(random);
if (facing2 != facing1)
{
int start2 = branchStart - random->nextInt(2) - 1;
int steps2 = 1 + random->nextInt(3);
int topY2 = 0;
for (int l4 = start2; l4 < height && steps2 > 0; --steps2)
{
if (l4 >= 1)
{
int curY2 = y + l4;
curX2 += Direction::getStepX(facing2);
curZ2 += Direction::getStepZ(facing2);
int tile2 = level->getTile(curX2, curY2, curZ2);
if (tile2 == 0 || tile2 == Tile::leaves_Id || tile2 == Tile::leaves2_Id)
{
placeLog(level, curX2, curY2, curZ2);
topY2 = curY2;
}
}
++l4;
}
if (topY2 > 0)
{
if (abs(lx) == 3 && abs(lz) == 3) continue;
if (abs(lx) + abs(lz) > 4) continue;
placeLeaf(level, x + lx, y, z + lz);
for (int dx = -2; dx <= 2; ++dx)
{
for (int dz = -2; dz <= 2; ++dz)
{
if (abs(dx) != 2 || abs(dz) != 2)
{
placeLeafAt(level, curX2 + dx, topY2, curZ2 + dz);
}
}
}
for (int dx = -1; dx <= 1; ++dx)
{
for (int dz = -1; dz <= 1; ++dz)
{
placeLeafAt(level, curX2 + dx, topY2 + 1, curZ2 + dz);
}
}
}
}
for (int lx = -2; lx <= 2; lx++) {
for (int lz = -2; lz <= 2; lz++) {
if (abs(lx) == 2 && abs(lz) == 2) continue;
placeLeaf(level, x + lx, y + 1, z + lz);
}
}
}
void SavannaTreeFeature::placeLeaf(Level* level, int x, int y, int z) {
if (level->getTile(x, y, z) == 0) {
placeBlock(level, x, y, z, Tile::leaves2_Id, 0);
}
return true;
}

View file

@ -1,28 +1,18 @@
#pragma once
#include "net.minecraft.world.level.levelgen.feature.h"
#include "Feature.h"
#include "AbstractTreeFeature.h"
class SavannaTreeFeature : public Feature
class SavannaTreeFeature : public AbstractTreeFeature
{
public:
SavannaTreeFeature(bool doUpdate);
virtual bool place(Level* level, Random* random, int x, int y, int z) override;
private:
int baseHeight;
static int s_logState;
static int s_leafState;
void generateBendingTree(Level* level, Random* random, int x, int y, int z, int height);
void generateForkingTree(Level* level, Random* random, int x, int y, int z, int height);
void generateLeafCap(Level* level, int x, int y, int z);
void placeLeaf(Level* level, int x, int y, int z);
void placeLog(Level* level, int x, int y, int z);
void placeLeafAt(Level* level, int x, int y, int z);
void placeLeavesLayer3(Level* level, int cx, int cy, int cz);
void placeLeavesLayer1(Level* level, int cx, int cy, int cz);
};

View file

@ -0,0 +1,8 @@
#pragma once
#include "ByteArrayTag.h"
class SuperflatConfig {
public:
ByteArrayTag* toTag();
};

View file

@ -1459,6 +1459,7 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_LEVELGEN
"${CMAKE_CURRENT_SOURCE_DIR}/TheEndLevelRandomLevelSource.h"
"${CMAKE_CURRENT_SOURCE_DIR}/TownFeature.h"
"${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.level.levelgen.h"
"${CMAKE_CURRENT_SOURCE_DIR}/SuperflatConfig.h"
)
source_group("net/minecraft/world/level/levelgen" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_LEVELGEN})