5 New Technical Biomes

This commit is contained in:
Lord Cambion 2026-03-24 13:41:49 +01:00
parent d10deb4cc2
commit 6fc2808592
37 changed files with 1782 additions and 766 deletions

View file

@ -1858,31 +1858,31 @@ bool TileRenderer::tesselateLeverInWorld( Tile* tt, int x, int y, int z )
if ( flipped )
{
corners[i]->z -= 1 / 16.0f;
corners[i]->xRot( 40 * PI / 180 );
corners[i]->xRotInPlace( 40 * PI / 180 );
}
else
{
corners[i]->z += 1 / 16.0f;
corners[i]->xRot( -40 * PI / 180 );
corners[i]->xRotInPlace( -40 * PI / 180 );
}
if (dir == 0 || dir == 7)
{
corners[i]->zRot(180 * PI / 180);
corners[i]->zRotInPlace(180 * PI / 180);
}
if ( dir == 6 || dir == 0 )
{
corners[i]->yRot( 90 * PI / 180 );
corners[i]->yRotInPlace( 90 * PI / 180 );
}
if ( dir > 0 && dir < 5 )
{
corners[i]->y -= 6 / 16.0f;
corners[i]->xRot( 90 * PI / 180 );
corners[i]->xRotInPlace( 90 * PI / 180 );
if ( dir == 4 ) corners[i]->yRot( 0 * PI / 180 );
if ( dir == 3 ) corners[i]->yRot( 180 * PI / 180 );
if ( dir == 2 ) corners[i]->yRot( 90 * PI / 180 );
if ( dir == 1 ) corners[i]->yRot( -90 * PI / 180 );
if ( dir == 4 ) corners[i]->yRotInPlace( 0 * PI / 180 );
if ( dir == 3 ) corners[i]->yRotInPlace( 180 * PI / 180 );
if ( dir == 2 ) corners[i]->yRotInPlace( 90 * PI / 180 );
if ( dir == 1 ) corners[i]->yRotInPlace( -90 * PI / 180 );
corners[i]->x += x + 0.5;
corners[i]->y += y + 8 / 16.0f;
@ -2047,26 +2047,26 @@ bool TileRenderer::tesselateTripwireSourceInWorld(Tile *tt, int x, int y, int z)
if (powered)
{
corners[i]->xRot(30 * PI / 180);
corners[i]->xRotInPlace(30 * PI / 180);
corners[i]->y -= 7 / 16.0f;
}
else if (attached)
{
corners[i]->xRot(5 * PI / 180);
corners[i]->xRotInPlace(5 * PI / 180);
corners[i]->y -= 7 / 16.0f;
}
else
{
corners[i]->xRot(-40 * PI / 180);
corners[i]->xRotInPlace(-40 * PI / 180);
corners[i]->y -= 6 / 16.0f;
}
corners[i]->xRot(90 * PI / 180);
corners[i]->xRotInPlace(90 * PI / 180);
if (dir == Direction::NORTH) corners[i]->yRot(0 * PI / 180);
if (dir == Direction::SOUTH) corners[i]->yRot(180 * PI / 180);
if (dir == Direction::WEST) corners[i]->yRot(90 * PI / 180);
if (dir == Direction::EAST) corners[i]->yRot(-90 * PI / 180);
if (dir == Direction::NORTH) corners[i]->yRotInPlace(0 * PI / 180);
if (dir == Direction::SOUTH) corners[i]->yRotInPlace(180 * PI / 180);
if (dir == Direction::WEST) corners[i]->yRotInPlace(90 * PI / 180);
if (dir == Direction::EAST) corners[i]->yRotInPlace(-90 * PI / 180);
corners[i]->x += x + 0.5;
corners[i]->y += y + 5 / 16.0f;
@ -2158,23 +2158,23 @@ bool TileRenderer::tesselateTripwireSourceInWorld(Tile *tt, int x, int y, int z)
{
corners[i]->y -= 1.5 / 16.0f;
corners[i]->z -= 2.6 / 16.0f;
corners[i]->xRot(0 * PI / 180);
corners[i]->xRotInPlace(0 * PI / 180);
}
else if (attached)
{
corners[i]->y += 0.25 / 16.0f;
corners[i]->z -= 2.75 / 16.0f;
corners[i]->xRot(10 * PI / 180);
corners[i]->xRotInPlace(10 * PI / 180);
}
else
{
corners[i]->xRot(50 * PI / 180);
corners[i]->xRotInPlace(50 * PI / 180);
}
if (dir == Direction::NORTH) corners[i]->yRot(0 * PI / 180);
if (dir == Direction::SOUTH) corners[i]->yRot(180 * PI / 180);
if (dir == Direction::WEST) corners[i]->yRot(90 * PI / 180);
if (dir == Direction::EAST) corners[i]->yRot(-90 * PI / 180);
if (dir == Direction::NORTH) corners[i]->yRotInPlace(0 * PI / 180);
if (dir == Direction::SOUTH) corners[i]->yRotInPlace(180 * PI / 180);
if (dir == Direction::WEST) corners[i]->yRotInPlace(90 * PI / 180);
if (dir == Direction::EAST) corners[i]->yRotInPlace(-90 * PI / 180);
corners[i]->x += x + 0.5;
corners[i]->y += y + 5 / 16.0f;

View file

@ -13,6 +13,8 @@
Biome *Biome::biomes[256];
Biome *Biome::ocean = nullptr;
Biome *Biome::plains = nullptr;
Biome *Biome::desert = nullptr;
@ -39,14 +41,23 @@ Biome *Biome::jungleHills = nullptr;
Biome *Biome::savanna = nullptr;
Biome *Biome::roofedForest = nullptr;
Biome *Biome::flowerForest = nullptr;
Biome *Biome::birchForest = nullptr;
Biome *Biome::birchForestHills = nullptr;
Biome *Biome::birchForestHillsM = nullptr;
Biome *Biome::birchForestM = nullptr;
Biome *Biome::deepOcean = nullptr;
Biome *Biome::roofedForestM = nullptr;
void Biome::staticCtor()
{
Biome::ocean = (new OceanBiome(0))->setColor(0x000070)->setName(L"Ocean")->setDepthAndScale(-1, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Ocean, eMinecraftColour_Foliage_Ocean, eMinecraftColour_Water_Ocean,eMinecraftColour_Sky_Ocean);
Biome::ocean = (new OceanBiome(0))->setColor(0x000070)->setName(L"Ocean")->setDepthAndScale(-1, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Ocean, eMinecraftColour_Foliage_Ocean, eMinecraftColour_Water_Ocean,eMinecraftColour_Sky_Ocean);
Biome::plains = (new PlainsBiome(1))->setColor(0x8db360)->setName(L"Plains")->setTemperatureAndDownfall(0.8f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Plains, eMinecraftColour_Foliage_Plains, eMinecraftColour_Water_Plains,eMinecraftColour_Sky_Plains);
Biome::desert = (new DesertBiome(2))->setColor(0xFA9418)->setName(L"Desert")->setNoRain()->setTemperatureAndDownfall(2, 0)->setDepthAndScale(0.1f, 0.2f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Desert, eMinecraftColour_Foliage_Desert, eMinecraftColour_Water_Desert,eMinecraftColour_Sky_Desert);
Biome::extremeHills = (new ExtremeHillsBiome(3))->setColor(0x606060)->setName(L"Extreme Hills")->setDepthAndScale(0.3f, 1.5f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills, eMinecraftColour_Foliage_ExtremeHills, eMinecraftColour_Water_ExtremeHills,eMinecraftColour_Sky_ExtremeHills);
// Foreste Base
Biome::forest = (new ForestBiome(4,0))->setColor(0x056621)->setName(L"Forest")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.7f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Forest, eMinecraftColour_Water_Forest,eMinecraftColour_Sky_Forest);
Biome::forestHills = (new ForestBiome(18,0))->setColor(0x22551c)->setName(L"ForestHills")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.7f, 0.8f)->setDepthAndScale(0.3f, 0.7f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_ForestHills, eMinecraftColour_Water_ForestHills,eMinecraftColour_Sky_ForestHills);
Biome::taiga = (new TaigaBiome(5))->setColor(0x0b6659)->setName(L"Taiga")->setLeafColor(0x4EBA31)->setSnowCovered()->setTemperatureAndDownfall(0.05f, 0.8f)->setDepthAndScale(0.1f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Taiga, eMinecraftColour_Foliage_Taiga, eMinecraftColour_Water_Taiga,eMinecraftColour_Sky_Taiga);
Biome::swampland = (new SwampBiome(6))->setColor(0x07F9B2)->setName(L"Swampland")->setLeafColor(0x8BAF48)->setDepthAndScale(-0.2f, 0.1f)->setTemperatureAndDownfall(0.8f, 0.9f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Swampland, eMinecraftColour_Foliage_Swampland, eMinecraftColour_Water_Swampland,eMinecraftColour_Sky_Swampland);
@ -61,17 +72,25 @@ void Biome::staticCtor()
Biome::mushroomIslandShore = (new MushroomIslandBiome(15))->setColor(0xa000ff)->setName(L"MushroomIslandShore")->setTemperatureAndDownfall(0.9f, 1.0f)->setDepthAndScale(-1, 0.1f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_MushroomIslandShore, eMinecraftColour_Foliage_MushroomIslandShore, eMinecraftColour_Water_MushroomIslandShore,eMinecraftColour_Sky_MushroomIslandShore);
Biome::beaches = (new BeachBiome(16))->setColor(0xfade55)->setName(L"Beach")->setTemperatureAndDownfall(0.8f, 0.4f)->setDepthAndScale(0.0f, 0.1f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Beach, eMinecraftColour_Foliage_Beach, eMinecraftColour_Water_Beach,eMinecraftColour_Sky_Beach);
Biome::desertHills = (new DesertBiome(17))->setColor(0xd25f12)->setName(L"DesertHills")->setNoRain()->setTemperatureAndDownfall(2, 0)->setDepthAndScale(0.3f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_DesertHills, eMinecraftColour_Foliage_DesertHills, eMinecraftColour_Water_DesertHills,eMinecraftColour_Sky_DesertHills);
Biome::forestHills = (new ForestBiome(18,1))->setColor(0x22551c)->setName(L"ForestHills")->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.7f, 0.8f)->setDepthAndScale(0.3f, 0.7f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_ForestHills, eMinecraftColour_Water_ForestHills,eMinecraftColour_Sky_ForestHills);
Biome::taigaHills = (new TaigaBiome(19))->setColor(0x163933)->setName(L"TaigaHills")->setSnowCovered()->setLeafColor(0x4EBA31)->setTemperatureAndDownfall(0.05f, 0.8f)->setDepthAndScale(0.3f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_TaigaHills, eMinecraftColour_Foliage_TaigaHills, eMinecraftColour_Water_TaigaHills,eMinecraftColour_Sky_TaigaHills);
Biome::smallerExtremeHills = (new ExtremeHillsBiome(20))->setColor(0x72789a)->setName(L"Extreme Hills Edge")->setDepthAndScale(0.2f, 0.8f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHillsEdge, eMinecraftColour_Foliage_ExtremeHillsEdge, eMinecraftColour_Water_ExtremeHillsEdge,eMinecraftColour_Sky_ExtremeHillsEdge);
Biome::jungle = (new JungleBiome(21))->setColor(0x537b09)->setName(L"Jungle")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(0.2f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_Jungle,eMinecraftColour_Sky_Jungle);
Biome::jungleHills = (new JungleBiome(22))->setColor(0x2c4205)->setName(L"JungleHills")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(1.8f, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_JungleHills, eMinecraftColour_Foliage_JungleHills, eMinecraftColour_Water_JungleHills,eMinecraftColour_Sky_JungleHills);
Biome::savanna = (new SavannaBiome(35))->setColor(0xbda235)->setName(L"Savanna")->setNoRain()->setTemperatureAndDownfall(1.2f, 0.0f) ->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Savanna, eMinecraftColour_Foliage_Savanna, eMinecraftColour_Sky_Desert, eMinecraftColour_Sky_Desert);
Biome::deepOcean= (new OceanBiome(24))->setName(L"Deep Ocean")->setDepthAndScale(-1.8,0.1f)->setColor(0x000070)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Ocean, eMinecraftColour_Foliage_Ocean, eMinecraftColour_Water_Ocean,eMinecraftColour_Sky_Ocean);;
// Foreste Avanzate e Speciali
Biome::roofedForest = (new ForestBiome(29, 3))->setColor(0x056621)->setName(L"Roofed Forest")->setTemperatureAndDownfall(0.7f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_RoofedForest, eMinecraftColour_Foliage_RoofedForest, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest);
Biome::flowerForest = (new ForestBiome(132, 1))->setColor(0x056621)->setName(L"Flower Forest")->setTemperatureAndDownfall(0.7f, 0.8f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Forest, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest);
}
// Nuovi Biomi Betulla
Biome::birchForest=(new ForestBiome(27, 2))->setColor(0x307444)->setName(L"Birch Forest")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest);
Biome::birchForestHills=(new ForestBiome(28, 2))->setColor(0x1f5f32)->setName(L"Birch Forest Hills")->setDepthAndScale(0.45f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_ForestHills);
// Varianti Mutate (M)
Biome::birchForestM=(new ForestBiome::MutatedBirchForestBiome(155, biomes[27]))->setColor(0x47875a)->setName(L"Birch Forest M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Forest, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest);
Biome::birchForestHillsM=(new ForestBiome::MutatedBirchForestBiome(156, biomes[28]))->setColor(0x47875a)->setName(L"Birch Forest Hills M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ForestHills, eMinecraftColour_Foliage_Birch, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_ForestHills);
Biome::roofedForestM=(new ForestBiome::MutatedForestBiome(157, biomes[29]))->setColor(0x177a35)->setName(L"Roofed Forest M")->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_RoofedForest, eMinecraftColour_Foliage_RoofedForest, eMinecraftColour_Water_Forest, eMinecraftColour_Sky_Forest);
}
Biome::Biome(int id) : id(id)
{
color = 0;
@ -86,7 +105,6 @@ Biome::Biome(int id) : id(id)
decorator = nullptr;
m_temperatureNoise = nullptr;
m_grassColor = eMinecraftColour_NOT_SET;
m_foliageColor = eMinecraftColour_NOT_SET;
m_waterColor = eMinecraftColour_NOT_SET;
@ -94,6 +112,10 @@ Biome::Biome(int id) : id(id)
biomes[id] = this;
decorator = createDecorator();
// -- FIX FIORI ED ERBA GLOBALI --
decorator->flowerCount = 2; // Valore base di fiori (esclusi biomi speciali che ne sovrascrivono il numero)
decorator->grassCount = 1; // Valore base di erba alta
friendlies.push_back(new MobSpawnerData(eTYPE_SHEEP, 12, 4, 4));
friendlies.push_back(new MobSpawnerData(eTYPE_PIG, 10, 4, 4));
friendlies_chicken.push_back(new MobSpawnerData(eTYPE_CHICKEN, 10, 4, 4));
@ -223,7 +245,7 @@ bool Biome::isHumid()
return downfall > .85f;
}
float Biome::getCreatureProbability()
float Biome::getCreatureProbability() const
{
return 0.1f;
}
@ -253,12 +275,12 @@ void Biome::decorate(Level *level, Random *random, int xo, int zo)
decorator->decorate(level, random, xo, zo);
}
int Biome::getGrassColor()
int Biome::getGrassColor() const
{
return Minecraft::GetInstance()->getColourTable()->getColor( m_grassColor );
}
int Biome::getFolageColor()
int Biome::getFoliageColor() const
{
return Minecraft::GetInstance()->getColourTable()->getColor( m_foliageColor );
}
@ -363,4 +385,53 @@ void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlock
}
}
}
}
float Biome::getTemperature(const BlockPos& pos)
{
return getTemperature(pos.getX(), pos.getY(), pos.getZ());
}
void Biome::buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, const BlockPos& pos, double noiseVal)
{
buildSurfaceAtDefault(level, random, chunkBlocks, pos.getX(), pos.getZ(), noiseVal);
}
bool Biome::isSame(const Biome* other) const
{
if (!other) return false;
return id == other->id;
}
int Biome::getTemperatureCategory() const
{
if (temperature < 0.2f) return 1;
if (temperature > 1.0f) return 3;
return 2;
}
void Biome::buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal)
{
buildSurfaceAtDefault(level, random, primer->getBlockIds(), x, z, noiseVal);
}
Feature *Biome::getFlowerFeature(Random *random, int x, int y, int z)
{
if (random->nextInt(3) > 0)
{
return new FlowerFeature(Tile::flower_Id);
}
return new FlowerFeature(Tile::rose_Id);
}
int Biome::getRandomDoublePlantType(Random *random)
{
int type = random->nextInt(10);
if (type < 7) return 0;
if (type == 7) return 3;
if (type == 8) return 4;
return 2;
}

View file

@ -4,6 +4,9 @@ using namespace std;
#include "LevelSource.h"
#include "Mob.h"
#include "WeighedRandom.h"
#include "BlockPos.h"
#include "ChunkPrimer.h"
class Feature;
class MobCategory;
@ -14,6 +17,8 @@ class BirchFeature;
class SwampTreeFeature;
class ChunkRebuildData;
class PerlinNoise;
class MutatedBiome;
class ChunkPrimer;
class Biome
{
@ -48,9 +53,20 @@ public:
static Biome *jungleHills;
static Biome *savanna;
static Biome *roofedForest;
static Biome *flowerForest;
static const int BIOME_COUNT = 23; // 4J Stu added
static Biome *flowerForest;
static Biome *Biome::birchForest;
static Biome *Biome::birchForestHills ;
static Biome *Biome::birchForestM ;
static Biome *Biome::birchForestHillsM;
static Biome *Biome::roofedForestM;
static Biome *Biome::deepOcean;
static const int BIOME_COUNT = 32;
public:
wstring m_name;
@ -75,7 +91,8 @@ public:
int minCount;
int maxCount;
MobSpawnerData(eINSTANCEOF mobClass, int probabilityWeight, int minCount, int maxCount) : WeighedRandomItem(probabilityWeight)
MobSpawnerData(eINSTANCEOF mobClass, int probabilityWeight, int minCount, int maxCount)
: WeighedRandomItem(probabilityWeight)
{
this->mobClass = mobClass;
this->minCount = minCount;
@ -83,7 +100,7 @@ public:
}
};
protected:
public:
vector<MobSpawnerData *> enemies;
vector<MobSpawnerData *> friendlies;
vector<MobSpawnerData *> waterFriendlies;
@ -104,7 +121,6 @@ public:
bool snowCovered;
bool _hasRain;
// 4J Added
eMinecraftColour m_grassColor;
eMinecraftColour m_foliageColor;
eMinecraftColour m_waterColor;
@ -121,12 +137,11 @@ protected:
Biome *setName(const wstring &name);
Biome *setLeafColor(int leafColor);
public:
public:
virtual Biome *setColor(int color, bool b = false);
// 4J Added
Biome *setLeafFoliageWaterSkyColor(eMinecraftColour grassColor, eMinecraftColour foliageColor, eMinecraftColour waterColour, eMinecraftColour skyColour);
Biome *setLeafFoliageWaterSkyColor(eMinecraftColour grassColor, eMinecraftColour foliageColor,
eMinecraftColour waterColour, eMinecraftColour skyColour);
public:
virtual int getSkyColor(float temp);
@ -137,22 +152,49 @@ public:
virtual bool hasRain();
virtual bool isHumid();
virtual float getCreatureProbability();
virtual int getDownfallInt();
virtual int getTemperatureInt();
virtual float getDownfall();
virtual float getTemperature();
virtual float getTemperature(int x, int y, int z);
virtual float getTemperature(const BlockPos& pos);
virtual float getTemperature(int x, int y, int z);
virtual void decorate(Level *level, Random *random, int xo, int zo);
virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, int x, int z, double noiseVal);
virtual int getGrassColor();
virtual int getFolageColor();
virtual void buildSurfaceAtDefault(Level *level, Random *random, byte* chunkBlocks, const BlockPos& pos, double noiseVal);
virtual int getWaterColor();
public:
void setWaterSkyColor(int waterRGB, int skyRGB) {
m_waterColor = (eMinecraftColour)waterRGB;
m_skyColor = (eMinecraftColour)skyRGB;
}
void setDebugName(const wstring& name) { m_name = name; }
int getWaterColor() const { return m_waterColor; }
int getSkyColor() const { return m_skyColor; }
virtual int getBaseBiomeId() const { return id; }
virtual int getFoliageColor() const; // rename from getFolageColor
virtual bool isSame(const Biome* other) const;
virtual int getTemperatureCategory() const;
virtual void buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal);
virtual float getCreatureProbability() const;
virtual int getGrassColor() const;
virtual int Biome::getFolageColor()const{
return getFoliageColor(); }
virtual Feature *getFlowerFeature(Random *random, int x, int y, int z);
virtual int getRandomDoublePlantType(Random *random);
};

View file

@ -3,370 +3,393 @@
#include "net.minecraft.world.level.tile.h"
#include "net.minecraft.world.level.levelgen.feature.h"
#include "net.minecraft.world.level.biome.h"
#include "Rose.h"
#include "TallGrass.h"
#include "Tallgrass2.h"
#include "DoublePlantFeature.h"
BiomeDecorator::BiomeDecorator(Biome *biome)
{
_init();
_init();
// 4J inits
level = nullptr;
random = nullptr;
xo = 0;
zo = 0;
// 4J inits
level = nullptr;
random = nullptr;
xo = 0;
zo = 0;
this->biome = biome;
this->biome = biome;
}
void BiomeDecorator::decorate(Level *level, Random *random, int xo, int zo)
{
if (this->level != nullptr)
{
app.DebugPrintf("BiomeDecorator::decorate - Already decorating!!\n");
if (this->level != nullptr)
{
app.DebugPrintf("BiomeDecorator::decorate - Already decorating!!\n");
#ifndef _CONTENT_PACKAGE
__debugbreak();
//throw new RuntimeException("Already decorating!!");
__debugbreak();
//throw new RuntimeException("Already decorating!!");
#endif
}
this->level = level;
this->random = random;
this->xo = xo;
this->zo = zo;
}
this->level = level;
this->random = random;
this->xo = xo;
this->zo = zo;
decorate();
decorate();
this->level = nullptr;
this->random = nullptr;
this->level = nullptr;
this->random = nullptr;
}
void BiomeDecorator::_init()
{
clayFeature = new ClayFeature(4);
sandFeature = new SandFeature(7, Tile::sand_Id);
gravelFeature = new SandFeature(6, Tile::gravel_Id);
dirtOreFeature = new OreFeature(Tile::dirt_Id, 32);
gravelOreFeature = new OreFeature(Tile::gravel_Id, 32);
coalOreFeature = new OreFeature(Tile::coalOre_Id, 16);
ironOreFeature = new OreFeature(Tile::ironOre_Id, 8);
goldOreFeature = new OreFeature(Tile::goldOre_Id, 8);
redStoneOreFeature = new OreFeature(Tile::redStoneOre_Id, 7);
diamondOreFeature = new OreFeature(Tile::diamondOre_Id, 7);
lapisOreFeature = new OreFeature(Tile::lapisOre_Id, 6);
yellowFlowerFeature = new FlowerFeature(Tile::flower_Id);
roseFlowerFeature = new FlowerFeature(Tile::rose_Id);
brownMushroomFeature = new FlowerFeature(Tile::mushroom_brown_Id);
redMushroomFeature = new FlowerFeature(Tile::mushroom_red_Id);
hugeMushroomFeature = new HugeMushroomFeature();
reedsFeature = new ReedsFeature();
cactusFeature = new CactusFeature();
waterlilyFeature = new WaterlilyFeature();
blueOrchidFeature = new FlowerFeature(Tile::rose_Id, Rose::BLUE_ORCHID);
alliumFeature = new FlowerFeature(Tile::rose_Id, Rose::ALLIUM);
azureBluetFeature = new FlowerFeature(Tile::rose_Id, Rose::AZURE_BLUET);
oxeyeDaisyFeature = new FlowerFeature(Tile::rose_Id, Rose::OXEYE_DAISY);
clayFeature = new ClayFeature(4);
sandFeature = new SandFeature(7, Tile::sand_Id);
gravelFeature = new SandFeature(6, Tile::gravel_Id);
dirtOreFeature = new OreFeature(Tile::dirt_Id, 32);
gravelOreFeature = new OreFeature(Tile::gravel_Id, 32);
coalOreFeature = new OreFeature(Tile::coalOre_Id, 16);
ironOreFeature = new OreFeature(Tile::ironOre_Id, 8);
goldOreFeature = new OreFeature(Tile::goldOre_Id, 8);
redStoneOreFeature = new OreFeature(Tile::redStoneOre_Id, 7);
diamondOreFeature = new OreFeature(Tile::diamondOre_Id, 7);
lapisOreFeature = new OreFeature(Tile::lapisOre_Id, 6);
yellowFlowerFeature = new FlowerFeature(Tile::flower_Id);
roseFlowerFeature = new FlowerFeature(Tile::rose_Id);
brownMushroomFeature = new FlowerFeature(Tile::mushroom_brown_Id);
redMushroomFeature = new FlowerFeature(Tile::mushroom_red_Id);
hugeMushroomFeature = new HugeMushroomFeature();
reedsFeature = new ReedsFeature();
cactusFeature = new CactusFeature();
waterlilyFeature = new WaterlilyFeature();
blueOrchidFeature = new FlowerFeature(Tile::rose_Id, Rose::BLUE_ORCHID);
alliumFeature = new FlowerFeature(Tile::rose_Id, Rose::ALLIUM);
azureBluetFeature = new FlowerFeature(Tile::rose_Id, Rose::AZURE_BLUET);
oxeyeDaisyFeature = new FlowerFeature(Tile::rose_Id, Rose::OXEYE_DAISY);
tulipRedFeature = new FlowerFeature(Tile::rose_Id, Rose::RED_TULIP);
tulipOrangeFeature = new FlowerFeature(Tile::rose_Id, Rose::ORANGE_TULIP);
tulipWhiteFeature = new FlowerFeature(Tile::rose_Id, Rose::WHITE_TULIP);
tulipPinkFeature = new FlowerFeature(Tile::rose_Id, Rose::PINK_TULIP);
waterlilyCount = 0;
treeCount = 0;
flowerCount = 2;
grassCount = 1;
deadBushCount = 0;
mushroomCount = 0;
reedsCount = 0;
cactusCount = 0;
gravelCount = 1;
sandCount = 3;
clayCount = 1;
hugeMushrooms = 0;
blueOrchidCount = 0;
alliumCount = 0;
azureBluetCount = 0;
oxeyeDaisyCount = 0;
liquids = true;
doublePlantFeature = new DoublePlantFeature(false);
waterlilyCount = 0;
treeCount = 0;
flowerCount = 2;
grassCount = 1;
deadBushCount = 0;
mushroomCount = 0;
reedsCount = 0;
cactusCount = 0;
gravelCount = 1;
sandCount = 3;
clayCount = 1;
hugeMushrooms = 0;
blueOrchidCount = 0;
alliumCount = 0;
azureBluetCount = 0;
oxeyeDaisyCount = 0;
liquids = true;
}
void BiomeDecorator::decorate()
{
PIXBeginNamedEvent(0,"Decorate ores");
decorateOres();
PIXEndNamedEvent();
PIXBeginNamedEvent(0,"Decorate ores");
decorateOres();
PIXEndNamedEvent();
PIXBeginNamedEvent(0,"Decorate sand/clay/gravel");
for (int i = 0; i < sandCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
sandFeature->place(level, random, x, level->getTopSolidBlock(x, z), z);
}
PIXBeginNamedEvent(0,"Decorate sand/clay/gravel");
for (int i = 0; i < sandCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
sandFeature->place(level, random, x, level->getTopSolidBlock(x, z), z);
}
for (int i = 0; i < clayCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
clayFeature->place(level, random, x, level->getTopSolidBlock(x, z), z);
}
for (int i = 0; i < clayCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
clayFeature->place(level, random, x, level->getTopSolidBlock(x, z), z);
}
for (int i = 0; i < gravelCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
sandFeature->place(level, random, x, level->getTopSolidBlock(x, z), z);
}
PIXEndNamedEvent();
for (int i = 0; i < gravelCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
sandFeature->place(level, random, x, level->getTopSolidBlock(x, z), z);
}
PIXEndNamedEvent();
PIXBeginNamedEvent(0, "Decorate forests");
int forests = treeCount;
if (random->nextInt(10) == 0) forests += 1;
PIXBeginNamedEvent(0, "Decorate forests");
int forests = treeCount;
if (random->nextInt(10) == 0) forests += 1;
for (int i = 0; i < forests; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
Feature *tree = biome->getTreeFeature(random);
tree->init(1, 1, 1);
tree->place(level, random, x, level->getHeightmap(x, z), z);
delete tree;
}
PIXEndNamedEvent();
for (int i = 0; i < forests; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
Feature *tree = biome->getTreeFeature(random);
tree->init(1, 1, 1);
tree->place(level, random, x, level->getHeightmap(x, z), z);
delete tree;
}
PIXEndNamedEvent();
PIXBeginNamedEvent(0,"Decorate mushrooms/flowers/grass");
for (int i = 0; i < hugeMushrooms; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
hugeMushroomFeature->place(level, random, x, level->getHeightmap(x, z), z);
}
PIXBeginNamedEvent(0,"Decorate mushrooms/flowers/grass");
for (int i = 0; i < hugeMushrooms; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
hugeMushroomFeature->place(level, random, x, level->getHeightmap(x, z), z);
}
for (int i = 0; i < flowerCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
yellowFlowerFeature->place(level, random, x, y, z);
for (int i = 0; i < flowerCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
Feature* selectedFlower = biome->getFlowerFeature(random, x, y, z);
if (selectedFlower != nullptr)
{
selectedFlower->place(level, random, x, y, z);
delete selectedFlower;
}
}
if (random->nextInt(4) == 0)
{
x = xo + random->nextInt(16) + 8;
y = random->nextInt(Level::genDepth);
z = zo + random->nextInt(16) + 8;
roseFlowerFeature->place(level, random, x, y, z);
}
}
//forced biomes
for (int i = 0; i < blueOrchidCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
blueOrchidFeature->place(level, random, x, y, z);
}
for (int i = 0; i < alliumCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
alliumFeature->place(level, random, x, y, z);
}
for (int i = 0; i < azureBluetCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
azureBluetFeature->place(level, random, x, y, z);
}
// Nuovi fiori — generati solo se il bioma ha impostato il contatore
for (int i = 0; i < blueOrchidCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
blueOrchidFeature->place(level, random, x, y, z);
}
for (int i = 0; i < oxeyeDaisyCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
oxeyeDaisyFeature->place(level, random, x, y, z);
}
for (int i = 0; i < alliumCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
alliumFeature->place(level, random, x, y, z);
}
// 1block grass
for (int i = 0; i < grassCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
MemSect(50);
Feature *grassFeature = biome->getGrassFeature(random);
MemSect(0);
if (grassFeature)
{
grassFeature->place(level, random, x, y, z);
delete grassFeature;
}
}
for (int i = 0; i < azureBluetCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
azureBluetFeature->place(level, random, x, y, z);
}
// 2blockstall
int doublePlantsToGen = (grassCount + flowerCount) / 2;
if (doublePlantsToGen > 0 && random->nextInt(3) == 0)
{
for (int i = 0; i < doublePlantsToGen; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
int plantType = biome->getRandomDoublePlantType(random);
DoublePlantFeature* dpf = static_cast<DoublePlantFeature*>(doublePlantFeature);
dpf->setPlantType(plantType);
dpf->place(level, random, x, y, z);
}
}
PIXEndNamedEvent();
for (int i = 0; i < oxeyeDaisyCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
oxeyeDaisyFeature->place(level, random, x, y, z);
}
PIXBeginNamedEvent(0,"Decorate bush/waterlily/mushroom/reeds/pumpkins/cactuses");
for (int i = 0; i < grassCount; i++)
{
//int grassType = TallGrass::TALL_GRASS;
DeadBushFeature *deadBushFeature = nullptr;
if(deadBushCount > 0) deadBushFeature = new DeadBushFeature(Tile::deadBush_Id);
for (int i = 0; i < deadBushCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
deadBushFeature->place(level, random, x, y, z);
}
if(deadBushFeature != nullptr) delete deadBushFeature;
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
MemSect(50);
Feature *grassFeature = biome->getGrassFeature(random);
MemSect(0);
grassFeature->place(level, random, x, y, z);
delete grassFeature;
}
PIXEndNamedEvent();
PIXBeginNamedEvent(0,"Decorate bush/waterlily/mushroom/reeds/pumpkins/cactuses");
for (int i = 0; i < waterlilyCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
while (y > 0 && level->getTile(x, y - 1, z) == 0)
y--;
waterlilyFeature->place(level, random, x, y, z);
}
// 4J Stu - For some reason this was created each time round in the loop
// I assume there is a case where deadBushCount could be 0
DeadBushFeature *deadBushFeature = nullptr;
if(deadBushCount > 0) deadBushFeature = new DeadBushFeature(Tile::deadBush_Id);
for (int i = 0; i < deadBushCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
//new DeadBushFeature(Tile::deadBush_Id)->place(level, random, x, y, z);
deadBushFeature->place(level, random, x, y, z);
}
if(deadBushFeature != nullptr)delete deadBushFeature;
for (int i = 0; i < mushroomCount; i++)
{
if (random->nextInt(4) == 0)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
int y = level->getHeightmap(x, z);
brownMushroomFeature->place(level, random, x, y, z);
}
for (int i = 0; i < waterlilyCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
while (y > 0 && level->getTile(x, y - 1, z) == 0)
y--;
waterlilyFeature->place(level, random, x, y, z);
}
if (random->nextInt(8) == 0)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
redMushroomFeature->place(level, random, x, y, z);
}
}
for (int i = 0; i < mushroomCount; i++)
{
if (random->nextInt(4) == 0)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
int y = level->getHeightmap(x, z);
brownMushroomFeature->place(level, random, x, y, z);
}
if (random->nextInt(4) == 0)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
brownMushroomFeature->place(level, random, x, y, z);
}
if (random->nextInt(8) == 0)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
redMushroomFeature->place(level, random, x, y, z);
}
}
if (random->nextInt(8) == 0)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
redMushroomFeature->place(level, random, x, y, z);
}
if (random->nextInt(4) == 0)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
brownMushroomFeature->place(level, random, x, y, z);
}
for (int i = 0; i < reedsCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
reedsFeature->place(level, random, x, y, z);
}
if (random->nextInt(8) == 0)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
redMushroomFeature->place(level, random, x, y, z);
}
for (int i = 0; i < 10; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
reedsFeature->place(level, random, x, y, z);
}
for (int i = 0; i < reedsCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int z = zo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
reedsFeature->place(level, random, x, y, z);
}
if (random->nextInt(32) == 0)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
PumpkinFeature *pumpkinFeature = new PumpkinFeature();
pumpkinFeature->place(level, random, x, y, z);
delete pumpkinFeature;
}
for (int i = 0; i < 10; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
reedsFeature->place(level, random, x, y, z);
}
for (int i = 0; i < cactusCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
cactusFeature->place(level, random, x, y, z);
}
if (random->nextInt(32) == 0)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
PumpkinFeature *pumpkinFeature = new PumpkinFeature();
pumpkinFeature->place(level, random, x, y, z);
delete pumpkinFeature;
}
PIXEndNamedEvent();
PIXBeginNamedEvent(0,"Decorate liquids");
for (int i = 0; i < cactusCount; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(Level::genDepth);
int z = zo + random->nextInt(16) + 8;
cactusFeature->place(level, random, x, y, z);
}
if( liquids )
{
SpringFeature *waterSpringFeature = new SpringFeature(Tile::water_Id);
for (int i = 0; i < 50; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(random->nextInt(Level::genDepth - 8) + 8);
int z = zo + random->nextInt(16) + 8;
waterSpringFeature->place(level, random, x, y, z);
}
delete waterSpringFeature;
PIXEndNamedEvent();
PIXBeginNamedEvent(0,"Decorate liquids");
if( liquids )
{
// 4J Stu - For some reason this was created each time round in the loop
SpringFeature *waterSpringFeature = new SpringFeature(Tile::water_Id);
for (int i = 0; i < 50; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(random->nextInt(Level::genDepth - 8) + 8);
int z = zo + random->nextInt(16) + 8;
waterSpringFeature->place(level, random, x, y, z);
}
delete waterSpringFeature;
// 4J Stu - For some reason this was created each time round in the loop
SpringFeature *lavaSpringFeature = new SpringFeature(Tile::lava_Id);
for (int i = 0; i < 20; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(random->nextInt(random->nextInt(Level::genDepth - 16) + 8) + 8);
int z = zo + random->nextInt(16) + 8;
lavaSpringFeature->place(level, random, x, y, z);
}
delete lavaSpringFeature;
}
PIXEndNamedEvent();
SpringFeature *lavaSpringFeature = new SpringFeature(Tile::lava_Id);
for (int i = 0; i < 20; i++)
{
int x = xo + random->nextInt(16) + 8;
int y = random->nextInt(random->nextInt(random->nextInt(Level::genDepth - 16) + 8) + 8);
int z = zo + random->nextInt(16) + 8;
lavaSpringFeature->place(level, random, x, y, z);
}
delete lavaSpringFeature;
}
PIXEndNamedEvent();
}
void BiomeDecorator::decorate(int count, Feature *feature)
{
decorateDepthSpan(count, feature, 0, Level::genDepth);
decorateDepthSpan(count, feature, 0, Level::genDepth);
}
void BiomeDecorator::decorateDepthSpan(int count, Feature *feature, int y0, int y1)
{
for (int i = 0; i < count; i++)
{
int x = xo + random->nextInt(16);
int y = random->nextInt(y1 - y0) + y0;
int z = zo + random->nextInt(16);
feature->place(level, random, x, y, z);
}
for (int i = 0; i < count; i++)
{
int x = xo + random->nextInt(16);
int y = random->nextInt(y1 - y0) + y0;
int z = zo + random->nextInt(16);
feature->place(level, random, x, y, z);
}
}
void BiomeDecorator::decorateDepthAverage(int count, Feature *feature, int yMid, int ySpan)
{
for (int i = 0; i < count; i++)
{
int x = xo + random->nextInt(16);
int y = random->nextInt(ySpan) + random->nextInt(ySpan) + (yMid - ySpan);
int z = zo + random->nextInt(16);
feature->place(level, random, x, y, z);
}
for (int i = 0; i < count; i++)
{
int x = xo + random->nextInt(16);
int y = random->nextInt(ySpan) + random->nextInt(ySpan) + (yMid - ySpan);
int z = zo + random->nextInt(16);
feature->place(level, random, x, y, z);
}
}
void BiomeDecorator::decorateOres()
{
level->setInstaTick(true); // 4J - optimisation
decorateDepthSpan(20, dirtOreFeature, 0, Level::genDepth);
decorateDepthSpan(10, gravelOreFeature, 0, Level::genDepth);
decorateDepthSpan(20, coalOreFeature, 0, Level::genDepth);
decorateDepthSpan(20, ironOreFeature, 0, Level::genDepth / 2);
decorateDepthSpan(2, goldOreFeature, 0, Level::genDepth / 4);
decorateDepthSpan(8, redStoneOreFeature, 0, Level::genDepth / 8);
decorateDepthSpan(1, diamondOreFeature, 0, Level::genDepth / 8);
decorateDepthAverage(1, lapisOreFeature, Level::genDepth / 8, Level::genDepth / 8);
level->setInstaTick(false);
}
level->setInstaTick(true); // 4J - optimisation
decorateDepthSpan(20, dirtOreFeature, 0, Level::genDepth);
decorateDepthSpan(10, gravelOreFeature, 0, Level::genDepth);
decorateDepthSpan(20, coalOreFeature, 0, Level::genDepth);
decorateDepthSpan(20, ironOreFeature, 0, Level::genDepth / 2);
decorateDepthSpan(2, goldOreFeature, 0, Level::genDepth / 4);
decorateDepthSpan(8, redStoneOreFeature, 0, Level::genDepth / 8);
decorateDepthSpan(1, diamondOreFeature, 0, Level::genDepth / 8);
decorateDepthAverage(1, lapisOreFeature, Level::genDepth / 8, Level::genDepth / 8);
level->setInstaTick(false);
}

View file

@ -16,7 +16,6 @@ class BiomeDecorator
friend class BeachBiome;
friend class SavannaBiome;
friend class JungleBiome;
friend class RoofedForestBiome;
friend class FlowerForestBiome;
protected:
Level *level;
@ -30,7 +29,7 @@ public:
void decorate(Level *level, Random *random, int xo, int zo);
protected:
public:
Feature *clayFeature;
Feature *sandFeature;
Feature *gravelFeature;
@ -54,6 +53,11 @@ protected:
Feature *alliumFeature;
Feature *azureBluetFeature;
Feature *oxeyeDaisyFeature;
Feature *tulipRedFeature;
Feature *tulipOrangeFeature;
Feature *tulipWhiteFeature;
Feature *tulipPinkFeature;
Feature *doublePlantFeature;
int waterlilyCount;
int treeCount;

View file

@ -21,7 +21,7 @@ BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptr<Layer>parent, LevelType
}
else
{
startBiomes = BiomeArray(10);
startBiomes = BiomeArray(16);
startBiomes[0] = Biome::desert;
startBiomes[1] = Biome::forest;
startBiomes[2] = Biome::extremeHills;
@ -32,6 +32,12 @@ BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptr<Layer>parent, LevelType
startBiomes[7] = Biome::savanna;
startBiomes[8] = Biome::roofedForest;
startBiomes[9] = Biome::flowerForest;
startBiomes[10] = Biome::birchForest;
startBiomes[11] = Biome::birchForestHills;
startBiomes[12] = Biome::birchForestM;
startBiomes[13] = Biome::birchForestHillsM;
startBiomes[14] = Biome::roofedForestM;
startBiomes[15] = Biome::deepOcean;
}
}

View file

@ -0,0 +1,188 @@
#include "stdafx.h"
#include "BlockPos.h"
#include "Entity.h"
#include "Direction.h"
#include "BlockSource.h"
#include <sstream>
#include <cmath>
const BlockPos BlockPos::ZERO = BlockPos(0, 0, 0);
// Costruttori
BlockPos::BlockPos() : Vec3i(0, 0, 0) {}
BlockPos::BlockPos(int x, int y, int z) : Vec3i(x, y, z) {}
BlockPos::BlockPos(double x, double y, double z)
: Vec3i((int)std::floor(x), (int)std::floor(y), (int)std::floor(z)) {}
BlockPos::BlockPos(const std::shared_ptr<Entity>& entity) : Vec3i(0, 0, 0) {
if (entity) {
x = (int)std::floor(entity->x);
y = (int)std::floor(entity->y);
z = (int)std::floor(entity->z);
}
}
BlockPos::BlockPos(const double* pos)
: Vec3i((int)std::floor(pos[0]), (int)std::floor(pos[1]), (int)std::floor(pos[2])) {}
BlockPos::BlockPos(const double* pos, bool fromEntity) : Vec3i(0, 0, 0) {
if (fromEntity) {
x = (int)std::floor(pos[10]);
y = (int)std::floor(pos[11]);
z = (int)std::floor(pos[12]);
} else {
x = (int)std::floor(pos[0]);
y = (int)std::floor(pos[1]);
z = (int)std::floor(pos[2]);
}
}
BlockPos::BlockPos(const Vec3i& other)
: Vec3i(other.getX(), other.getY(), other.getZ()) {}
BlockPos::BlockPos(int compressed) : Vec3i(0, 0, 0) {
*this = decompress(compressed);
}
BlockPos::BlockPos(BlockSource& source)
: Vec3i(source.getBlockX(), source.getBlockY(), source.getBlockZ()) {}
// Metodi di confronto
bool BlockPos::equals(const BlockPos& other) const {
return x == other.x && y == other.y && z == other.z;
}
bool BlockPos::equals(int x, int y, int z) const {
return this->x == x && this->y == y && this->z == z;
}
int BlockPos::hashCode() const {
int result = 0x1F * (y + 0x1F * z);
return result + x;
}
// Offset
BlockPos BlockPos::offset(int dx, int dy, int dz) const {
return BlockPos(x + dx, y + dy, z + dz);
}
BlockPos BlockPos::offset(double dx, double dy, double dz) const {
return BlockPos(x + dx, y + dy, z + dz);
}
BlockPos BlockPos::offset(const BlockPos& delta) const {
return BlockPos(x + delta.x, y + delta.y, z + delta.z);
}
BlockPos BlockPos::relative(int direction, int distance) const {
int dx = 0, dz = 0;
switch (direction) {
case Direction::NORTH: dz = -distance; break;
case Direction::SOUTH: dz = distance; break;
case Direction::WEST: dx = -distance; break;
case Direction::EAST: dx = distance; break;
default: break;
}
return BlockPos(x + dx, y, z + dz);
}
// Metodi direzionali
BlockPos BlockPos::above(int distance) const {
return BlockPos(x, y + distance, z);
}
BlockPos BlockPos::below(int distance) const {
return BlockPos(x, y - distance, z);
}
BlockPos BlockPos::north(int distance) const {
return relative(Direction::NORTH, distance);
}
BlockPos BlockPos::south(int distance) const {
return relative(Direction::SOUTH, distance);
}
BlockPos BlockPos::east(int distance) const {
return relative(Direction::EAST, distance);
}
BlockPos BlockPos::west(int distance) const {
return relative(Direction::WEST, distance);
}
BlockPos BlockPos::multiply(int factor) const {
if (factor == 0) return ZERO;
if (factor == 1) return *this;
return BlockPos(x * factor, y * factor, z * factor);
}
// Compressione
int BlockPos::compress() const {
static const int MASK_X = (1 << BITS_X) - 1;
static const int MASK_Y = (1 << BITS_Y) - 1;
static const int MASK_Z = (1 << BITS_Z) - 1;
static const int SHIFT_Z = 0;
static const int SHIFT_Y = BITS_Z;
static const int SHIFT_X = BITS_Z + BITS_Y;
int cx = x & MASK_X;
int cy = y & MASK_Y;
int cz = z & MASK_Z;
return (cx << SHIFT_X) | (cy << SHIFT_Y) | (cz << SHIFT_Z);
}
BlockPos BlockPos::decompress(int compressed) {
static const int MASK_X = (1 << BITS_X) - 1;
static const int MASK_Y = (1 << BITS_Y) - 1;
static const int MASK_Z = (1 << BITS_Z) - 1;
static const int SHIFT_Z = 0;
static const int SHIFT_Y = BITS_Z;
static const int SHIFT_X = BITS_Z + BITS_Y;
int x = (compressed >> SHIFT_X) & MASK_X;
int y = (compressed >> SHIFT_Y) & MASK_Y;
int z = (compressed >> SHIFT_Z) & MASK_Z;
if (x & (1 << (BITS_X - 1))) x |= ~MASK_X;
if (y & (1 << (BITS_Y - 1))) y |= ~MASK_Y;
if (z & (1 << (BITS_Z - 1))) z |= ~MASK_Z;
return BlockPos(x, y, z);
}
BlockPos BlockPos::operator+(const BlockPos& other) const {
return BlockPos(x + other.x, y + other.y, z + other.z);
}
BlockPos BlockPos::operator-(const BlockPos& other) const {
return BlockPos(x - other.x, y - other.y, z - other.z);
}
BlockPos BlockPos::operator*(int scalar) const {
return multiply(scalar);
}
BlockPos& BlockPos::operator+=(const BlockPos& other) {
x += other.x;
y += other.y;
z += other.z;
return *this;
}
BlockPos& BlockPos::operator-=(const BlockPos& other) {
x -= other.x;
y -= other.y;
z -= other.z;
return *this;
}
std::string BlockPos::toString() const {
std::ostringstream oss;
oss << "(" << x << ", " << y << ", " << z << ")";
return oss.str();
}

View file

@ -0,0 +1,65 @@
#pragma once
#include "Vec3i.h"
#include <memory>
#include <string>
class Entity;
class BlockSource;
class BlockPos : public Vec3i {
public:
BlockPos();
BlockPos(int x, int y, int z);
BlockPos(double x, double y, double z);
explicit BlockPos(const std::shared_ptr<Entity>& entity);
explicit BlockPos(const double* pos);
BlockPos(const double* pos, bool fromEntity);
explicit BlockPos(const Vec3i& other);
explicit BlockPos(int compressed);
explicit BlockPos(BlockSource& source);
int getX() const { return x; }
int getY() const { return y; }
int getZ() const { return z; }
void set(int x, int y, int z) { this->x = x; this->y = y; this->z = z; }
void set(const BlockPos& other) { x = other.x; y = other.y; z = other.z; }
bool equals(const BlockPos& other) const;
bool equals(int x, int y, int z) const;
bool operator==(const BlockPos& other) const { return equals(other); }
bool operator!=(const BlockPos& other) const { return !equals(other); }
int hashCode() const;
BlockPos offset(int dx, int dy, int dz) const;
BlockPos offset(double dx, double dy, double dz) const;
BlockPos offset(const BlockPos& delta) const;
BlockPos relative(int direction, int distance = 1) const;
BlockPos above(int distance = 1) const;
BlockPos below(int distance = 1) const;
BlockPos north(int distance = 1) const;
BlockPos south(int distance = 1) const;
BlockPos east(int distance = 1) const;
BlockPos west(int distance = 1) const;
BlockPos multiply(int factor) const;
int compress() const;
static BlockPos decompress(int compressed);
BlockPos operator+(const BlockPos& other) const;
BlockPos operator-(const BlockPos& other) const;
BlockPos operator*(int scalar) const;
BlockPos& operator+=(const BlockPos& other);
BlockPos& operator-=(const BlockPos& other);
bool isZero() const { return x == 0 && y == 0 && z == 0; }
std::string toString() const;
static const BlockPos ZERO;
static const int BITS_X = 26;
static const int BITS_Y = 12;
static const int BITS_Z = 26;
};

View file

@ -0,0 +1,105 @@
#include "stdafx.h"
#include "ChunkPrimer.h"
#include "Tile.h" // for Tile::air (or your air tile)
ChunkPrimer::ChunkPrimer()
{
m_blockIds = new byte[65536];
m_blockData = new byte[32768];
memset(m_blockIds, 0, 65536);
memset(m_blockData, 0, 32768);
m_airBlockId = 0; // adjust if your air tile has a different ID
}
ChunkPrimer::~ChunkPrimer()
{
delete[] m_blockIds;
delete[] m_blockData;
}
int ChunkPrimer::getIndex(int x, int y, int z)
{
// Match the indexing used in the decompiled code: (x << 12) | (z << 8) | y
return (x << 12) | (z << 8) | y;
}
void ChunkPrimer::setBlockAndData(int packedPos, int blockId, int data)
{
if (packedPos < 0 || packedPos >= 65536)
{
// Handle error (log, assert, etc.)
return;
}
m_blockIds[packedPos] = static_cast<byte>(blockId);
int byteIdx = packedPos >> 1;
if (packedPos & 1)
m_blockData[byteIdx] = (m_blockData[byteIdx] & 0x0F) | ((data & 0x0F) << 4);
else
m_blockData[byteIdx] = (m_blockData[byteIdx] & 0xF0) | (data & 0x0F);
}
int ChunkPrimer::getState(int packedPos) const
{
if (packedPos < 0 || packedPos >= 65536)
return 0; // air
int id = m_blockIds[packedPos];
int byteIdx = packedPos >> 1;
int data;
if (packedPos & 1)
data = (m_blockData[byteIdx] >> 4) & 0x0F;
else
data = m_blockData[byteIdx] & 0x0F;
// Return a packed state (can be used in place of BlockState* for material checks)
return (id << 4) | data;
}
int ChunkPrimer::getBlockId(int packedPos) const
{
if (packedPos < 0 || packedPos >= 65536)
return 0;
return m_blockIds[packedPos];
}
int ChunkPrimer::getBlockData(int packedPos) const
{
if (packedPos < 0 || packedPos >= 65536)
return 0;
int byteIdx = packedPos >> 1;
if (packedPos & 1)
return (m_blockData[byteIdx] >> 4) & 0x0F;
else
return m_blockData[byteIdx] & 0x0F;
}
int ChunkPrimer::getHighestNonAirPos(int x, int z) const
{
// We iterate from top (y=127) down to 0, checking the block ID.
// The decompiled code uses: (x << 11) | (z << 7) | 1 + y + 126?
// In the decompiled version, they had:
// base = (x << 11) | (z << 7) | 1;
// for (int y = 127; y >= 0; y--)
// if (Block::byId(m_blockIds[base + y + 126]) != Blocks::AIR)
// return y;
// We'll use the same indexing: linear index = (x << 12) | (z << 8) | y.
// To find the topmost nonair block for given x,z, we need to check all y.
// We can compute the base offset for this column: (x << 12) | (z << 8)
int base = (x << 12) | (z << 8);
for (int y = 127; y >= 0; --y)
{
int idx = base | y;
if (m_blockIds[idx] != m_airBlockId)
return y;
}
return 0;
}
void ChunkPrimer::setBlockAndData(int x, int y, int z, int blockId, int data)
{
setBlockAndData(getIndex(x, y, z), blockId, data);
}
int ChunkPrimer::getState(int x, int y, int z) const
{
return getState(getIndex(x, y, z));
}

View file

@ -0,0 +1,42 @@
#pragma once
#include "stdafx.h"
class ChunkPrimer
{
public:
ChunkPrimer();
~ChunkPrimer();
void setBlockAndData(int packedPos, int blockId, int data);
int getState(int packedPos) const;
int getBlockId(int packedPos) const;
int getBlockData(int packedPos) const;
int getHighestNonAirPos(int x, int z) const;
byte* getBlockIds() const { return m_blockIds; }
byte* getBlockData() const { return m_blockData; }
void setBlockAndData(int x, int y, int z, int blockId, int data);
int getState(int x, int y, int z) const;
private:
static int getIndex(int x, int y, int z);
byte* m_blockIds;
byte* m_blockData;
int m_airBlockId;
};

View file

@ -1,189 +0,0 @@
#include "stdafx.h"
#include "DarkOakFeature.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.tile.h"
#include "TreeTile2.h"
#include "LeafTile2.h"
#include <cmath>
#include <algorithm>
DarkOakFeature::DarkOakFeature(bool doUpdate) : Feature(doUpdate) {
}
bool DarkOakFeature::place(Level *level, Random *rand, int x, int y, int z) {
int treeHeight = rand->nextInt(3) + rand->nextInt(2) + 6;
int startX = x;
int startY = y;
int startZ = z;
if (startY >= 1 && startY + treeHeight + 1 < Level::maxBuildHeight) {
int belowTile = level->getTile(startX, startY - 1, startZ);
bool isSoil = (belowTile == Tile::grass_Id || belowTile == Tile::dirt_Id);
if (!(isSoil && startY < Level::maxBuildHeight - treeHeight - 1)) {
return false;
} else if (!this->checkSpace(level, startX, startY, startZ, treeHeight)) {
return false;
} else {
if(app.getLevelGenerationOptions() != nullptr)
{
LevelGenerationOptions *levelGenOptions = app.getLevelGenerationOptions();
int radius = 4;
bool intersects = levelGenOptions->checkIntersects(x - radius, y - 1, z - radius, x + radius + 1, y + treeHeight, z + radius + 1);
if(intersects)
{
return false;
}
}
placeBlock(level, startX, startY - 1, startZ, Tile::dirt_Id);
placeBlock(level, startX + 1, startY - 1, startZ, Tile::dirt_Id);
placeBlock(level, startX, startY - 1, startZ + 1, Tile::dirt_Id);
placeBlock(level, startX + 1, startY - 1, startZ + 1, Tile::dirt_Id);
int face = rand->nextInt(4); // Direzione: 0=N, 1=E, 2=S, 3=W
int dx = 0;
int dz = 0;
if (face == 0) dz = -1;
else if (face == 1) dx = 1;
else if (face == 2) dz = 1;
else if (face == 3) dx = -1;
int bendHeight = treeHeight - rand->nextInt(4);
int bendLength = 2 - rand->nextInt(3);
int trunkX = startX;
int trunkZ = startZ;
int topY = startY + treeHeight - 1;
for (int j2 = 0; j2 < treeHeight; ++j2) {
if (j2 >= bendHeight && bendLength > 0) {
trunkX += dx;
trunkZ += dz;
--bendLength;
}
int currentY = startY + j2;
this->placeLog(level, trunkX, currentY, trunkZ);
this->placeLog(level, trunkX + 1, currentY, trunkZ);
this->placeLog(level, trunkX, currentY, trunkZ + 1);
this->placeLog(level, trunkX + 1, currentY, trunkZ + 1);
}
for (int i3 = -2; i3 <= 0; ++i3) {
for (int l3 = -2; l3 <= 0; ++l3) {
int k4 = -1;
this->placeLeaf(level, trunkX + i3, topY + k4, trunkZ + l3);
this->placeLeaf(level, 1 + trunkX - i3, topY + k4, trunkZ + l3);
this->placeLeaf(level, trunkX + i3, topY + k4, 1 + trunkZ - l3);
this->placeLeaf(level, 1 + trunkX - i3, topY + k4, 1 + trunkZ - l3);
if ((i3 > -2 || l3 > -1) && (i3 != -1 || l3 != -2)) {
k4 = 1;
this->placeLeaf(level, trunkX + i3, topY + k4, trunkZ + l3);
this->placeLeaf(level, 1 + trunkX - i3, topY + k4, trunkZ + l3);
this->placeLeaf(level, trunkX + i3, topY + k4, 1 + trunkZ - l3);
this->placeLeaf(level, 1 + trunkX - i3, topY + k4, 1 + trunkZ - l3);
}
}
}
if (rand->nextInt(2) == 0) {
this->placeLeaf(level, trunkX, topY + 2, trunkZ);
this->placeLeaf(level, trunkX + 1, topY + 2, trunkZ);
this->placeLeaf(level, trunkX + 1, topY + 2, trunkZ + 1);
this->placeLeaf(level, trunkX, topY + 2, trunkZ + 1);
}
for (int j3 = -3; j3 <= 4; ++j3) {
for (int i4 = -3; i4 <= 4; ++i4) {
if ((j3 != -3 || i4 != -3) && (j3 != -3 || i4 != 4) && (j3 != 4 || i4 != -3) && (j3 != 4 || i4 != 4) && (std::abs(j3) < 3 || std::abs(i4) < 3)) {
this->placeLeaf(level, trunkX + j3, topY, trunkZ + i4);
}
}
}
for (int k3 = -1; k3 <= 2; ++k3) {
for (int j4 = -1; j4 <= 2; ++j4) {
if ((k3 < 0 || k3 > 1 || j4 < 0 || j4 > 1) && rand->nextInt(3) <= 0) {
int l4 = rand->nextInt(3) + 2;
for (int i5 = 0; i5 < l4; ++i5) {
this->placeLog(level, startX + k3, topY - i5 - 1, startZ + j4);
}
for (int j5 = -1; j5 <= 1; ++j5) {
for (int l2 = -1; l2 <= 1; ++l2) {
this->placeLeaf(level, trunkX + k3 + j5, topY, trunkZ + j4 + l2);
}
}
for (int k5 = -2; k5 <= 2; ++k5) {
for (int l5 = -2; l5 <= 2; ++l5) {
if (std::abs(k5) != 2 || std::abs(l5) != 2) {
this->placeLeaf(level, trunkX + k3 + k5, topY - 1, trunkZ + j4 + l5);
}
}
}
}
}
}
return true;
}
}
return false;
}
bool DarkOakFeature::checkSpace(Level *worldIn, int x, int y, int z, int height) {
for (int l = 0; l <= height + 1; ++l) {
int i1 = 1;
if (l == 0) i1 = 0;
if (l >= height - 1) i1 = 2;
for (int j1 = -i1; j1 <= i1; ++j1) {
for (int k1 = -i1; k1 <= i1; ++k1) {
if (l == 0 && j1 == 0 && k1 == 0) continue;
int tile = worldIn->getTile(x + j1, y + l, z + k1);
if (tile != 0 &&
tile != Tile::leaves_Id && tile != Tile::leaves2_Id &&
tile != Tile::tallgrass_Id && tile != Tile::sapling_Id &&
tile != Tile::grass_Id && tile != Tile::dirt_Id &&
tile != Tile::treeTrunk_Id && tile != Tile::tree2Trunk_Id) {
return false;
}
if (tile == Tile::water_Id) return false;
}
}
}
return true;
}
void DarkOakFeature::placeLog(Level *worldIn, int x, int y, int z) {
int tile = worldIn->getTile(x, y, z);
if (tile == 0 || tile == Tile::leaves_Id || tile == Tile::leaves2_Id || tile == Tile::tallgrass_Id) {
placeBlock(worldIn, x, y, z, Tile::tree2Trunk_Id, TreeTile2::DARK_TRUNK);
}
}
void DarkOakFeature::placeLeaf(Level *worldIn, int x, int y, int z) {
int tile = worldIn->getTile(x, y, z);
if (tile == 0) {
placeBlock(worldIn, x, y, z, Tile::leaves2_Id, 1);
}
}

View file

@ -34,4 +34,24 @@ public:
static int getDirection(double xd, double zd);
static int getDirection(int x0, int z0, int x1, int z1);
static int getStepX(int direction) {
switch (direction) {
case WEST: return -1;
case EAST: return 1;
default: return 0;
}
}
static int getStepZ(int direction) {
switch (direction) {
case NORTH: return -1;
case SOUTH: return 1;
default: return 0;
}
}
static int getStepY(int direction) {
return 0;
}
};

View file

@ -0,0 +1,43 @@
#include "stdafx.h"
#include "DoublePlantFeature.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.tile.h"
#include "TallGrass2.h"
DoublePlantFeature::DoublePlantFeature(bool doUpdate)
: Feature(doUpdate), m_plantType(0)
{
}
void DoublePlantFeature::setPlantType(int plantType)
{
m_plantType = plantType;
}
bool DoublePlantFeature::place(Level* level, Random* rand, int x, int y, int z)
{
bool placed = false;
for (int i = 0; i < 64; ++i)
{
int bx = x + rand->nextInt(8) - rand->nextInt(8);
int by = y + rand->nextInt(4) - rand->nextInt(4);
int bz = z + rand->nextInt(8) - rand->nextInt(8);
if (by >= Level::maxBuildHeight - 1) continue;
if (by < 1) continue;
if (level->getTile(bx, by, bz) != 0) continue;
if (level->getTile(bx, by + 1, bz) != 0) continue;
if (!static_cast<TallGrass2*>(Tile::tiles[Tile::tallgrass2_Id])->mayPlace(level, bx, by, bz)) continue;
level->setTileAndData(bx, by, bz, Tile::tallgrass2_Id, m_plantType, Tile::UPDATE_ALL);
level->setTileAndData(bx, by + 1, bz, Tile::tallgrass2_Id, m_plantType | TallGrass2::UPPER_BIT, Tile::UPDATE_ALL);
placed = true;
}
return placed;
}

View file

@ -0,0 +1,16 @@
#pragma once
#include "Feature.h"
class Level;
class Random;
class DoublePlantFeature : public Feature
{
private:
int m_plantType;
public:
DoublePlantFeature(bool doUpdate = false);
void setPlantType(int plantType);
bool place(Level* level, Random* rand, int x, int y, int z);
};

View file

@ -1,85 +1,298 @@
#include "stdafx.h"
#include "ForestBiome.h"
#include "net.minecraft.world.level.levelgen.feature.h"
#include "net.minecraft.world.level.biome.h"
#include "DarkOakFeature.h"
#include "BiomeDecorator.h"
#include "TreeFeature.h"
#include "BirchFeature.h"
#include "FlowerFeature.h"
#include "RoofTreeFeature.h"
#include "Tile.h"
#include "Rose.h"
#include "HugeMushroomFeature.h"
#include "DoublePlantFeature.h"
#include "../Minecraft.Client/Minecraft.h"
#include "../Minecraft.Client/Common/Colours/ColourTable.h"
#include "Level.h"
#include "Random.h"
#include "BlockPos.h"
#include "PerlinNoise.h"
ForestBiome::ForestBiome(int id, int type) : Biome(id)
static const int LEAF_COLOR_NORMAL = 0x4EBA31;
static const int LEAF_COLOR_MUTATED = 0x7DA225;
static const int WATER_COLOR_NORMAL = 0x307444;
static const int SKY_COLOR_NORMAL = 0x56621;
static const int SKY_COLOR_BIRCH_ALT = 0x23310;
static const float TEMP_NORMAL = 0.7f;
static const float DOWNFALL_NORMAL = 0.8f;
static const float TEMP_BIRCH = 0.6f;
static const float DOWNFALL_BIRCH = 0.6f;
ForestBiome::ForestBiome(int id, int type)
: Biome(id), biomeType(type)
{
this->biomeType = type;
this->setLeafColor(0x4EBA31);
this->setTemperatureAndDownfall(0.7f, 0.8f);
setLeafColor((eMinecraftColour)LEAF_COLOR_NORMAL);
setTemperatureAndDownfall(TEMP_NORMAL, DOWNFALL_NORMAL);
if (this->biomeType == 1) //flowerforest
if (type == 1) // flower forest
{
this->decorator->treeCount = 10;
this->decorator->grassCount = 2;
this->decorator->flowerCount = 100;
this->decorator->alliumCount = 2;
this->decorator->azureBluetCount = 2;
this->decorator->oxeyeDaisyCount = 2;
this->decorator->blueOrchidCount = 0;
this->setTemperatureAndDownfall(0.6f, 0.6f);
decorator->treeCount = 6;
decorator->grassCount = 1;
decorator->flowerCount = 100;
friendlies.push_back(new MobSpawnerData(eTYPE_RABBIT, 4, 2, 3));
}
else if (this->biomeType == 2) //birchforest
else
{
this->decorator->treeCount = 10;
this->decorator->grassCount = 2;
}
else if (this->biomeType == 3) //roofedforest
{
this->decorator->treeCount = 50;
this->decorator->grassCount = 2;
this->decorator->flowerCount = 1;
this->decorator->hugeMushrooms = 2;
}
else
{
this->decorator->treeCount = 6;
this->decorator->flowerCount = 4;
this->decorator->grassCount = 1;
MobSpawnerData* wolfSpawn = new MobSpawnerData(eTYPE_WOLF, 5, 4, 4);
this->friendlies.push_back(wolfSpawn);
decorator->grassCount = 2;
decorator->treeCount = 10;
}
if (this->biomeType == 0)
if (type == 2) // birch forest
{
MobSpawnerData* rabbitSpawn = new MobSpawnerData(eTYPE_RABBIT, 4, 2, 3);
this->friendlies.push_back(rabbitSpawn);
m_waterColor = (eMinecraftColour)WATER_COLOR_NORMAL;
m_skyColor = (eMinecraftColour)SKY_COLOR_NORMAL;
setTemperatureAndDownfall(TEMP_BIRCH, DOWNFALL_BIRCH);
}
else if (type == 0) // normale
{
enemies.push_back(new MobSpawnerData(eTYPE_WOLF, 5, 4, 4));
}
else if (type == 3) // roofed forest
{
decorator->hugeMushrooms = 2;
}
}
ForestBiome::~ForestBiome() {}
Feature* ForestBiome::getTreeFeature(Random* random)
{
if (this->biomeType == 3) // Roofed Forest
if (biomeType == 3)
{
if (random->nextInt(3) > 0)
return new RoofTreeFeature(false);
}
if (biomeType == 2 || random->nextInt(5) == 0)
return new BirchFeature(false, false);
return new TreeFeature(false);
}
Biome* ForestBiome::setColor(int color, bool b)
{
if (biomeType != 2)
return Biome::setColor(color, b);
m_waterColor = (eMinecraftColour)color;
m_skyColor = (eMinecraftColour)(b ? SKY_COLOR_BIRCH_ALT : SKY_COLOR_NORMAL);
return this;
}
int ForestBiome::getRandomFlower(Random* rand, const BlockPos& pos) const
{
if (biomeType == 1)
{
double noise = m_temperatureNoise->getValue(pos.getX() / 48.0, pos.getZ() / 48.0);
double t = (noise + 1.0) * 0.5;
if (t < 0.0) t = 0.0;
if (t > 0.9999) t = 0.9999;
int idx = (int)(t * 10.0);
static const int FLOWER_COLORS[10] = { 0,1,2,3,4,5,6,7,8,9 };
int color = FLOWER_COLORS[idx];
return color;
}
return 0;
}
void ForestBiome::decorate(Level* level, Random* rand, int xo, int zo)
{
BlockPos pos(xo, 0, zo);
if (biomeType == 3)
{
for (int i = 0; i < 4; ++i)
{
return new DarkOakFeature(false);
int baseX = 9 + i * 4;
int y = 13;
for (int j = 0; j < 2; ++j)
{
int dx = baseX + rand->nextInt(3);
int dz = y - 4 + rand->nextInt(3);
BlockPos treePos = pos.offset(dx, 0, dz);
int highestY = level->getHeightmap(treePos.getX(), treePos.getZ());
treePos = BlockPos(treePos.getX(), highestY, treePos.getZ());
if (rand->nextInt(20) == 0)
{
HugeMushroomFeature mushroom;
mushroom.place(level, rand, treePos.getX(), treePos.getY(), treePos.getZ());
}
else
{
Feature* tree = getTreeFeature(rand);
if (tree)
{
tree->place(level, rand, treePos.getX(), treePos.getY(), treePos.getZ());
delete tree;
}
}
dx = baseX + rand->nextInt(3);
dz = y + rand->nextInt(3);
treePos = pos.offset(dx, 0, dz);
highestY = level->getHeightmap(treePos.getX(), treePos.getZ());
treePos = BlockPos(treePos.getX(), highestY, treePos.getZ());
if (rand->nextInt(20) == 0)
{
HugeMushroomFeature mushroom;
mushroom.place(level, rand, treePos.getX(), treePos.getY(), treePos.getZ());
}
else
{
Feature* tree = getTreeFeature(rand);
if (tree)
{
tree->place(level, rand, treePos.getX(), treePos.getY(), treePos.getZ());
delete tree;
}
}
y += 8;
}
}
}
int count = rand->nextInt(5) - 3;
if (biomeType == 1) count += 2;
if (count > 0)
{
do
{
int plantType = rand->nextInt(3);
DoublePlantFeature plantFeature;
for (int attempts = 2; attempts >= 0; --attempts)
{
int dx = rand->nextInt(16) + 8;
int dz = rand->nextInt(16) + 8;
BlockPos plantPos = pos.offset(dx, 0, dz);
int highestY = level->getHeightmap(plantPos.getX(), plantPos.getZ());
plantPos = BlockPos(plantPos.getX(), highestY, plantPos.getZ());
int plantY = rand->nextInt(plantPos.getY() + 32);
BlockPos finalPos(plantPos.getX(), plantY, plantPos.getZ());
if (plantFeature.place(level, rand, finalPos.getX(), finalPos.getY(), finalPos.getZ()))
{
break;
}
}
--count;
} while (count > 0);
}
Biome::decorate(level, rand, xo, zo);
}
unsigned int ForestBiome::getGrassColor(const BlockPos& pos) const
{
unsigned int base = Biome::getGrassColor();
if (biomeType == 3)
{
ColourTable* table = Minecraft::GetInstance()->getColourTable();
if (table)
{
unsigned int color2 = table->getColour(eMinecraftColour_Grass_Forest);
return ((base & 0xFEFEFE) + (color2 & 0xFEFEFE)) >> 1;
}
}
return base;
}
Biome* ForestBiome::createMutatedCopy(int id) const
{
ForestBiome* copy = new ForestBiome(id, 1);
copy->setDepthAndScale(depth, scale + 0.2f);
copy->setName(L"Forest Mutated");
if (this->biomeType == 2 || random->nextInt(5) == 0)
{
return new BirchFeature(false, false);
}
return new TreeFeature(false);
copy->setLeafColor((eMinecraftColour)LEAF_COLOR_MUTATED);
return copy;
}
Biome* ForestBiome::setColor(int color, bool b)
// MutatedBirchForestBiome
ForestBiome::MutatedBirchForestBiome::MutatedBirchForestBiome(int id, Biome* baseBiome)
: MutatedBiome(id, baseBiome) {}
ForestBiome::MutatedBirchForestBiome::~MutatedBirchForestBiome() {}
Feature* ForestBiome::MutatedBirchForestBiome::getTreeFeature(Random* random)
{
Biome::setColor(color, b);
if (random->nextBoolean())
return new BirchFeature(false, true);
else
return new BirchFeature(false, false);
}
// MutatedForestBiome
ForestBiome::MutatedForestBiome::MutatedForestBiome(int id, Biome* baseBiome)
: MutatedBiome(id, baseBiome) {}
ForestBiome::MutatedForestBiome::~MutatedForestBiome() {}
void ForestBiome::MutatedForestBiome::decorate(Level* level, Random* rand, int xo, int zo)
{
if (m_baseBiome)
m_baseBiome->decorate(level, rand, xo, zo);
}
Feature* ForestBiome::getFlowerFeature(Random* random, int x, int y, int z)
{
if (biomeType == 1) // Flower Forest
{
int fType = random->nextInt(9);
switch (fType) {
case 0: return new FlowerFeature(Tile::flower_Id, 0);
case 1: return new FlowerFeature(Tile::rose_Id, 0);
case 2: return new FlowerFeature(Tile::rose_Id, Rose::ALLIUM);
case 3: return new FlowerFeature(Tile::rose_Id, Rose::AZURE_BLUET);
case 4: return new FlowerFeature(Tile::rose_Id, Rose::RED_TULIP);
case 5: return new FlowerFeature(Tile::rose_Id, Rose::ORANGE_TULIP);
case 6: return new FlowerFeature(Tile::rose_Id, Rose::WHITE_TULIP);
case 7: return new FlowerFeature(Tile::rose_Id, Rose::PINK_TULIP);
case 8: return new FlowerFeature(Tile::rose_Id, Rose::OXEYE_DAISY);
}
}
else if (biomeType == 2 || biomeType == 3)
{
return nullptr;
}
return Biome::getFlowerFeature(random, x, y, z);
}
int ForestBiome::getRandomDoublePlantType(Random* random)
{
if (biomeType == 1 || biomeType == 2 || biomeType == 3)
{
return random->nextInt(3) + 2;
}
return this;
return Biome::getRandomDoublePlantType(random);
}

View file

@ -1,16 +1,46 @@
#pragma once
#include "Biome.h"
#include "MutatedBiome.h"
#include "BlockPos.h"
class ForestBiome : public Biome
{
public:
ForestBiome(int id, int type = 0);
virtual ~ForestBiome();
virtual Feature* getTreeFeature(Random* random) override;
virtual Biome* setColor(int color, bool b = false) override;
virtual int getRandomFlower(Random* rand, const BlockPos& pos) const;
virtual void decorate(Level* level, Random* rand, int xo, int zo) override;
virtual unsigned int getGrassColor(const BlockPos& pos) const;
virtual Feature* getFlowerFeature(Random* random, int x, int y, int z) override;
virtual int getRandomDoublePlantType(Random* random) override;
virtual Biome* createMutatedCopy(int id) const;
class MutatedBirchForestBiome : public MutatedBiome
{
public:
MutatedBirchForestBiome(int id, Biome* baseBiome);
virtual ~MutatedBirchForestBiome();
virtual Feature* getTreeFeature(Random* random) override;
};
class MutatedForestBiome : public MutatedBiome
{
public:
// Rimosso 'const'
MutatedForestBiome(int id, Biome* baseBiome);
virtual ~MutatedForestBiome();
virtual void decorate(Level* level, Random* rand, int xo, int zo) override;
};
private:
int biomeType;
public:
ForestBiome(int id, int type = 0);
virtual Feature *getTreeFeature(Random *random) override;
virtual Biome *setColor(int color, bool b = false) override;
};

View file

@ -2449,6 +2449,7 @@
<ClInclude Include="Blaze.h" />
<ClInclude Include="BlockDestructionProgress.h" />
<ClInclude Include="BlockGenMethods.h" />
<ClInclude Include="BlockPos.h" />
<ClInclude Include="BlockRegionUpdatePacket.h" />
<ClInclude Include="BlockReplacements.h" />
<ClInclude Include="BlockSource.h" />
@ -2461,12 +2462,15 @@
<ClInclude Include="BookshelfTile.h" />
<ClInclude Include="BossMob.h" />
<ClInclude Include="Calendar.h" />
<ClInclude Include="ChunkPrimer.h" />
<ClInclude Include="ColoredTile.h" />
<ClInclude Include="CommandBlock.h" />
<ClInclude Include="CommandBlockEntity.h" />
<ClInclude Include="ComparatorTile.h" />
<ClInclude Include="ComparatorTileEntity.h" />
<ClInclude Include="DarkOakFeature.h" />
<ClInclude Include="DoublePlantFeature.h" />
<ClInclude Include="MutatedBiome.h" />
<ClInclude Include="RoofTreeFeature.h" />
<ClInclude Include="DaylightDetectorTile.h" />
<ClInclude Include="DaylightDetectorTileEntity.h" />
<ClInclude Include="DropperTile.h" />
@ -2718,7 +2722,6 @@
<ClInclude Include="RedSandStoneTile.h" />
<ClInclude Include="Redstone.h" />
<ClInclude Include="RepeaterTile.h" />
<ClInclude Include="RoofedForestBiome.h" />
<ClInclude Include="RotatedPillarTile.h" />
<ClInclude Include="SandTile.h" />
<ClInclude Include="SavannaBiome.h" />
@ -3540,6 +3543,7 @@
<ClCompile Include="Blaze.cpp" />
<ClCompile Include="BlockDestructionProgress.cpp" />
<ClCompile Include="BlockGenMethods.cpp" />
<ClCompile Include="BlockPos.cpp" />
<ClCompile Include="BlockRegionUpdatePacket.cpp" />
<ClCompile Include="BlockReplacements.cpp" />
<ClCompile Include="BlockSourceImpl.cpp" />
@ -3550,12 +3554,15 @@
<ClCompile Include="BookItem.cpp" />
<ClCompile Include="BookshelfTile.cpp" />
<ClCompile Include="Calendar.cpp" />
<ClCompile Include="ChunkPrimer.cpp" />
<ClCompile Include="ColoredTile.cpp" />
<ClCompile Include="CommandBlock.cpp" />
<ClCompile Include="CommandBlockEntity.cpp" />
<ClCompile Include="ComparatorTile.cpp" />
<ClCompile Include="ComparatorTileEntity.cpp" />
<ClCompile Include="DarkOakFeature.cpp" />
<ClCompile Include="DoublePlantFeature.cpp" />
<ClCompile Include="MutatedBiome.cpp" />
<ClCompile Include="RoofTreeFeature.cpp" />
<ClCompile Include="DaylightDetectorTile.cpp" />
<ClCompile Include="DaylightDetectorTileEntity.cpp" />
<ClCompile Include="DropperTile.cpp" />
@ -3662,7 +3669,6 @@
<ClCompile Include="RedSandStoneTile.cpp" />
<ClCompile Include="Redstone.cpp" />
<ClCompile Include="RepeaterTile.cpp" />
<ClCompile Include="RoofedForestBiome.cpp" />
<ClCompile Include="Rose.cpp" />
<ClInclude Include="Rose.h" />
<ClCompile Include="RotatedPillarTile.cpp" />

View file

@ -822,14 +822,17 @@
<ClCompile Include="LeafTile2.cpp" />
<ClCompile Include="LeafTileItem2.cpp" />
<ClCompile Include="SavannaTreeFeature.cpp" />
<ClCompile Include="DarkOakFeature.cpp" />
<ClCompile Include="RoofTreeFeature.cpp" />
<ClCompile Include="SavannaBiome.cpp" />
<ClCompile Include="RoofedForestBiome.cpp" />
<ClCompile Include="PrismarineTile.cpp" />
<ClCompile Include="FishFoodItem.cpp" />
<ClCompile Include="Tallgrass2.cpp" />
<ClCompile Include="Endermite.cpp" />
<ClCompile Include="Vec3i.cpp" />
<ClCompile Include="BlockPos.cpp" />
<ClCompile Include="MutatedBiome.cpp" />
<ClCompile Include="ChunkPrimer.cpp" />
<ClCompile Include="DoublePlantFeature.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AABB.h" />
@ -1821,14 +1824,17 @@
<ClInclude Include="LeafTile2.h" />
<ClInclude Include="LeafTileItem2.h" />
<ClInclude Include="SavannaTreeFeature.h" />
<ClInclude Include="DarkOakFeature.h" />
<ClInclude Include="RoofTreeFeature.h" />
<ClInclude Include="SavannaBiome.h" />
<ClInclude Include="RoofedForestBiome.h" />
<ClInclude Include="PrismarineTile.h" />
<ClInclude Include="FishFoodItem.h" />
<ClInclude Include="Tallgrass2.h" />
<ClInclude Include="Endermite.h" />
<ClInclude Include="Vec3i.h" />
<ClInclude Include="BlockPos.h" />
<ClInclude Include="MutatedBiome.h" />
<ClInclude Include="ChunkPrimer.h" />
<ClInclude Include="DoublePlantFeature.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\Minecraft.Client\Xbox\res\audio\Minecraft.xgs" />

View file

@ -0,0 +1,84 @@
#include "stdafx.h"
#include "MutatedBiome.h"
#include "BiomeDecorator.h"
#include "Level.h"
#include "Random.h"
#include "ChunkPrimer.h"
MutatedBiome::MutatedBiome(int id, Biome* baseBiome)
: Biome(id), m_baseBiome(baseBiome)
{
if (!baseBiome) return;
color = baseBiome->color;
topMaterial = baseBiome->topMaterial;
material = baseBiome->material;
leafColor = baseBiome->leafColor;
depth = baseBiome->depth + 0.1f;
scale = baseBiome->scale + 0.2f;
temperature = baseBiome->temperature;
downfall = baseBiome->downfall;
friendlies = baseBiome->friendlies;
enemies = baseBiome->enemies;
waterFriendlies = baseBiome->waterFriendlies;
friendlies_chicken = baseBiome->friendlies_chicken;
friendlies_wolf = baseBiome->friendlies_wolf;
friendlies_mushroomcow = baseBiome->friendlies_mushroomcow;
ambientFriendlies = baseBiome->ambientFriendlies;
m_waterColor = baseBiome->m_waterColor;
m_skyColor = baseBiome->m_skyColor;
m_name = baseBiome->m_name + L" Mutated";
// Copia parametri del decorator
if (decorator && baseBiome->decorator) {
decorator->treeCount = baseBiome->decorator->treeCount;
decorator->grassCount = baseBiome->decorator->grassCount;
decorator->flowerCount = baseBiome->decorator->flowerCount;
decorator->hugeMushrooms = baseBiome->decorator->hugeMushrooms;
// ... altri campi se necessari
}
}
MutatedBiome::~MutatedBiome() {}
Feature* MutatedBiome::getTreeFeature(Random* random) {
return m_baseBiome ? m_baseBiome->getTreeFeature(random) : Biome::getTreeFeature(random);
}
void MutatedBiome::decorate(Level* level, Random* rand, int xo, int zo) {
if (m_baseBiome)
m_baseBiome->decorate(level, rand, xo, zo);
else
Biome::decorate(level, rand, xo, zo);
}
int MutatedBiome::getGrassColor() const {
return m_baseBiome ? m_baseBiome->getGrassColor() : Biome::getGrassColor();
}
int MutatedBiome::getFoliageColor() const {
return m_baseBiome ? m_baseBiome->getFoliageColor() : Biome::getFoliageColor();
}
float MutatedBiome::getCreatureProbability() const
{
return m_baseBiome ? m_baseBiome->getCreatureProbability() : Biome::getCreatureProbability();
}
bool MutatedBiome::isSame(const Biome* other) const {
return m_baseBiome ? m_baseBiome->isSame(other) : Biome::isSame(other);
}
int MutatedBiome::getTemperatureCategory() const {
return m_baseBiome ? m_baseBiome->getTemperatureCategory() : Biome::getTemperatureCategory();
}
void MutatedBiome::buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal) {
if (m_baseBiome)
m_baseBiome->buildSurfaceAt(level, random, primer, x, z, noiseVal);
else
Biome::buildSurfaceAt(level, random, primer, x, z, noiseVal);
}

View file

@ -0,0 +1,24 @@
#pragma once
#include "Biome.h"
class MutatedBiome : public Biome
{
public:
MutatedBiome(int id, Biome* baseBiome);
virtual ~MutatedBiome();
virtual Feature* getTreeFeature(Random* random) override;
virtual void decorate(Level* level, Random* rand, int xo, int zo) override;
virtual int getGrassColor() const override;
virtual int getFoliageColor() const override;
virtual float getCreatureProbability() const override;
virtual bool isSame(const Biome* other) const override;
virtual int getTemperatureCategory() const override;
virtual void buildSurfaceAt(Level* level, Random* random, ChunkPrimer* primer, int x, int z, double noiseVal) override;
Biome* getBaseBiome() const { return m_baseBiome; } // Rimosso const
protected:
Biome* m_baseBiome; // Rimosso const
};

View file

@ -9,4 +9,22 @@ PlainsBiome::PlainsBiome(int id) : Biome(id)
decorator->treeCount = -999;
decorator->flowerCount = 4;
decorator->grassCount = 10;
}
Feature* PlainsBiome::getFlowerFeature(Random* random, int x, int y, int z)
{
int fType = random->nextInt(3);
if (fType == 0) return new FlowerFeature(Tile::rose_Id, Rose::OXEYE_DAISY);
if (fType == 1) return new FlowerFeature(Tile::rose_Id, Rose::AZURE_BLUET);
// Tulipani (qualsiasi colore)
int tulipColor = random->nextInt(4);
switch (tulipColor) {
case 0: return new FlowerFeature(Tile::rose_Id, Rose::RED_TULIP);
case 1: return new FlowerFeature(Tile::rose_Id, Rose::ORANGE_TULIP);
case 2: return new FlowerFeature(Tile::rose_Id, Rose::WHITE_TULIP);
case 3: return new FlowerFeature(Tile::rose_Id, Rose::PINK_TULIP);
}
return Biome::getFlowerFeature(random, x, y, z);
}

View file

@ -7,4 +7,5 @@ class PlainsBiome : public Biome
friend class Biome;
protected:
PlainsBiome(int id);
virtual Feature* getFlowerFeature(Random* random, int x, int y, int z) override;
};

View file

@ -0,0 +1,199 @@
#include "stdafx.h"
#include "RoofTreeFeature.h"
#include "net.minecraft.world.level.h"
#include "net.minecraft.world.level.tile.h"
#include "TreeTile2.h"
#include "LeafTile2.h"
#include <cmath>
#include <algorithm>
RoofTreeFeature::RoofTreeFeature(bool doUpdate) : Feature(doUpdate) {
}
static bool isReplaceable(int tile) {
return tile == 0 ||
tile == Tile::tallgrass_Id ||
tile == Tile::sapling_Id ||
tile == Tile::grass_Id ||
tile == Tile::dirt_Id ||
tile == Tile::leaves_Id ||
tile == Tile::leaves2_Id;
}
bool RoofTreeFeature::checkSpace(Level *worldIn, int x, int y, int z, int height) {
for (int dy = 0; dy <= height + 1; ++dy) {
int radius = 1;
if (dy == 0) radius = 0;
if (dy >= height - 1) radius = 2;
for (int dx = -radius; dx <= radius; ++dx) {
for (int dz = -radius; dz <= radius; ++dz) {
if (dy == 0 && dx == 0 && dz == 0) continue;
int tile = worldIn->getTile(x + dx, y + dy, z + dz);
if (tile != 0 && !isReplaceable(tile)) {
return false;
}
if (tile == Tile::water_Id) {
return false;
}
}
}
}
return true;
}
void RoofTreeFeature::placeLog(Level *worldIn, int x, int y, int z) {
int tile = worldIn->getTile(x, y, z);
if (tile == 0 || tile == Tile::leaves_Id || tile == Tile::leaves2_Id || tile == Tile::tallgrass_Id) {
placeBlock(worldIn, x, y, z, Tile::tree2Trunk_Id, TreeTile2::DARK_TRUNK);
}
}
void RoofTreeFeature::placeLeaf(Level *worldIn, int x, int y, int z) {
int tile = worldIn->getTile(x, y, z);
if (tile == 0) {
placeBlock(worldIn, x, y, z, Tile::leaves2_Id, 1);
}
}
bool RoofTreeFeature::place(Level *level, Random *rand, int x, int y, int z) {
int height = rand->nextInt(3) + 6;
int startX = x, startY = y, startZ = z;
if (startY < 1 || startY + height + 1 >= Level::maxBuildHeight) return false;
if (level->getTile(startX, startY - 1, startZ) != Tile::grass_Id &&
level->getTile(startX, startY - 1, startZ) != Tile::dirt_Id) return false;
if (startY >= Level::maxBuildHeight - height - 1) return false;
if (!checkSpace(level, startX, startY, startZ, height)) return false;
if (app.getLevelGenerationOptions() != nullptr) {
LevelGenerationOptions *options = app.getLevelGenerationOptions();
int radius = 4;
if (options->checkIntersects(x - radius, y - 1, z - radius,
x + radius + 1, y + height, z + radius + 1))
return false;
}
placeBlock(level, startX, startY - 1, startZ, Tile::dirt_Id, 0);
placeBlock(level, startX + 1, startY - 1, startZ, Tile::dirt_Id, 0);
placeBlock(level, startX, startY - 1, startZ + 1, Tile::dirt_Id, 0);
placeBlock(level, startX + 1, startY - 1, startZ + 1, Tile::dirt_Id, 0);
int face = rand->nextInt(4);
int dx = 0, dz = 0;
if (face == 0) dz = -1;
else if (face == 1) dx = 1;
else if (face == 2) dz = 1;
else if (face == 3) dx = -1;
int bendHeight = height - rand->nextInt(2) - 1;
int bendLength = rand->nextInt(2);
int trunkX = startX, trunkZ = startZ;
int topY = startY + height - 1;
for (int dy = 0; dy < height; ++dy) {
if (dy >= bendHeight && bendLength > 0) {
trunkX += dx;
trunkZ += dz;
--bendLength;
}
int currentY = startY + dy;
placeLog(level, trunkX, currentY, trunkZ);
placeLog(level, trunkX + 1, currentY, trunkZ);
placeLog(level, trunkX, currentY, trunkZ + 1);
placeLog(level, trunkX + 1, currentY, trunkZ + 1);
}
for (int i3 = -2; i3 <= 0; ++i3) {
for (int l3 = -2; l3 <= 0; ++l3) {
int yOffset = -1;
placeLeaf(level, trunkX + i3, topY + yOffset, trunkZ + l3);
placeLeaf(level, trunkX + 1 - i3, topY + yOffset, trunkZ + l3);
placeLeaf(level, trunkX + i3, topY + yOffset, trunkZ + 1 - l3);
placeLeaf(level, trunkX + 1 - i3, topY + yOffset, trunkZ + 1 - l3);
if ((i3 > -2 || l3 > -1) && (i3 != -1 || l3 != -2)) {
yOffset = 1;
placeLeaf(level, trunkX + i3, topY + yOffset, trunkZ + l3);
placeLeaf(level, trunkX + 1 - i3, topY + yOffset, trunkZ + l3);
placeLeaf(level, trunkX + i3, topY + yOffset, trunkZ + 1 - l3);
placeLeaf(level, trunkX + 1 - i3, topY + yOffset, trunkZ + 1 - l3);
}
}
}
if (rand->nextInt(2) == 0) {
placeLeaf(level, trunkX, topY + 2, trunkZ);
placeLeaf(level, trunkX + 1, topY + 2, trunkZ);
placeLeaf(level, trunkX + 1, topY + 2, trunkZ + 1);
placeLeaf(level, trunkX, topY + 2, trunkZ + 1);
}
for (int dxOff = -3; dxOff <= 4; ++dxOff) {
for (int dzOff = -3; dzOff <= 4; ++dzOff) {
if ((dxOff == -3 || dxOff == 4) && (dzOff == -3 || dzOff == 4))
continue;
if (std::abs(dxOff) < 3 || std::abs(dzOff) < 3) {
placeLeaf(level, trunkX + dxOff, topY, trunkZ + dzOff);
}
}
}
for (int dxOff = -1; dxOff <= 2; ++dxOff) {
for (int dzOff = -1; dzOff <= 2; ++dzOff) {
if ((dxOff < 0 || dxOff > 1 || dzOff < 0 || dzOff > 1) && rand->nextInt(3) <= 0) {
int branchLength = rand->nextInt(2) + 2;
for (int l = 0; l < branchLength; ++l) {
placeLog(level, startX + dxOff, topY - l - 1, startZ + dzOff);
}
for (int lx = -1; lx <= 1; ++lx) {
for (int lz = -1; lz <= 1; ++lz) {
placeLeaf(level, trunkX + dxOff + lx, topY, trunkZ + dzOff + lz);
}
}
for (int lx = -2; lx <= 2; ++lx) {
for (int lz = -2; lz <= 2; ++lz) {
if (std::abs(lx) != 2 || std::abs(lz) != 2) {
placeLeaf(level, trunkX + dxOff + lx, topY - 1, trunkZ + dzOff + lz);
}
}
}
}
}
}
return true;
}

View file

@ -2,10 +2,10 @@
#pragma once
#include "Feature.h"
class DarkOakFeature : public Feature
class RoofTreeFeature : public Feature
{
public:
DarkOakFeature(bool doUpdate);
RoofTreeFeature(bool doUpdate);
virtual bool place(Level *level, Random *random, int x, int y, int z);
private:

View file

@ -1,64 +0,0 @@
#include "stdafx.h"
#include "RoofedForestBiome.h"
#include "BiomeDecorator.h"
#include "DarkOakFeature.h"
#include "HugeMushroomFeature.h"
#include "TreeFeature.h"
#include "BirchFeature.h"
#include "net.minecraft.world.level.tile.h"
#include "..\Level.h"
RoofedForestBiome::RoofedForestBiome(int id) : Biome(id)
{
decorator->treeCount = 35;
decorator->grassCount = 2;
decorator->flowerCount = 1;
decorator->mushroomCount = 1;
decorator->hugeMushrooms = 1;
temperature = 0.7f;
downfall = 0.8f;
topMaterial = static_cast<byte>(Tile::grass_Id);
material = static_cast<byte>(Tile::dirt_Id);
setColor(0x28340A);
setLeafColor(0x2D5A27);
}
Feature* RoofedForestBiome::getTreeFeature(Random* random)
{
if (random->nextInt(20) == 0)
{
return new HugeMushroomFeature();
}
if (random->nextInt(3) > 0)
{
return new DarkOakFeature(true);
}
{
return new TreeFeature(false);
}
return new BirchFeature(false);
}
int RoofedForestBiome::getGrassColor()
{
return 0x28340A;
}
int RoofedForestBiome::getFolageColor()
{
return 0x2D5A27;
}

View file

@ -1,12 +0,0 @@
#pragma once
#include "Biome.h"
class RoofedForestBiome : public Biome
{
public:
RoofedForestBiome(int id);
virtual Feature* getTreeFeature(Random* random) override;
// virtual void decorate(Level* level, Random* random, int xo, int zo) override;
virtual int getGrassColor() override;
virtual int getFolageColor() override;
};

View file

@ -6,7 +6,7 @@
#include "Sapling.h"
#include "SavannaTreeFeature.h"
#include "DarkOakFeature.h"
#include "RoofTreeFeature.h"
int Sapling::SAPLING_NAMES[SAPLING_NAMES_SIZE] = {
IDS_TILE_SAPLING_OAK,
@ -133,7 +133,7 @@ void Sapling::growTree(Level *level, int x, int y, int z, Random *random)
isSapling(level, x + ox, y, z + oz + 1, TYPE_DARK_OAK) &&
isSapling(level, x + ox + 1, y, z + oz + 1, TYPE_DARK_OAK))
{
f = new DarkOakFeature(true);
f = new RoofTreeFeature(true);
multiblock = true;
break;
}

View file

@ -14,7 +14,8 @@ SavannaBiome::SavannaBiome(int id) : Biome(id)
decorator->treeCount = 1;
decorator->flowerCount = 4;
decorator->grassCount = 20;
decorator->grassCount = 20;
}
Feature *SavannaBiome::getTreeFeature(Random *random)
@ -29,12 +30,24 @@ Feature *SavannaBiome::getTreeFeature(Random *random)
return new TreeFeature(false);
}
int SavannaBiome::getGrassColor()
int SavannaBiome::getGrassColor() const
{
return 0xBFB755;
}
int SavannaBiome::getFolageColor()
int SavannaBiome::getFoliageColor() const
{
return 0xAEA42A;
}
Feature *SavannaBiome::getFlowerFeature(Random *random, int x, int y, int z)
{
return nullptr;
}
int SavannaBiome::getRandomDoublePlantType(Random *random)
{
return 0;
}

View file

@ -7,7 +7,9 @@ public:
SavannaBiome(int id);
virtual Feature *getTreeFeature(Random *random);
virtual int getFolageColor() override;
virtual int getGrassColor() override;
virtual int getFoliageColor() const override;
virtual int getGrassColor() const override;
//virtual int getWaterColor() override;
virtual Feature *getFlowerFeature(Random *random, int x, int y, int z) override;
virtual int getRandomDoublePlantType(Random *random) override;
};

View file

@ -1,5 +1,8 @@
#pragma once
#include "Biome.h"
#include "FlowerFeature.h"
#include "Tile.h"
#include "Rose.h"
class LevelSource;
class SwampBiome : public Biome
@ -11,7 +14,7 @@ public:
public:
virtual Feature *getTreeFeature(Random *random);
virtual Feature* getFlowerFeature(Random* random, int x, int y, int z) override{return new FlowerFeature(Tile::rose_Id, Rose::BLUE_ORCHID);}
// 4J Stu - Not using these any more
//virtual int getGrassColor();
//virtual int getFolageColor();

View file

@ -57,11 +57,11 @@ void Vec3::resetPool()
Vec3 *Vec3::newTemp(double x, double y, double z)
{
ThreadStorage *tls = static_cast<ThreadStorage *>(TlsGetValue(tlsIdx));
Vec3 *thisVec = &tls->pool[tls->poolPointer];
thisVec->set(x, y, z);
tls->poolPointer = ( tls->poolPointer + 1 ) % ThreadStorage::POOL_SIZE;
return thisVec;
ThreadStorage *tls = static_cast<ThreadStorage *>(TlsGetValue(tlsIdx));
Vec3 *thisVec = &tls->pool[tls->poolPointer];
thisVec->set(x, y, z);
tls->poolPointer = ( tls->poolPointer + 1 ) % ThreadStorage::POOL_SIZE;
return thisVec;
}
Vec3::Vec3(double x, double y, double z)
@ -213,46 +213,26 @@ Vec3 *Vec3::lerp(Vec3 *v, double a)
return Vec3::newTemp(x + (v->x - x) * a, y + (v->y - y) * a, z + (v->z - z) * a);
}
void Vec3::xRot(float degs)
// Le nuove restituiscono un Vec3*
Vec3* Vec3::xRot(float degs)
{
double _cos = cos((double)degs); // Use double for precision
double _cos = cos((double)degs);
double _sin = sin((double)degs);
double xx = x;
double yy = y * _cos + z * _sin;
double zz = z * _cos - y * _sin;
x = xx;
y = yy;
z = zz;
return Vec3::newTemp(x, y * _cos + z * _sin, z * _cos - y * _sin);
}
void Vec3::yRot(float degs)
Vec3* Vec3::yRot(float degs)
{
double _cos = cos((double)degs);
double _cos = cos((double)degs);
double _sin = sin((double)degs);
double xx = x * _cos + z * _sin;
double yy = y;
double zz = z * _cos - x * _sin;
x = xx;
y = yy;
z = zz;
return Vec3::newTemp(x * _cos + z * _sin, y, z * _cos - x * _sin);
}
void Vec3::zRot(float degs)
Vec3* Vec3::zRot(float degs)
{
double _cos = cos((double)degs);
double _cos = cos((double)degs);
double _sin = sin((double)degs);
double xx = x * _cos + y * _sin;
double yy = y * _cos - x * _sin;
double zz = z;
x = xx;
y = yy;
z = zz;
return Vec3::newTemp(x * _cos + y * _sin, y * _cos - x * _sin, z);
}
double Vec3::distanceTo(AABB *box)
@ -278,7 +258,7 @@ Vec3* Vec3::closestPointOnLine(Vec3* p1, Vec3* p2)
Vec3* diff = newTemp(x-p1->x, y-p1->y, z-p1->z);
Vec3* dir = newTemp(p2->x-p1->x, p2->y-p1->y, p2->z-p1->z);
// Cambiato float in double
double dot1 = diff->dot(dir);
if (dot1 <= 0.0)
return p1;
@ -297,4 +277,48 @@ double Vec3::distanceFromLine(Vec3* p1, Vec3* p2)
Vec3* closestPoint = closestPointOnLine(p1, p2);
Vec3* diff = newTemp(x-closestPoint->x, y-closestPoint->y, z-closestPoint->z);
return diff->length();
}
void Vec3::xRotInPlace(float degs)
{
double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless wasting precision here
double _sin = sin(degs);
double xx = x;
double yy = y * _cos + z * _sin;
double zz = z * _cos - y * _sin;
x = xx;
y = yy;
z = zz;;
}
void Vec3::yRotInPlace(float degs)
{
double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless wasting precision here
double _sin = sin(degs);
double xx = x * _cos + z * _sin;
double yy = y;
double zz = z * _cos - x * _sin;
x = xx;
y = yy;
z = zz;
}
void Vec3::zRotInPlace(float degs)
{
double _cos = cos(degs); // 4J - cos/sin were floats but seems pointless wasting precision here
double _sin = sin(degs);
double xx = x * _cos + y * _sin;
double yy = y * _cos - x * _sin;
double zz = z;
x = xx;
y = yy;
z = zz;
}

View file

@ -61,9 +61,12 @@ public:
Vec3 *lerp(Vec3 *v, double a);
void xRot(float degs);
void yRot(float degs);
void zRot(float degs);
Vec3* xRot(float degs);
Vec3* yRot(float degs);
Vec3* zRot(float degs);
void xRotInPlace(float degs);
void yRotInPlace(float degs);
void zRotInPlace(float degs);
// 4J Added
double distanceTo(AABB *box);

View file

@ -2,29 +2,40 @@
#include "Vec3i.h"
#include <cmath>
Vec3i::Vec3i(int x, int y, int z) : x(x), y(y), z(z)
void Vec3i::cross(Vec3i& result, const Vec3i& a, const Vec3i& b)
{
result.set(
a.getY() * b.getZ() - a.getZ() * b.getY(),
a.getZ() * b.getX() - a.getX() * b.getZ(),
a.getX() * b.getY() - a.getY() * b.getX()
);
}
int Vec3i::getX() const
double Vec3i::dist(int x2, int y2, int z2) const
{
return this->x;
double dx = x - x2;
double dy = y - y2;
double dz = z - z2;
return std::sqrt(dx*dx + dy*dy + dz*dz);
}
int Vec3i::getY() const
double Vec3i::distSqr(double x2, double y2, double z2) const
{
return this->y;
double dx = x - x2;
double dy = y - y2;
double dz = z - z2;
return dx*dx + dy*dy + dz*dz;
}
int Vec3i::getZ() const
double Vec3i::distSqrToCenter(double x2, double y2, double z2) const
{
return this->z;
double dx = (x + 0.5) - x2;
double dy = (y + 0.5) - y2;
double dz = (z + 0.5) - z2;
return dx*dx + dy*dy + dz*dz;
}
double Vec3i::distSqr(const Vec3i& other) const
{
double dx = (double)(this->x - other.getX());
double dy = (double)(this->y - other.getY());
double dz = (double)(this->z - other.getZ());
return dx * dx + dy * dy + dz * dz;
return distSqr(other.getX(), other.getY(), other.getZ());
}

View file

@ -1,20 +1,37 @@
#pragma once
#include <cmath>
#include <string>
class Vec3i
{
protected:
int x;
int y;
int z;
class Vec3i {
protected:
int x, y, z;
public:
Vec3i(int x, int y, int z);
virtual ~Vec3i() = default;
Vec3i() : x(0), y(0), z(0) {}
Vec3i(int x, int y, int z) : x(x), y(y), z(z) {}
Vec3i(double x, double y, double z)
: x((int)std::floor(x)), y((int)std::floor(y)), z((int)std::floor(z)) {}
int getX() const;
int getY() const;
int getZ() const;
int getX() const { return x; }
int getY() const { return y; }
int getZ() const { return z; }
double distSqr(const Vec3i& other) const;
void set(int x, int y, int z) { this->x = x; this->y = y; this->z = z; }
static void cross(Vec3i& result, const Vec3i& a, const Vec3i& b);
double dist(int x2, int y2, int z2) const;
double distSqr(double x2, double y2, double z2) const;
double distSqrToCenter(double x2, double y2, double z2) const;
double distSqr(const Vec3i& other) const;
bool equals(const Vec3i& other) const {
return x == other.x && y == other.y && z == other.z;
}
Vec3i above() const { return Vec3i(x, y + 1, z); }
Vec3i below() const { return Vec3i(x, y - 1, z); }
Vec3i north() const { return Vec3i(x, y, z - 1); }
Vec3i south() const { return Vec3i(x, y, z + 1); }
Vec3i east() const { return Vec3i(x + 1, y, z); }
Vec3i west() const { return Vec3i(x - 1, y, z); }
};

View file

@ -32,5 +32,4 @@
#include "JungleBiome.h"
//TU31
#include "SavannaBiome.h"
#include "RoofedForestBiome.h"
#include "SavannaBiome.h"

View file

@ -22,6 +22,7 @@
#include "SpringFeature.h"
#include "SpruceFeature.h"
#include "TallGrassFeature.h"
#include "DoublePlantFeature.h"
#include "TreeFeature.h"
#include "HugeMushroomFeature.h"
@ -31,9 +32,9 @@
#include "SpikeFeature.h"
#include "EndPodiumFeature.h"
#include "SavannaTreeFeature.h"
#include "DarkOakFeature.h"
#include "RoofTreeFeature.h"
#include "DesertWellFeature.h"
#include "MegaTreeFeature.h"
#include "VinesFeature.h"
#include "GroundBushFeature.h"
#include "GroundBushFeature.h"

View file

@ -138,4 +138,6 @@
#include "LeafTile2.h"
#include "PrismarineTile.h"
#include "PackedIceTile.h"
#include "PackedIceTile.h"
#include "Tallgrass2.h"