TU19: merge Minecraft.World/WorldGen

This commit is contained in:
Tropical 2026-03-21 17:45:10 -05:00
parent eb23fc1a83
commit 0f280b5ed3
108 changed files with 3505 additions and 957 deletions

View file

@ -7,8 +7,8 @@ BeachBiome::BeachBiome(int id) : Biome(id) {
// remove default mob spawn settings // remove default mob spawn settings
friendlies.clear(); friendlies.clear();
friendlies_chicken.clear(); // 4J added friendlies_chicken.clear(); // 4J added
this->topMaterial = (uint8_t)Tile::sand_Id; topMaterial = (uint8_t)Tile::sand_Id;
this->material = (uint8_t)Tile::sand_Id; material = (uint8_t)Tile::sand_Id;
decorator->treeCount = -999; decorator->treeCount = -999;
decorator->deadBushCount = 0; decorator->deadBushCount = 0;

View file

@ -309,9 +309,10 @@ Biome::Biome(int id) : id(id) {
m_waterColor = eMinecraftColour_NOT_SET; m_waterColor = eMinecraftColour_NOT_SET;
/* 4J - removing these so that we can consistently return newly created /* 4J - removing these so that we can consistently return newly created
trees via getTreeFeature, and let the calling function be resposible for trees via getTreeFeature, and let the calling function be resposible for
deleting the returned tree normalTree = new TreeFeature(); fancyTree = new deleting the returned tree normalTree = new TreeFeature(); fancyTree = new
BasicTree(); birchTree = new BirchFeature(); swampTree = new SwampTreeFeature(); BasicTree(); birchTree = new BirchFeature(); swampTree = new
SwampTreeFeature();
*/ */
biomes[id] = this; biomes[id] = this;
@ -333,6 +334,8 @@ BasicTree(); birchTree = new BirchFeature(); swampTree = new SwampTreeFeature();
// wolves are added to forests and taigas // wolves are added to forests and taigas
waterFriendlies.push_back(new MobSpawnerData(eTYPE_SQUID, 10, 4, 4)); waterFriendlies.push_back(new MobSpawnerData(eTYPE_SQUID, 10, 4, 4));
ambientFriendlies.push_back(new MobSpawnerData(eTYPE_BAT, 10, 8, 8));
} }
Biome::~Biome() { Biome::~Biome() {
@ -354,7 +357,7 @@ Biome* Biome::setLeafFoliageWaterSkyColor(eMinecraftColour grassColor,
} }
Biome* Biome::setTemperatureAndDownfall(float temp, float downfall) { Biome* Biome::setTemperatureAndDownfall(float temp, float downfall) {
this->temperature = temp; temperature = temp;
this->downfall = downfall; this->downfall = downfall;
return this; return this;
} }
@ -388,7 +391,7 @@ Feature* Biome::getGrassFeature(Random* random) {
} }
Biome* Biome::setSnowCovered() { Biome* Biome::setSnowCovered() {
this->snowCovered = true; snowCovered = true;
return this; return this;
} }
@ -426,6 +429,7 @@ std::vector<Biome::MobSpawnerData*>* Biome::getMobs(MobCategory* category) {
if (category == MobCategory::creature_wolf) return &friendlies_wolf; if (category == MobCategory::creature_wolf) return &friendlies_wolf;
if (category == MobCategory::creature_mushroomcow) if (category == MobCategory::creature_mushroomcow)
return &friendlies_mushroomcow; return &friendlies_mushroomcow;
if (category == MobCategory::ambient) return &ambientFriendlies;
return NULL; return NULL;
} }

View file

@ -86,6 +86,7 @@ protected:
std::vector<MobSpawnerData*> friendlies_chicken; std::vector<MobSpawnerData*> friendlies_chicken;
std::vector<MobSpawnerData*> friendlies_wolf; std::vector<MobSpawnerData*> friendlies_wolf;
std::vector<MobSpawnerData*> friendlies_mushroomcow; std::vector<MobSpawnerData*> friendlies_mushroomcow;
std::vector<MobSpawnerData*> ambientFriendlies;
Biome(int id); Biome(int id);
~Biome(); ~Biome();
@ -109,9 +110,9 @@ private:
protected: protected:
/* removing these so that we can consistently return newly created trees via /* removing these so that we can consistently return newly created trees via
getTreeFeature, and let the calling function be resposible for deleting the getTreeFeature, and let the calling function be resposible for deleting the
returned tree TreeFeature *normalTree; BasicTree *fancyTree; BirchFeature returned tree TreeFeature *normalTree; BasicTree *fancyTree; BirchFeature
*birchTree; SwampTreeFeature *swampTree; *birchTree; SwampTreeFeature *swampTree;
*/ */
public: public:

View file

@ -7,8 +7,10 @@
BiomeCache::Block::Block(int x, int z, BiomeCache* parent) { BiomeCache::Block::Block(int x, int z, BiomeCache* parent) {
// temps = floatArray(ZONE_SIZE * ZONE_SIZE, false); // MGH - // temps = floatArray(ZONE_SIZE * ZONE_SIZE, false); // MGH -
// added "no clear" flag to arrayWithLength downfall = floatArray(ZONE_SIZE // added "no clear" flag to arrayWithLength downfall =
// * ZONE_SIZE, false); biomes = BiomeArray(ZONE_SIZE * ZONE_SIZE, false); // floatArray(ZONE_SIZE
// * ZONE_SIZE, false); biomes = BiomeArray(ZONE_SIZE * ZONE_SIZE,
// false);
biomeIndices = byteArray(ZONE_SIZE * ZONE_SIZE, false); biomeIndices = byteArray(ZONE_SIZE * ZONE_SIZE, false);
lastUse = 0; lastUse = 0;
@ -35,7 +37,7 @@ BiomeCache::Block::~Block() {
Biome* BiomeCache::Block::getBiome(int x, int z) { Biome* BiomeCache::Block::getBiome(int x, int z) {
// return biomes[(x & ZONE_SIZE_MASK) | ((z & ZONE_SIZE_MASK) << // return biomes[(x & ZONE_SIZE_MASK) | ((z & ZONE_SIZE_MASK) <<
//ZONE_SIZE_BITS)]; // ZONE_SIZE_BITS)];
int biomeIndex = biomeIndices[(x & ZONE_SIZE_MASK) | int biomeIndex = biomeIndices[(x & ZONE_SIZE_MASK) |
((z & ZONE_SIZE_MASK) << ZONE_SIZE_BITS)]; ((z & ZONE_SIZE_MASK) << ZONE_SIZE_BITS)];
@ -44,7 +46,7 @@ Biome* BiomeCache::Block::getBiome(int x, int z) {
float BiomeCache::Block::getTemperature(int x, int z) { float BiomeCache::Block::getTemperature(int x, int z) {
// return temps[(x & ZONE_SIZE_MASK) | ((z & ZONE_SIZE_MASK) << // return temps[(x & ZONE_SIZE_MASK) | ((z & ZONE_SIZE_MASK) <<
//ZONE_SIZE_BITS)]; // ZONE_SIZE_BITS)];
int biomeIndex = biomeIndices[(x & ZONE_SIZE_MASK) | int biomeIndex = biomeIndices[(x & ZONE_SIZE_MASK) |
((z & ZONE_SIZE_MASK) << ZONE_SIZE_BITS)]; ((z & ZONE_SIZE_MASK) << ZONE_SIZE_BITS)];
@ -147,4 +149,4 @@ BiomeArray BiomeCache::getBiomeBlockAt(int x, int z) {
byteArray BiomeCache::getBiomeIndexBlockAt(int x, int z) { byteArray BiomeCache::getBiomeIndexBlockAt(int x, int z) {
return getBlockAt(x, z)->biomeIndices; return getBlockAt(x, z)->biomeIndices;
} }

View file

@ -1,5 +1,5 @@
#pragma once #pragma once
#include "../../Util/JavaIntHash.h" #include "../Minecraft.World/JavaIntHash.h"
class BiomeCache { class BiomeCache {
private: private:
@ -49,4 +49,4 @@ public:
private: private:
CRITICAL_SECTION m_CS; CRITICAL_SECTION m_CS;
}; };

View file

@ -49,8 +49,8 @@ void BiomeDecorator::_init() {
lapisOreFeature = new OreFeature(Tile::lapisOre_Id, 6); lapisOreFeature = new OreFeature(Tile::lapisOre_Id, 6);
yellowFlowerFeature = new FlowerFeature(Tile::flower_Id); yellowFlowerFeature = new FlowerFeature(Tile::flower_Id);
roseFlowerFeature = new FlowerFeature(Tile::rose_Id); roseFlowerFeature = new FlowerFeature(Tile::rose_Id);
brownMushroomFeature = new FlowerFeature(Tile::mushroom1_Id); brownMushroomFeature = new FlowerFeature(Tile::mushroom_brown_Id);
redMushroomFeature = new FlowerFeature(Tile::mushroom2_Id); redMushroomFeature = new FlowerFeature(Tile::mushroom_red_Id);
hugeMushroomFeature = new HugeMushroomFeature(); hugeMushroomFeature = new HugeMushroomFeature();
reedsFeature = new ReedsFeature(); reedsFeature = new ReedsFeature();
cactusFeature = new CactusFeature(); cactusFeature = new CactusFeature();

View file

@ -239,6 +239,7 @@ void BiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z,
*/ */
bool BiomeSource::containsOnly(int x, int z, int r, bool BiomeSource::containsOnly(int x, int z, int r,
std::vector<Biome*> allowed) { std::vector<Biome*> allowed) {
IntCache::releaseAll();
int x0 = ((x - r) >> 2); int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2); int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2); int x1 = ((x + r) >> 2);
@ -265,6 +266,7 @@ bool BiomeSource::containsOnly(int x, int z, int r,
* NO other biomes, add a margin of at least four blocks to the radius * NO other biomes, add a margin of at least four blocks to the radius
*/ */
bool BiomeSource::containsOnly(int x, int z, int r, Biome* allowed) { bool BiomeSource::containsOnly(int x, int z, int r, Biome* allowed) {
IntCache::releaseAll();
int x0 = ((x - r) >> 2); int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2); int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2); int x1 = ((x + r) >> 2);
@ -290,6 +292,7 @@ bool BiomeSource::containsOnly(int x, int z, int r, Biome* allowed) {
*/ */
TilePos* BiomeSource::findBiome(int x, int z, int r, Biome* toFind, TilePos* BiomeSource::findBiome(int x, int z, int r, Biome* toFind,
Random* random) { Random* random) {
IntCache::releaseAll();
int x0 = ((x - r) >> 2); int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2); int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2); int x1 = ((x + r) >> 2);
@ -324,6 +327,7 @@ TilePos* BiomeSource::findBiome(int x, int z, int r, Biome* toFind,
*/ */
TilePos* BiomeSource::findBiome(int x, int z, int r, TilePos* BiomeSource::findBiome(int x, int z, int r,
std::vector<Biome*> allowed, Random* random) { std::vector<Biome*> allowed, Random* random) {
IntCache::releaseAll();
int x0 = ((x - r) >> 2); int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2); int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2); int x1 = ((x + r) >> 2);
@ -335,8 +339,7 @@ TilePos* BiomeSource::findBiome(int x, int z, int r,
intArray biomes = layer->getArea(x0, z0, w, h); intArray biomes = layer->getArea(x0, z0, w, h);
TilePos* res = NULL; TilePos* res = NULL;
int found = 0; int found = 0;
int biomesCount = w * h; for (unsigned int i = 0; i < w * h; i++) {
for (unsigned int i = 0; i < biomesCount; i++) {
int xx = (x0 + i % w) << 2; int xx = (x0 + i % w) << 2;
int zz = (z0 + i / w) << 2; int zz = (z0 + i / w) << 2;
Biome* b = Biome::biomes[biomes[i]]; Biome* b = Biome::biomes[biomes[i]];
@ -376,7 +379,7 @@ int64_t BiomeSource::findSeed(LevelType* generator)
#ifndef _CONTENT_PACKAGE #ifndef _CONTENT_PACKAGE
if (app.DebugSettingsOn() && if (app.DebugSettingsOn() &&
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) & app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
(1L << eDebugSetting_EnableHeightWaterBiomeOverride)) { (1L << eDebugSetting_EnableBiomeOverride)) {
// Do nothing // Do nothing
} else } else
#endif #endif
@ -590,4 +593,4 @@ bool BiomeSource::getIsMatch(float* frac) {
// or more - currently there's 8 critical so this just forces at least 1 // or more - currently there's 8 critical so this just forces at least 1
// more others // more others
return (typeCount >= 9); return (typeCount >= 9);
} }

View file

@ -27,4 +27,4 @@ void DesertBiome::decorate(Level* level, Random* random, int xo, int zo) {
Feature* well = new DesertWellFeature(); Feature* well = new DesertWellFeature();
well->place(level, random, x, level->getHeightmap(x, z) + 1, z); well->place(level, random, x, level->getHeightmap(x, z) + 1, z);
} }
} }

View file

@ -1,9 +1,15 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
#include "../../Headers/net.minecraft.world.level.levelgen.feature.h"
#include "ExtremeHillsBiome.h" #include "ExtremeHillsBiome.h"
ExtremeHillsBiome::ExtremeHillsBiome(int id) : Biome(id) { friendlies.clear(); } ExtremeHillsBiome::ExtremeHillsBiome(int id) : Biome(id) {
silverfishFeature = new OreFeature(Tile::monsterStoneEgg_Id, 8);
friendlies.clear();
}
ExtremeHillsBiome::~ExtremeHillsBiome() { delete silverfishFeature; }
void ExtremeHillsBiome::decorate(Level* level, Random* random, int xo, int zo) { void ExtremeHillsBiome::decorate(Level* level, Random* random, int xo, int zo) {
Biome::decorate(level, random, xo, zo); Biome::decorate(level, random, xo, zo);
@ -15,9 +21,17 @@ void ExtremeHillsBiome::decorate(Level* level, Random* random, int xo, int zo) {
int y = random->nextInt((Level::genDepth / 4) - 4) + 4; int y = random->nextInt((Level::genDepth / 4) - 4) + 4;
int z = zo + random->nextInt(16); int z = zo + random->nextInt(16);
int tile = level->getTile(x, y, z); int tile = level->getTile(x, y, z);
if (tile == Tile::rock_Id) { if (tile == Tile::stone_Id) {
level->setTileNoUpdate(x, y, z, Tile::emeraldOre_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(Level::genDepth / 2);
int z = zo + random->nextInt(16);
silverfishFeature->place(level, random, x, y, z);
}
} }

View file

@ -7,9 +7,11 @@ class ExtremeHillsBiome : public Biome {
private: private:
static const bool GENERATE_EMERALD_ORE = true; static const bool GENERATE_EMERALD_ORE = true;
Feature* silverfishFeature;
protected: protected:
ExtremeHillsBiome(int id); ExtremeHillsBiome(int id);
~ExtremeHillsBiome();
public: public:
void decorate(Level* level, Random* random, int xo, int zo); void decorate(Level* level, Random* random, int xo, int zo);

View file

@ -2,77 +2,29 @@
#include "../../Util/Arrays.h" #include "../../Util/Arrays.h"
#include "FixedBiomeSource.h" #include "FixedBiomeSource.h"
/**
* @brief Constructs a FixedBiomeSource with a single biome, temperature, and
* downfall.
*
* @param fixed Biome to use for the entire source
* @param temperature Temperature value for all blocks
* @param downfall Downfall value for all blocks
*/
FixedBiomeSource::FixedBiomeSource(Biome* fixed, float temperature, FixedBiomeSource::FixedBiomeSource(Biome* fixed, float temperature,
float downfall) { float downfall) {
this->biome = fixed; biome = fixed;
this->temperature = temperature; this->temperature = temperature;
this->downfall = downfall; this->downfall = downfall;
} }
/**
* @brief Returns the biome at a given ChunkPos.
*
* @param cp Target chunk position
* @return Biome* Always returns the fixed biome
*/
Biome* FixedBiomeSource::getBiome(ChunkPos* cp) { return biome; } Biome* FixedBiomeSource::getBiome(ChunkPos* cp) { return biome; }
/**
* @brief Returns the biome at specific coordinates.
*
* @param x X coordinate
* @param z Z coordinate
* @return Biome* Always returns the fixed biome
*/
Biome* FixedBiomeSource::getBiome(int x, int z) { return biome; } Biome* FixedBiomeSource::getBiome(int x, int z) { return biome; }
/**
* @brief Returns the temperature at specific coordinates.
*
* @param x X coordinate
* @param z Z coordinate
* @return float The fixed temperature
*/
float FixedBiomeSource::getTemperature(int x, int z) { return temperature; } float FixedBiomeSource::getTemperature(int x, int z) { return temperature; }
/**
* @brief Fills a float array with temperature values for a rectangular region.
*
* If the array is null or too small, it will be reallocated.
*
* @param temperatures Array to fill with temperature values
* @param x Starting X coordinate
* @param z Starting Z coordinate
* @param w Width of the region
* @param h Height of the region
*/
void FixedBiomeSource::getTemperatureBlock(floatArray& temperatures, int x, void FixedBiomeSource::getTemperatureBlock(floatArray& temperatures, int x,
int z, int w, int h) const { int z, int w, int h) const {
if (!temperatures.data || temperatures.length < w * h) { if (temperatures.data == NULL || temperatures.length < w * h) {
if (temperatures.data) delete[] temperatures.data; if (temperatures.data != NULL) delete[] temperatures.data;
temperatures = floatArray(w * h); temperatures = floatArray(w * h);
} }
Arrays::fill(temperatures, 0, w * h, temperature); Arrays::fill(temperatures, 0, w * h, temperature);
} }
/**
* @brief Returns a floatArray filled with temperatures.
*
* @param x Starting X coordinate
* @param z Starting Z coordinate
* @param w Width of the region
* @param h Height of the region
* @note 4J - Caller is responsible for deleting returned array.
* @note 4J - Temperatures array is for output only
* @return floatArray Filled with temperature values
*/
floatArray FixedBiomeSource::getTemperatureBlock(int x, int z, int w, floatArray FixedBiomeSource::getTemperatureBlock(int x, int z, int w,
int h) const { int h) const {
floatArray temps(w * h); floatArray temps(w * h);
@ -80,24 +32,15 @@ floatArray FixedBiomeSource::getTemperatureBlock(int x, int z, int w,
return temps; return temps;
} }
/** // 4J - note that caller is responsible for deleting returned array.
* @brief Fills a double array with temperature values. // temperatures array is for output only.
*
* @param temperatures Array to fill (memory allocated inside)
* @param x Starting X coordinate
* @param z Starting Z coordinate
* @param w Width of the region
* @param h Height of the region
*/
void FixedBiomeSource::getTemperatureBlock(doubleArray& temperatures, int x, void FixedBiomeSource::getTemperatureBlock(doubleArray& temperatures, int x,
int z, int w, int h) const { int z, int w, int h) const {
temperatures = doubleArray(w * h); temperatures = doubleArray(w * h);
Arrays::fill(temperatures, 0, w * h, static_cast<double>(temperature));
Arrays::fill(temperatures, 0, w * h, (double)temperature);
} }
/**
* @brief Fills a float array with downfall values for a rectangular region.
*/
void FixedBiomeSource::getDownfallBlock(floatArray& downfalls, int x, int z, void FixedBiomeSource::getDownfallBlock(floatArray& downfalls, int x, int z,
int w, int h) const { int w, int h) const {
if (downfalls.data == NULL || downfalls.length < w * h) { if (downfalls.data == NULL || downfalls.length < w * h) {
@ -106,9 +49,7 @@ void FixedBiomeSource::getDownfallBlock(floatArray& downfalls, int x, int z,
} }
Arrays::fill(downfalls, 0, w * h, downfall); Arrays::fill(downfalls, 0, w * h, downfall);
} }
/**
* @brief Returns a floatArray filled with downfall values.
*/
floatArray FixedBiomeSource::getDownfallBlock(int x, int z, int w, floatArray FixedBiomeSource::getDownfallBlock(int x, int z, int w,
int h) const { int h) const {
floatArray downfalls(w * h); floatArray downfalls(w * h);
@ -116,37 +57,30 @@ floatArray FixedBiomeSource::getDownfallBlock(int x, int z, int w,
return downfalls; return downfalls;
} }
/**
* @brief Returns the fixed downfall value at given coordinates.
*/
float FixedBiomeSource::getDownfall(int x, int z) const { return downfall; } float FixedBiomeSource::getDownfall(int x, int z) const { return downfall; }
/** void FixedBiomeSource::getDownfallBlock(doubleArray downfalls, int x, int z,
* @brief Fills a double array with downfall values.
*/
void FixedBiomeSource::getDownfallBlock(doubleArray& downfalls, int x, int z,
int w, int h) { int w, int h) {
if (!downfalls.data || downfalls.length < w * h) { if (downfalls.data == NULL || downfalls.length < w * h) {
if (downfalls.data) delete[] downfalls.data; if (downfalls.data != NULL) delete[] downfalls.data;
downfalls = doubleArray(w * h); downfalls = doubleArray(w * h);
} }
Arrays::fill(downfalls, 0, w * h, static_cast<double>(downfall)); Arrays::fill(downfalls, 0, w * h, (double)downfall);
} }
/** // 4J - caller is responsible for deleting biomes array, plus any optional
* @brief Fills a BiomeArray with the fixed biome for a region. // arrays output if pointers are passed in (_temperatures, _downfalls)
*/
void FixedBiomeSource::getBiomeBlock(BiomeArray& biomes, int x, int z, int w, void FixedBiomeSource::getBiomeBlock(BiomeArray& biomes, int x, int z, int w,
int h, bool useCache) const { int h, bool useCache) const {
MemSect(36); MemSect(36);
biomes = BiomeArray(w * h); biomes = BiomeArray(w * h);
MemSect(0); MemSect(0);
Arrays::fill(biomes, 0, w * h, biome); Arrays::fill(biomes, 0, w * h, biome);
} }
/** // 4J - caller is responsible for deleting biomes array, plus any optional
* @brief Fills a byteArray with the biome index for a region. // arrays output if pointers are passed in (_temperatures, _downfalls)
*/
void FixedBiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, void FixedBiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z,
int w, int h, bool useCache) const { int w, int h, bool useCache) const {
MemSect(36); MemSect(36);
@ -156,27 +90,21 @@ void FixedBiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z,
Arrays::fill(biomeIndices, 0, w * h, biomeIndex); Arrays::fill(biomeIndices, 0, w * h, biomeIndex);
} }
/** // 4J-PB added in from beyond 1.8.2
* @brief Fills a BiomeArray with the fixed biome for a region (raw version). // 4J - caller is responsible for deleting biomes array, plus any optional
* @note 4J-PB Added in beyond 1.8.2 // arrays output if pointers are passed in (_temperatures, _downfalls)
* @note 4J - Caller is responsible for deleting biomes array, plus any optional
* arrays output if pointers are passed in (_temperatures, _downfalls)
*/
void FixedBiomeSource::getRawBiomeBlock(BiomeArray& biomes, int x, int z, int w, void FixedBiomeSource::getRawBiomeBlock(BiomeArray& biomes, int x, int z, int w,
int h) const { int h) const {
MemSect(36); MemSect(36);
biomes = BiomeArray(w * h); biomes = BiomeArray(w * h);
MemSect(0); MemSect(0);
Arrays::fill(biomes, 0, w * h, biome); Arrays::fill(biomes, 0, w * h, biome);
} }
/** // 4J-PB added in from beyond 1.8.2
* @brief Returns a raw BiomeArray. // 4J - caller is responsible for deleting biomes array, plus any optional
* @note 4J-PB Added in beyond 1.8.2 // arrays output if pointers are passed in (_temperatures, _downfalls)
* @note 4J - caller is responsible for deleting biomes array, plus any
* optional arrays output if pointers are passed in (_temperatures,
* _downfalls)
*/
BiomeArray FixedBiomeSource::getRawBiomeBlock(int x, int z, int w, BiomeArray FixedBiomeSource::getRawBiomeBlock(int x, int z, int w,
int h) const { int h) const {
BiomeArray biomes; BiomeArray biomes;
@ -184,9 +112,6 @@ BiomeArray FixedBiomeSource::getRawBiomeBlock(int x, int z, int w,
return biomes; return biomes;
} }
/**
* @brief Finds a biome within a radius randomly.
*/
TilePos* FixedBiomeSource::findBiome(int x, int z, int r, Biome* toFind, TilePos* FixedBiomeSource::findBiome(int x, int z, int r, Biome* toFind,
Random* random) { Random* random) {
if (toFind == biome) { if (toFind == biome) {
@ -196,30 +121,22 @@ TilePos* FixedBiomeSource::findBiome(int x, int z, int r, Biome* toFind,
return nullptr; return nullptr;
} }
/**
* @brief Finds a biome from a list of allowed biomes randomly.
*/
TilePos* FixedBiomeSource::findBiome(int x, int z, int r, TilePos* FixedBiomeSource::findBiome(int x, int z, int r,
const std::vector<Biome*> allowed, std::vector<Biome*> allowed,
Random* random) { Random* random) {
if (find(allowed.begin(), allowed.end(), biome) != allowed.end()) { if (find(allowed.begin(), allowed.end(), biome) != allowed.end()) {
return new TilePos(x - r + random->nextInt(r * 2 + 1), 0, return new TilePos(x - r + random->nextInt(r * 2 + 1), 0,
z - r + random->nextInt(r * 2 + 1)); z - r + random->nextInt(r * 2 + 1));
} }
return nullptr;
return NULL;
} }
/**
* @brief Checks if the allowed biome matches the fixed biome.
*/
bool FixedBiomeSource::containsOnly(int x, int z, int r, Biome* allowed) { bool FixedBiomeSource::containsOnly(int x, int z, int r, Biome* allowed) {
return allowed == biome; return allowed == biome;
} }
/**
* @brief Checks if the fixed biome is in the allowed list.
*/
bool FixedBiomeSource::containsOnly(int x, int z, int r, bool FixedBiomeSource::containsOnly(int x, int z, int r,
const std::vector<Biome*> allowed) { std::vector<Biome*> allowed) {
return find(allowed.begin(), allowed.end(), biome) != allowed.end(); return find(allowed.begin(), allowed.end(), biome) != allowed.end();
} }

View file

@ -1,16 +1,16 @@
#pragma once #pragma once
#include <vector>
#include "BiomeSource.h" #include "BiomeSource.h"
class FixedBiomeSource : public BiomeSource { class FixedBiomeSource : public BiomeSource {
private: private:
Biome* biome; Biome* biome;
float temperature, downfall; float temperature, downfall;
public: public:
using BiomeSource::getTemperature; using BiomeSource::getTemperature;
FixedBiomeSource(Biome* fixed, float temperature, float downfall); FixedBiomeSource(Biome* fixed, float temperature, float downfall);
virtual Biome* getBiome(ChunkPos* cp); virtual Biome* getBiome(ChunkPos* cp);
virtual Biome* getBiome(int x, int z); virtual Biome* getBiome(int x, int z);
virtual float getTemperature(int x, int z); virtual float getTemperature(int x, int z);
@ -23,23 +23,23 @@ class FixedBiomeSource : public BiomeSource {
int h) const; int h) const;
virtual floatArray getDownfallBlock(int x, int z, int w, int h) const; virtual floatArray getDownfallBlock(int x, int z, int w, int h) const;
virtual float getDownfall(int x, int z) const; virtual float getDownfall(int x, int z) const;
virtual void getDownfallBlock(doubleArray& downfalls, int x, int z, int w, virtual void getDownfallBlock(doubleArray downfalls, int x, int z, int w,
int h); int h);
virtual void getBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h, virtual void getBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h,
bool useCache) const; bool useCache) const;
virtual void getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, virtual void getBiomeIndexBlock(byteArray& biomeIndices, int x, int z,
int w, int h, bool useCache) const; int w, int h, bool useCache) const;
// 4J-PB added in from beyond 1.8.2 // 4J-PB added in from beyond 1.8.2
virtual BiomeArray getRawBiomeBlock(int x, int z, int w, int h) const; virtual BiomeArray getRawBiomeBlock(int x, int z, int w, int h) const;
virtual void getRawBiomeBlock(BiomeArray& biomes, int x, int z, int w, virtual void getRawBiomeBlock(BiomeArray& biomes, int x, int z, int w,
int h) const; int h) const;
////////////////////////////////////
virtual TilePos* findBiome(int x, int z, int r, Biome* toFind, virtual TilePos* findBiome(int x, int z, int r, Biome* toFind,
Random* random); Random* random);
virtual TilePos* findBiome(int x, int z, int r, virtual TilePos* findBiome(int x, int z, int r, std::vector<Biome*> allowed,
const std::vector<Biome*> allowed,
Random* random); Random* random);
virtual bool containsOnly(int x, int z, int r, Biome* allowed); virtual bool containsOnly(int x, int z, int r, Biome* allowed);
virtual bool containsOnly( virtual bool containsOnly(int x, int z, int r, std::vector<Biome*> allowed);
int x, int z, int r,
const std::vector<Biome*> allowed);
}; };

View file

@ -8,6 +8,7 @@ HellBiome::HellBiome(int id) : Biome(id) {
friendlies_chicken.clear(); // 4J added friendlies_chicken.clear(); // 4J added
friendlies_wolf.clear(); // 4J added friendlies_wolf.clear(); // 4J added
waterFriendlies.clear(); waterFriendlies.clear();
ambientFriendlies.clear();
enemies.push_back(new MobSpawnerData(eTYPE_GHAST, 50, 4, 4)); enemies.push_back(new MobSpawnerData(eTYPE_GHAST, 50, 4, 4));
enemies.push_back(new MobSpawnerData(eTYPE_PIGZOMBIE, 100, 4, 4)); enemies.push_back(new MobSpawnerData(eTYPE_PIGZOMBIE, 100, 4, 4));

View file

@ -11,7 +11,7 @@ JungleBiome::JungleBiome(int id) : Biome(id) {
decorator->grassCount = 25; decorator->grassCount = 25;
decorator->flowerCount = 4; decorator->flowerCount = 4;
enemies.push_back(new MobSpawnerData(eTYPE_OZELOT, 2, 1, 1)); enemies.push_back(new MobSpawnerData(eTYPE_OCELOT, 2, 1, 1));
// make chicken a lot more common in the jungle // make chicken a lot more common in the jungle
friendlies.push_back(new MobSpawnerData(eTYPE_CHICKEN, 10, 4, 4)); friendlies.push_back(new MobSpawnerData(eTYPE_CHICKEN, 10, 4, 4));

View file

@ -2,6 +2,8 @@
#include "../../Headers/net.minecraft.world.level.biome.h" #include "../../Headers/net.minecraft.world.level.biome.h"
PlainsBiome::PlainsBiome(int id) : Biome(id) { PlainsBiome::PlainsBiome(int id) : Biome(id) {
friendlies.push_back(new MobSpawnerData(eTYPE_HORSE, 5, 2, 6));
decorator->treeCount = -999; decorator->treeCount = -999;
decorator->flowerCount = 4; decorator->flowerCount = 4;
decorator->grassCount = 10; decorator->grassCount = 10;

View file

@ -13,6 +13,8 @@ SwampBiome::SwampBiome(int id) : Biome(id) {
decorator->waterlilyCount = 4; decorator->waterlilyCount = 4;
// waterColor = 0xe0ffae; // waterColor = 0xe0ffae;
enemies.push_back(new MobSpawnerData(eTYPE_SLIME, 1, 1, 1));
} }
Feature* SwampBiome::getTreeFeature(Random* random) { Feature* SwampBiome::getTreeFeature(Random* random) {

View file

@ -10,10 +10,11 @@ TheEndBiome::TheEndBiome(int id) : Biome(id) {
friendlies_chicken.clear(); // 4J added friendlies_chicken.clear(); // 4J added
friendlies_wolf.clear(); // 4J added friendlies_wolf.clear(); // 4J added
waterFriendlies.clear(); waterFriendlies.clear();
ambientFriendlies.clear();
enemies.push_back(new MobSpawnerData(eTYPE_ENDERMAN, 10, 4, 4)); enemies.push_back(new MobSpawnerData(eTYPE_ENDERMAN, 10, 4, 4));
topMaterial = (uint8_t)Tile::dirt_Id; topMaterial = (uint8_t)Tile::dirt_Id;
this->material = (uint8_t)Tile::dirt_Id; material = (uint8_t)Tile::dirt_Id;
decorator = new TheEndBiomeDecorator(this); decorator = new TheEndBiomeDecorator(this);
} }

View file

@ -50,7 +50,7 @@ bool BirchFeature::place(Level* level, Random* random, int x, int y, int z) {
} }
} }
level->setTileNoUpdate(x, y - 1, z, Tile::dirt_Id); placeBlock(level, x, y - 1, z, Tile::dirt_Id);
for (int yy = y - 3 + treeHeight; yy <= y + treeHeight; yy++) { for (int yy = y - 3 + treeHeight; yy <= y + treeHeight; yy++) {
int yo = yy - (y + treeHeight); int yo = yy - (y + treeHeight);
@ -62,7 +62,8 @@ bool BirchFeature::place(Level* level, Random* random, int x, int y, int z) {
if (abs(xo) == offs && abs(zo) == offs && if (abs(xo) == offs && abs(zo) == offs &&
(random->nextInt(2) == 0 || yo == 0)) (random->nextInt(2) == 0 || yo == 0))
continue; continue;
if (!Tile::solid[level->getTile(xx, yy, zz)]) int t = level->getTile(xx, yy, zz);
if (t == 0 || t == Tile::leaves_Id)
placeBlock(level, xx, yy, zz, Tile::leaves_Id, placeBlock(level, xx, yy, zz, Tile::leaves_Id,
LeafTile::BIRCH_LEAF); LeafTile::BIRCH_LEAF);
} }

View file

@ -44,14 +44,13 @@ bool BonusChestFeature::place(Level* level, Random* random, int x, int y, int z,
if (force) { if (force) {
x2 = x; x2 = x;
y2 = y2 = y - 1; // 4J - the position passed in is actually two above
y - 1; // 4J - the position passed in is actually two above the // the top solid block, as the calling function adds 1
// top solid block, as the calling function adds 1 to // to getTopSolidBlock, and that actually returns the
// getTopSolidBlock, and that actually returns the block // block above anyway.
// above anyway. this would explain why there is a while // this would explain why there is a while loop above here (not used
// loop above here (not used in force mode) to move the // in force mode) to move the y back down again, shouldn't really be
// y back down again, shouldn't really be needed if 1 // needed if 1 wasn't added to the getTopSolidBlock return value.
// wasn't added to the getTopSolidBlock return value.
z2 = z; z2 = z;
} else { } else {
x2 = x + random->nextInt(4) - random->nextInt(4); x2 = x + random->nextInt(4) - random->nextInt(4);
@ -61,7 +60,8 @@ bool BonusChestFeature::place(Level* level, Random* random, int x, int y, int z,
if (force || (level->isEmptyTile(x2, y2, z2) && if (force || (level->isEmptyTile(x2, y2, z2) &&
level->isTopSolidBlocking(x2, y2 - 1, z2))) { level->isTopSolidBlocking(x2, y2 - 1, z2))) {
level->setTile(x2, y2, z2, Tile::chest_Id); level->setTileAndData(x2, y2, z2, Tile::chest_Id, 0,
Tile::UPDATE_CLIENTS);
std::shared_ptr<ChestTileEntity> chest = std::shared_ptr<ChestTileEntity> chest =
std::dynamic_pointer_cast<ChestTileEntity>( std::dynamic_pointer_cast<ChestTileEntity>(
level->getTileEntity(x2, y2, z2)); level->getTileEntity(x2, y2, z2));
@ -72,19 +72,23 @@ bool BonusChestFeature::place(Level* level, Random* random, int x, int y, int z,
} }
if (level->isEmptyTile(x2 - 1, y2, z2) && if (level->isEmptyTile(x2 - 1, y2, z2) &&
level->isTopSolidBlocking(x2 - 1, y2 - 1, z2)) { level->isTopSolidBlocking(x2 - 1, y2 - 1, z2)) {
level->setTile(x2 - 1, y2, z2, Tile::torch_Id); level->setTileAndData(x2 - 1, y2, z2, Tile::torch_Id, 0,
Tile::UPDATE_CLIENTS);
} }
if (level->isEmptyTile(x2 + 1, y2, z2) && if (level->isEmptyTile(x2 + 1, y2, z2) &&
level->isTopSolidBlocking(x2 - 1, y2 - 1, z2)) { level->isTopSolidBlocking(x2 - 1, y2 - 1, z2)) {
level->setTile(x2 + 1, y2, z2, Tile::torch_Id); level->setTileAndData(x2 + 1, y2, z2, Tile::torch_Id, 0,
Tile::UPDATE_CLIENTS);
} }
if (level->isEmptyTile(x2, y2, z2 - 1) && if (level->isEmptyTile(x2, y2, z2 - 1) &&
level->isTopSolidBlocking(x2 - 1, y2 - 1, z2)) { level->isTopSolidBlocking(x2 - 1, y2 - 1, z2)) {
level->setTile(x2, y2, z2 - 1, Tile::torch_Id); level->setTileAndData(x2, y2, z2 - 1, Tile::torch_Id, 0,
Tile::UPDATE_CLIENTS);
} }
if (level->isEmptyTile(x2, y2, z2 + 1) && if (level->isEmptyTile(x2, y2, z2 + 1) &&
level->isTopSolidBlocking(x2 - 1, y2 - 1, z2)) { level->isTopSolidBlocking(x2 - 1, y2 - 1, z2)) {
level->setTile(x2, y2, z2 + 1, Tile::torch_Id); level->setTileAndData(x2, y2, z2 + 1, Tile::torch_Id, 0,
Tile::UPDATE_CLIENTS);
} }
return true; return true;
} }

View file

@ -12,7 +12,8 @@ bool CactusFeature::place(Level* level, Random* random, int x, int y, int z) {
int h = 1 + random->nextInt(random->nextInt(3) + 1); int h = 1 + random->nextInt(random->nextInt(3) + 1);
for (int yy = 0; yy < h; yy++) { for (int yy = 0; yy < h; yy++) {
if (Tile::cactus->canSurvive(level, x2, y2 + yy, z2)) { if (Tile::cactus->canSurvive(level, x2, y2 + yy, z2)) {
level->setTileNoUpdate(x2, y2 + yy, z2, Tile::cactus_Id); level->setTileAndData(x2, y2 + yy, z2, Tile::cactus_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }

View file

@ -129,7 +129,7 @@ void CanyonFeature::addTunnel(int64_t seed, int xOffs, int zOffs,
if ((xd * xd + zd * zd) * rs[yy] + (yd * yd / 6) < 1) { if ((xd * xd + zd * zd) * rs[yy] + (yd * yd / 6) < 1) {
int block = blocks[p]; int block = blocks[p];
if (block == Tile::grass_Id) hasGrass = true; if (block == Tile::grass_Id) hasGrass = true;
if (block == Tile::rock_Id || if (block == Tile::stone_Id ||
block == Tile::dirt_Id || block == Tile::dirt_Id ||
block == Tile::grass_Id) { block == Tile::grass_Id) {
if (yy < 10) { if (yy < 10) {

View file

@ -77,7 +77,7 @@ bool CaveFeature::place(Level* level, Random* random, int x, int y, int z) {
AUTO_VAR(itEnd, toRemove.end()); AUTO_VAR(itEnd, toRemove.end());
for (AUTO_VAR(it, toRemove.begin()); it != itEnd; it++) { for (AUTO_VAR(it, toRemove.begin()); it != itEnd; it++) {
TilePos* p = *it; // toRemove[i]; TilePos* p = *it; // toRemove[i];
level->setTileNoUpdate(p->x, p->y, p->z, 0); level->setTileAndData(p->x, p->y, p->z, 0, 0, Tile::UPDATE_CLIENTS);
} }
itEnd = toRemove.end(); itEnd = toRemove.end();
@ -85,7 +85,8 @@ bool CaveFeature::place(Level* level, Random* random, int x, int y, int z) {
TilePos* p = *it; // toRemove[i]; TilePos* p = *it; // toRemove[i];
if (level->getTile(p->x, p->y - 1, p->z) == Tile::dirt_Id && if (level->getTile(p->x, p->y - 1, p->z) == Tile::dirt_Id &&
level->getDaytimeRawBrightness(p->x, p->y, p->z) > 8) { level->getDaytimeRawBrightness(p->x, p->y, p->z) > 8) {
level->setTileNoUpdate(p->x, p->y - 1, p->z, Tile::grass_Id); level->setTileAndData(p->x, p->y - 1, p->z, Tile::grass_Id, 0,
Tile::UPDATE_CLIENTS);
} }
delete p; delete p;
} }

View file

@ -22,7 +22,8 @@ bool ClayFeature::place(Level* level, Random* random, int x, int y, int z) {
for (int yy = y - yr; yy <= y + yr; yy++) { for (int yy = y - yr; yy <= y + yr; yy++) {
int t = level->getTile(xx, yy, zz); int t = level->getTile(xx, yy, zz);
if (t == Tile::dirt_Id || t == Tile::clay_Id) { if (t == Tile::dirt_Id || t == Tile::clay_Id) {
level->setTileNoUpdate(xx, yy, zz, tile); level->setTileAndData(xx, yy, zz, tile, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }

View file

@ -17,7 +17,8 @@ bool DeadBushFeature::place(Level* level, Random* random, int x, int y, int z) {
int z2 = z + random->nextInt(8) - random->nextInt(8); int z2 = z + random->nextInt(8) - random->nextInt(8);
if (level->isEmptyTile(x2, y2, z2)) { if (level->isEmptyTile(x2, y2, z2)) {
if (Tile::tiles[tile]->canSurvive(level, x2, y2, z2)) { if (Tile::tiles[tile]->canSurvive(level, x2, y2, z2)) {
level->setTileNoUpdate(x2, y2, z2, tile); level->setTileAndData(x2, y2, z2, tile, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }

View file

@ -26,57 +26,62 @@ bool DesertWellFeature::place(Level* level, Random* random, int x, int y,
for (int oy = -1; oy <= 0; oy++) { for (int oy = -1; oy <= 0; oy++) {
for (int ox = -2; ox <= 2; ox++) { for (int ox = -2; ox <= 2; ox++) {
for (int oz = -2; oz <= 2; oz++) { for (int oz = -2; oz <= 2; oz++) {
level->setTileNoUpdate(x + ox, y + oy, z + oz, level->setTileAndData(x + ox, y + oy, z + oz,
Tile::sandStone_Id); Tile::sandStone_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }
// place water cross // place water cross
level->setTileNoUpdate(x, y, z, Tile::water_Id); level->setTileAndData(x, y, z, Tile::water_Id, 0, Tile::UPDATE_CLIENTS);
level->setTileNoUpdate(x - 1, y, z, Tile::water_Id); level->setTileAndData(x - 1, y, z, Tile::water_Id, 0, Tile::UPDATE_CLIENTS);
level->setTileNoUpdate(x + 1, y, z, Tile::water_Id); level->setTileAndData(x + 1, y, z, Tile::water_Id, 0, Tile::UPDATE_CLIENTS);
level->setTileNoUpdate(x, y, z - 1, Tile::water_Id); level->setTileAndData(x, y, z - 1, Tile::water_Id, 0, Tile::UPDATE_CLIENTS);
level->setTileNoUpdate(x, y, z + 1, Tile::water_Id); level->setTileAndData(x, y, z + 1, Tile::water_Id, 0, Tile::UPDATE_CLIENTS);
// place "fence" // place "fence"
for (int ox = -2; ox <= 2; ox++) { for (int ox = -2; ox <= 2; ox++) {
for (int oz = -2; oz <= 2; oz++) { for (int oz = -2; oz <= 2; oz++) {
if (ox == -2 || ox == 2 || oz == -2 || oz == 2) { if (ox == -2 || ox == 2 || oz == -2 || oz == 2) {
level->setTileNoUpdate(x + ox, y + 1, z + oz, level->setTileAndData(x + ox, y + 1, z + oz, Tile::sandStone_Id,
Tile::sandStone_Id); 0, Tile::UPDATE_CLIENTS);
} }
} }
} }
level->setTileAndDataNoUpdate(x + 2, y + 1, z, Tile::stoneSlabHalf_Id, level->setTileAndData(x + 2, y + 1, z, Tile::stoneSlabHalf_Id,
StoneSlabTile::SAND_SLAB); StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS);
level->setTileAndDataNoUpdate(x - 2, y + 1, z, Tile::stoneSlabHalf_Id, level->setTileAndData(x - 2, y + 1, z, Tile::stoneSlabHalf_Id,
StoneSlabTile::SAND_SLAB); StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS);
level->setTileAndDataNoUpdate(x, y + 1, z + 2, Tile::stoneSlabHalf_Id, level->setTileAndData(x, y + 1, z + 2, Tile::stoneSlabHalf_Id,
StoneSlabTile::SAND_SLAB); StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS);
level->setTileAndDataNoUpdate(x, y + 1, z - 2, Tile::stoneSlabHalf_Id, level->setTileAndData(x, y + 1, z - 2, Tile::stoneSlabHalf_Id,
StoneSlabTile::SAND_SLAB); StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS);
// place roof // place roof
for (int ox = -1; ox <= 1; ox++) { for (int ox = -1; ox <= 1; ox++) {
for (int oz = -1; oz <= 1; oz++) { for (int oz = -1; oz <= 1; oz++) {
if (ox == 0 && oz == 0) { if (ox == 0 && oz == 0) {
level->setTileNoUpdate(x + ox, y + 4, z + oz, level->setTileAndData(x + ox, y + 4, z + oz, Tile::sandStone_Id,
Tile::sandStone_Id); 0, Tile::UPDATE_CLIENTS);
} else { } else {
level->setTileAndDataNoUpdate(x + ox, y + 4, z + oz, level->setTileAndData(
Tile::stoneSlabHalf_Id, x + ox, y + 4, z + oz, Tile::stoneSlabHalf_Id,
StoneSlabTile::SAND_SLAB); StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS);
} }
} }
} }
// place pillars // place pillars
for (int oy = 1; oy <= 3; oy++) { for (int oy = 1; oy <= 3; oy++) {
level->setTileNoUpdate(x - 1, y + oy, z - 1, Tile::sandStone_Id); level->setTileAndData(x - 1, y + oy, z - 1, Tile::sandStone_Id, 0,
level->setTileNoUpdate(x - 1, y + oy, z + 1, Tile::sandStone_Id); Tile::UPDATE_CLIENTS);
level->setTileNoUpdate(x + 1, y + oy, z - 1, Tile::sandStone_Id); level->setTileAndData(x - 1, y + oy, z + 1, Tile::sandStone_Id, 0,
level->setTileNoUpdate(x + 1, y + oy, z + 1, Tile::sandStone_Id); Tile::UPDATE_CLIENTS);
level->setTileAndData(x + 1, y + oy, z - 1, Tile::sandStone_Id, 0,
Tile::UPDATE_CLIENTS);
level->setTileAndData(x + 1, y + oy, z + 1, Tile::sandStone_Id, 0,
Tile::UPDATE_CLIENTS);
} }
return true; return true;

View file

@ -132,7 +132,7 @@ void DungeonFeature::addTunnel(int xOffs, int zOffs, byteArray blocks,
if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) { if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) {
int block = blocks[p]; int block = blocks[p];
if (block == Tile::grass_Id) hasGrass = true; if (block == Tile::grass_Id) hasGrass = true;
if (block == Tile::rock_Id || block == Tile::dirt_Id || if (block == Tile::stone_Id || block == Tile::dirt_Id ||
block == Tile::grass_Id) { block == Tile::grass_Id) {
if (yy < 10) { if (yy < 10) {
blocks[p] = (uint8_t)Tile::lava_Id; blocks[p] = (uint8_t)Tile::lava_Id;

View file

@ -59,7 +59,7 @@ bool EndPodiumFeature::place(Level* level, Random* random, int x, int y,
for (int xx = x - (r - 1); xx <= x + (r - 1); xx++) { for (int xx = x - (r - 1); xx <= x + (r - 1); xx++) {
for (int zz = z - (r - 1); zz <= z + (r - 1); zz++) { for (int zz = z - (r - 1); zz <= z + (r - 1); zz++) {
if (level->isEmptyTile(xx, yy, zz)) { if (level->isEmptyTile(xx, yy, zz)) {
placeBlock(level, xx, yy, zz, Tile::whiteStone_Id, 0); placeBlock(level, xx, yy, zz, Tile::endStone_Id, 0);
} }
} }
} }

View file

@ -1,11 +1,15 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.tile.h"
#include "Feature.h" #include "Feature.h"
Feature::Feature() { this->doUpdate = false; } Feature::Feature() { this->doUpdate = false; }
Feature::Feature(bool doUpdate) { this->doUpdate = doUpdate; } Feature::Feature(bool doUpdate) { this->doUpdate = doUpdate; }
void Feature::applyFeature(Level* level, Random* random, int xChunk,
int zChunk) {}
void Feature::placeBlock(Level* level, int x, int y, int z, int tile) { void Feature::placeBlock(Level* level, int x, int y, int z, int tile) {
placeBlock(level, x, y, z, tile, 0); placeBlock(level, x, y, z, tile, 0);
} }
@ -13,8 +17,8 @@ void Feature::placeBlock(Level* level, int x, int y, int z, int tile) {
void Feature::placeBlock(Level* level, int x, int y, int z, int tile, void Feature::placeBlock(Level* level, int x, int y, int z, int tile,
int data) { int data) {
if (doUpdate) { if (doUpdate) {
level->setTileAndData(x, y, z, tile, data); level->setTileAndData(x, y, z, tile, data, Tile::UPDATE_ALL);
} else { } else {
level->setTileAndDataNoUpdate(x, y, z, tile, data); level->setTileAndData(x, y, z, tile, data, Tile::UPDATE_CLIENTS);
} }
} }

View file

@ -17,6 +17,8 @@ public:
return false; return false;
} }
virtual void init(double V1, double V2, double V3) {}; virtual void init(double V1, double V2, double V3) {};
virtual void applyFeature(Level* level, Random* random, int xChunk,
int zChunk);
protected: protected:
virtual void placeBlock(Level* level, int x, int y, int z, int tile); virtual void placeBlock(Level* level, int x, int y, int z, int tile);

View file

@ -1,5 +1,6 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.dimension.h"
#include "FlowerFeature.h" #include "FlowerFeature.h"
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
@ -24,9 +25,11 @@ bool FlowerFeature::place(Level* level, Random* random, int x, int y, int z) {
int x2 = x + random->nextInt(8) - random->nextInt(8); int x2 = x + random->nextInt(8) - random->nextInt(8);
int y2 = y + random->nextInt(4) - random->nextInt(4); int y2 = y + random->nextInt(4) - random->nextInt(4);
int z2 = z + random->nextInt(8) - random->nextInt(8); int z2 = z + random->nextInt(8) - random->nextInt(8);
if (level->isEmptyTile(x2, y2, z2)) { if (level->isEmptyTile(x2, y2, z2) &&
(!level->dimension->hasCeiling || y2 < Level::genDepthMinusOne)) {
if (Tile::tiles[tile]->canSurvive(level, x2, y2, z2)) { if (Tile::tiles[tile]->canSurvive(level, x2, y2, z2)) {
level->setTileNoUpdate(x2, y2, z2, tile); level->setTileAndData(x2, y2, z2, tile, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }

View file

@ -4,8 +4,8 @@
#include "GroundBushFeature.h" #include "GroundBushFeature.h"
GroundBushFeature::GroundBushFeature(int trunkType, int leafType) { GroundBushFeature::GroundBushFeature(int trunkType, int leafType) {
this->trunkTileType = trunkType; trunkTileType = trunkType;
this->leafTileType = leafType; leafTileType = leafType;
} }
bool GroundBushFeature::place(Level* level, Random* random, int x, int y, bool GroundBushFeature::place(Level* level, Random* random, int x, int y,

View file

@ -9,8 +9,9 @@ bool HellFireFeature::place(Level* level, Random* random, int x, int y, int z) {
int y2 = y + random->nextInt(4) - random->nextInt(4); int y2 = y + random->nextInt(4) - random->nextInt(4);
int z2 = z + random->nextInt(8) - random->nextInt(8); int z2 = z + random->nextInt(8) - random->nextInt(8);
if (!level->isEmptyTile(x2, y2, z2)) continue; if (!level->isEmptyTile(x2, y2, z2)) continue;
if (level->getTile(x2, y2 - 1, z2) != Tile::hellRock_Id) continue; if (level->getTile(x2, y2 - 1, z2) != Tile::netherRack_Id) continue;
level->setTile(x2, y2, z2, Tile::fire_Id); level->setTileAndData(x2, y2, z2, Tile::fire_Id, 0,
Tile::UPDATE_CLIENTS);
} }
return true; return true;

View file

@ -6,8 +6,8 @@
bool HellPortalFeature::place(Level* level, Random* random, int x, int y, bool HellPortalFeature::place(Level* level, Random* random, int x, int y,
int z) { int z) {
if (!level->isEmptyTile(x, y, z)) return false; if (!level->isEmptyTile(x, y, z)) return false;
if (level->getTile(x, y + 1, z) != Tile::hellRock_Id) return false; if (level->getTile(x, y + 1, z) != Tile::netherRack_Id) return false;
level->setTile(x, y, z, Tile::lightGem_Id); level->setTileAndData(x, y, z, Tile::glowstone_Id, 0, Tile::UPDATE_CLIENTS);
for (int i = 0; i < 1500; i++) { for (int i = 0; i < 1500; i++) {
int x2 = x + random->nextInt(8) - random->nextInt(8); int x2 = x + random->nextInt(8) - random->nextInt(8);
@ -25,10 +25,12 @@ bool HellPortalFeature::place(Level* level, Random* random, int x, int y,
if (t == 4) tile = level->getTile(x2, y2, z2 - 1); if (t == 4) tile = level->getTile(x2, y2, z2 - 1);
if (t == 5) tile = level->getTile(x2, y2, z2 + 1); if (t == 5) tile = level->getTile(x2, y2, z2 + 1);
if (tile == Tile::lightGem_Id) count++; if (tile == Tile::glowstone_Id) count++;
} }
if (count == 1) level->setTile(x2, y2, z2, Tile::lightGem_Id); if (count == 1)
level->setTileAndData(x2, y2, z2, Tile::glowstone_Id, 0,
Tile::UPDATE_CLIENTS);
} }
return true; return true;

View file

@ -3,23 +3,26 @@
#include "HellSpringFeature.h" #include "HellSpringFeature.h"
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
HellSpringFeature::HellSpringFeature(int tile) { this->tile = tile; } HellSpringFeature::HellSpringFeature(int tile, bool insideRock) {
this->tile = tile;
this->insideRock = insideRock;
}
bool HellSpringFeature::place(Level* level, Random* random, int x, int y, bool HellSpringFeature::place(Level* level, Random* random, int x, int y,
int z) { int z) {
if (level->getTile(x, y + 1, z) != Tile::hellRock_Id) return false; if (level->getTile(x, y + 1, z) != Tile::netherRack_Id) return false;
if (level->getTile(x, y - 1, z) != Tile::hellRock_Id) return false; if (level->getTile(x, y - 1, z) != Tile::netherRack_Id) return false;
if (level->getTile(x, y, z) != 0 && if (level->getTile(x, y, z) != 0 &&
level->getTile(x, y, z) != Tile::hellRock_Id) level->getTile(x, y, z) != Tile::netherRack_Id)
return false; return false;
int rockCount = 0; int rockCount = 0;
if (level->getTile(x - 1, y, z) == Tile::hellRock_Id) rockCount++; if (level->getTile(x - 1, y, z) == Tile::netherRack_Id) rockCount++;
if (level->getTile(x + 1, y, z) == Tile::hellRock_Id) rockCount++; if (level->getTile(x + 1, y, z) == Tile::netherRack_Id) rockCount++;
if (level->getTile(x, y, z - 1) == Tile::hellRock_Id) rockCount++; if (level->getTile(x, y, z - 1) == Tile::netherRack_Id) rockCount++;
if (level->getTile(x, y, z + 1) == Tile::hellRock_Id) rockCount++; if (level->getTile(x, y, z + 1) == Tile::netherRack_Id) rockCount++;
if (level->getTile(x, y - 1, z) == Tile::hellRock_Id) rockCount++; if (level->getTile(x, y - 1, z) == Tile::netherRack_Id) rockCount++;
int holeCount = 0; int holeCount = 0;
if (level->isEmptyTile(x - 1, y, z)) holeCount++; if (level->isEmptyTile(x - 1, y, z)) holeCount++;
@ -28,8 +31,8 @@ bool HellSpringFeature::place(Level* level, Random* random, int x, int y,
if (level->isEmptyTile(x, y, z + 1)) holeCount++; if (level->isEmptyTile(x, y, z + 1)) holeCount++;
if (level->isEmptyTile(x, y - 1, z)) holeCount++; if (level->isEmptyTile(x, y - 1, z)) holeCount++;
if (rockCount == 4 && holeCount == 1) { if ((!insideRock && rockCount == 4 && holeCount == 1) || rockCount == 5) {
level->setTile(x, y, z, tile); level->setTileAndData(x, y, z, tile, 0, Tile::UPDATE_CLIENTS);
level->setInstaTick(true); level->setInstaTick(true);
Tile::tiles[tile]->tick(level, x, y, z, random); Tile::tiles[tile]->tick(level, x, y, z, random);
level->setInstaTick(false); level->setInstaTick(false);

View file

@ -4,9 +4,10 @@
class HellSpringFeature : public Feature { class HellSpringFeature : public Feature {
private: private:
int tile; int tile;
bool insideRock;
public: public:
HellSpringFeature(int tile); HellSpringFeature(int tile, bool insideRock);
virtual bool place(Level* level, Random* random, int x, int y, int z); virtual bool place(Level* level, Random* random, int x, int y, int z);
}; };

View file

@ -6,9 +6,8 @@
#include "../../Headers/net.minecraft.world.item.h" #include "../../Headers/net.minecraft.world.item.h"
bool HouseFeature::place(Level* level, Random* random, int x, int y, int z) { bool HouseFeature::place(Level* level, Random* random, int x, int y, int z) {
while (y > 0 && !level->getMaterial(x, y - 1, z)->blocksMotion()) { while (y > 0 && !level->getMaterial(x, y - 1, z)->blocksMotion()) y--;
y--;
}
int w = random->nextInt(7) + 7; int w = random->nextInt(7) + 7;
int h = 4 + random->nextInt(3) / 2; int h = 4 + random->nextInt(3) / 2;
int d = random->nextInt(7) + 7; int d = random->nextInt(7) + 7;
@ -37,7 +36,7 @@ bool HouseFeature::place(Level* level, Random* random, int x, int y, int z) {
if (ok) { if (ok) {
if (t != 0) return false; if (t != 0) return false;
} else { } else {
if (t == Tile::stoneBrick_Id || t == Tile::mossStone_Id) if (t == Tile::cobblestone_Id || t == Tile::mossyCobblestone_Id)
return false; return false;
} }
} }
@ -88,14 +87,15 @@ bool HouseFeature::place(Level* level, Random* random, int x, int y, int z) {
if (yy == y0 - 1 || yy == y0 + h - 1 || xx == xx0 || if (yy == y0 - 1 || yy == y0 + h - 1 || xx == xx0 ||
zz == zz0 || xx == xx1 || zz == zz1) { zz == zz0 || xx == xx1 || zz == zz1) {
if (yy <= y0 + random->nextInt(3)) if (yy <= y0 + random->nextInt(3))
material = Tile::mossStone_Id; material = Tile::mossyCobblestone_Id;
else else
material = Tile::stoneBrick_Id; material = Tile::cobblestone_Id;
} }
} }
if (material >= 0) { if (material >= 0) {
level->setTileNoUpdate(xx, yy, zz, material); level->setTileAndData(xx, yy, zz, material, 0,
Tile::UPDATE_CLIENTS);
} }
} }
h = ho; h = ho;
@ -108,8 +108,8 @@ bool HouseFeature::place(Level* level, Random* random, int x, int y, int z) {
if (doorSide == 1) xx = x0 + w - 1; if (doorSide == 1) xx = x0 + w - 1;
if (doorSide == 2) zz = z0; if (doorSide == 2) zz = z0;
if (doorSide == 3) zz = z0 + d - 1; if (doorSide == 3) zz = z0 + d - 1;
level->setTileNoUpdate(xx, y0, zz, 0); level->setTileAndData(xx, y0, zz, 0, 0, Tile::UPDATE_CLIENTS);
level->setTileNoUpdate(xx, y0 + 1, zz, 0); level->setTileAndData(xx, y0 + 1, zz, 0, 0, Tile::UPDATE_CLIENTS);
int dir = 0; int dir = 0;
if (doorSide == 0) dir = 0; if (doorSide == 0) dir = 0;
@ -139,7 +139,8 @@ bool HouseFeature::place(Level* level, Random* random, int x, int y, int z) {
level->isSolidBlockingTile(xx, y0 + 1, zz + 1)) level->isSolidBlockingTile(xx, y0 + 1, zz + 1))
count++; count++;
if (count == 1) { if (count == 1) {
level->setTileNoUpdate(xx, y0 + 1, zz, Tile::glass_Id); level->setTileAndData(xx, y0 + 1, zz, Tile::glass_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }
@ -158,7 +159,8 @@ bool HouseFeature::place(Level* level, Random* random, int x, int y, int z) {
if (level->isSolidBlockingTile(xx, yy + 2, zz - 1)) count++; if (level->isSolidBlockingTile(xx, yy + 2, zz - 1)) count++;
if (level->isSolidBlockingTile(xx, yy + 2, zz + 1)) count++; if (level->isSolidBlockingTile(xx, yy + 2, zz + 1)) count++;
if (count == 1) { if (count == 1) {
level->setTileNoUpdate(xx, y0 + 2, zz, Tile::torch_Id); level->setTileAndData(xx, y0 + 2, zz, Tile::torch_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }
@ -169,4 +171,4 @@ bool HouseFeature::place(Level* level, Random* random, int x, int y, int z) {
level->addEntity(pz); level->addEntity(pz);
return true; return true;
} }

View file

@ -46,10 +46,6 @@ bool HugeMushroomFeature::place(Level* level, Random* random, int x, int y,
if (!free) return false; if (!free) return false;
// if (!Tile::mushroom1->mayPlace(level, x, y, z)) return false;
// placeBlock(level, x, y - 1, z, Tile::dirt_Id, 0);
int low = y + treeHeight; int low = y + treeHeight;
if (type == 1) { if (type == 1) {
low = y + treeHeight - 3; low = y + treeHeight - 3;
@ -87,7 +83,7 @@ bool HugeMushroomFeature::place(Level* level, Random* random, int x, int y,
if (data != 0 || y >= y + treeHeight - 1) { if (data != 0 || y >= y + treeHeight - 1) {
if (!Tile::solid[level->getTile(xx, yy, zz)]) if (!Tile::solid[level->getTile(xx, yy, zz)])
placeBlock(level, xx, yy, zz, placeBlock(level, xx, yy, zz,
Tile::hugeMushroom1_Id + type, data); Tile::hugeMushroom_brown_Id + type, data);
} }
} }
} }
@ -95,7 +91,8 @@ bool HugeMushroomFeature::place(Level* level, Random* random, int x, int y,
for (int hh = 0; hh < treeHeight; hh++) { for (int hh = 0; hh < treeHeight; hh++) {
int t = level->getTile(x, y + hh, z); int t = level->getTile(x, y + hh, z);
if (!Tile::solid[t]) if (!Tile::solid[t])
placeBlock(level, x, y + hh, z, Tile::hugeMushroom1_Id + type, 10); placeBlock(level, x, y + hh, z, Tile::hugeMushroom_brown_Id + type,
10);
} }
return true; return true;
} }

View file

@ -9,9 +9,7 @@ LakeFeature::LakeFeature(int tile) { this->tile = tile; }
bool LakeFeature::place(Level* level, Random* random, int x, int y, int z) { bool LakeFeature::place(Level* level, Random* random, int x, int y, int z) {
x -= 8; x -= 8;
z -= 8; z -= 8;
while (y > 5 && level->isEmptyTile(x, y, z)) { while (y > 5 && level->isEmptyTile(x, y, z)) y--;
y--;
}
if (y <= 4) { if (y <= 4) {
return false; return false;
} }
@ -69,8 +67,8 @@ bool LakeFeature::place(Level* level, Random* random, int x, int y, int z) {
for (int yy = 0; yy < 8; yy++) { for (int yy = 0; yy < 8; yy++) {
bool check = bool check =
!grid[((xx) * 16 + (zz)) * 8 + (yy)] && !grid[((xx) * 16 + (zz)) * 8 + (yy)] &&
((xx < 15 && grid[((xx + 1) * 16 + (zz)) * 8 + (yy)]) || ((xx < 15 && grid[((xx + 1) * 16 + (zz)) * 8 + (yy)]) //
(xx > 0 && grid[((xx - 1) * 16 + (zz)) * 8 + (yy)]) || || (xx > 0 && grid[((xx - 1) * 16 + (zz)) * 8 + (yy)]) ||
(zz < 15 && grid[((xx) * 16 + (zz + 1)) * 8 + (yy)]) || (zz < 15 && grid[((xx) * 16 + (zz + 1)) * 8 + (yy)]) ||
(zz > 0 && grid[((xx) * 16 + (zz - 1)) * 8 + (yy)]) || (zz > 0 && grid[((xx) * 16 + (zz - 1)) * 8 + (yy)]) ||
(yy < 7 && grid[((xx) * 16 + (zz)) * 8 + (yy + 1)]) || (yy < 7 && grid[((xx) * 16 + (zz)) * 8 + (yy + 1)]) ||
@ -92,8 +90,9 @@ bool LakeFeature::place(Level* level, Random* random, int x, int y, int z) {
for (int zz = 0; zz < 16; zz++) { for (int zz = 0; zz < 16; zz++) {
for (int yy = 0; yy < 8; yy++) { for (int yy = 0; yy < 8; yy++) {
if (grid[((xx) * 16 + (zz)) * 8 + (yy)]) { if (grid[((xx) * 16 + (zz)) * 8 + (yy)]) {
level->setTileNoUpdate(x + xx, y + yy, z + zz, level->setTileAndData(x + xx, y + yy, z + zz,
yy >= 4 ? 0 : tile); yy >= 4 ? 0 : tile, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }
@ -109,11 +108,13 @@ bool LakeFeature::place(Level* level, Random* random, int x, int y, int z) {
z + zz) > 0) { z + zz) > 0) {
Biome* b = level->getBiome(x + xx, z + zz); Biome* b = level->getBiome(x + xx, z + zz);
if (b->topMaterial == Tile::mycel_Id) if (b->topMaterial == Tile::mycel_Id)
level->setTileNoUpdate(x + xx, y + yy - 1, z + zz, level->setTileAndData(x + xx, y + yy - 1, z + zz,
Tile::mycel_Id); Tile::mycel_Id, 0,
Tile::UPDATE_CLIENTS);
else else
level->setTileNoUpdate(x + xx, y + yy - 1, z + zz, level->setTileAndData(x + xx, y + yy - 1, z + zz,
Tile::grass_Id); Tile::grass_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }
@ -142,8 +143,9 @@ bool LakeFeature::place(Level* level, Random* random, int x, int y, int z) {
if ((yy < 4 || random->nextInt(2) != 0) && if ((yy < 4 || random->nextInt(2) != 0) &&
level->getMaterial(x + xx, y + yy, z + zz) level->getMaterial(x + xx, y + yy, z + zz)
->isSolid()) { ->isSolid()) {
level->setTileNoUpdate(x + xx, y + yy, z + zz, level->setTileAndData(x + xx, y + yy, z + zz,
Tile::rock_Id); Tile::stone_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }
@ -157,11 +159,11 @@ bool LakeFeature::place(Level* level, Random* random, int x, int y, int z) {
for (int zz = 0; zz < 16; zz++) { for (int zz = 0; zz < 16; zz++) {
int yy = 4; int yy = 4;
if (level->shouldFreezeIgnoreNeighbors(x + xx, y + yy, z + zz)) if (level->shouldFreezeIgnoreNeighbors(x + xx, y + yy, z + zz))
level->setTileNoUpdate(x + xx, y + yy, z + zz, level->setTileAndData(x + xx, y + yy, z + zz, Tile::ice_Id,
Tile::ice_Id); 0, Tile::UPDATE_CLIENTS);
} }
} }
} }
return true; return true;
} }

View file

@ -135,7 +135,7 @@ void LargeCaveFeature::addTunnel(int64_t seed, int xOffs, int zOffs,
if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) { if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) {
int block = blocks[p]; int block = blocks[p];
if (block == Tile::grass_Id) hasGrass = true; if (block == Tile::grass_Id) hasGrass = true;
if (block == Tile::rock_Id || if (block == Tile::stone_Id ||
block == Tile::dirt_Id || block == Tile::dirt_Id ||
block == Tile::grass_Id) { block == Tile::grass_Id) {
if (yy < 10) { if (yy < 10) {

View file

@ -28,4 +28,4 @@ void LargeFeature::apply(ChunkSource* ChunkSource, Level* level, int xOffs,
addFeature(level, x, z, xOffs, zOffs, blocks); addFeature(level, x, z, xOffs, zOffs, blocks);
} }
} }
} }

View file

@ -22,4 +22,4 @@ public:
protected: protected:
virtual void addFeature(Level* level, int x, int z, int xOffs, int zOffs, virtual void addFeature(Level* level, int x, int z, int xOffs, int zOffs,
byteArray blocks) {} byteArray blocks) {}
}; };

View file

@ -3,14 +3,16 @@
#include "LargeHellCaveFeature.h" #include "LargeHellCaveFeature.h"
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
void LargeHellCaveFeature::addRoom(int xOffs, int zOffs, byteArray blocks, void LargeHellCaveFeature::addRoom(int64_t seed, int xOffs, int zOffs,
double xRoom, double yRoom, double zRoom) { byteArray blocks, double xRoom, double yRoom,
addTunnel(xOffs, zOffs, blocks, xRoom, yRoom, zRoom, double zRoom) {
addTunnel(seed, xOffs, zOffs, blocks, xRoom, yRoom, zRoom,
1 + random->nextFloat() * 6, 0, 0, -1, -1, 0.5); 1 + random->nextFloat() * 6, 0, 0, -1, -1, 0.5);
} }
void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks, void LargeHellCaveFeature::addTunnel(int64_t seed, int xOffs, int zOffs,
double xCave, double yCave, double zCave, byteArray blocks, double xCave,
double yCave, double zCave,
float thickness, float yRot, float xRot, float thickness, float yRot, float xRot,
int step, int dist, double yScale) { int step, int dist, double yScale) {
double xMid = xOffs * 16 + 8; double xMid = xOffs * 16 + 8;
@ -18,11 +20,11 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks,
float yRota = 0; float yRota = 0;
float xRota = 0; float xRota = 0;
Random* random = new Random(this->random->nextLong()); Random random(seed);
if (dist <= 0) { if (dist <= 0) {
int max = radius * 16 - 16; int max = radius * 16 - 16;
dist = max - random->nextInt(max / 4); dist = max - random.nextInt(max / 4);
} }
bool singleStep = false; bool singleStep = false;
@ -31,8 +33,8 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks,
singleStep = true; singleStep = true;
} }
int splitPoint = random->nextInt(dist / 2) + dist / 4; int splitPoint = random.nextInt(dist / 2) + dist / 4;
bool steep = random->nextInt(6) == 0; bool steep = random.nextInt(6) == 0;
for (; step < dist; step++) { for (; step < dist; step++) {
double rad = 1.5 + (Mth::sin(step * PI / dist) * thickness) * 1; double rad = 1.5 + (Mth::sin(step * PI / dist) * thickness) * 1;
@ -54,22 +56,21 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks,
xRota *= 0.90f; xRota *= 0.90f;
yRota *= 0.75f; yRota *= 0.75f;
xRota += (random->nextFloat() - random->nextFloat()) * xRota +=
random->nextFloat() * 2; (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2;
yRota += (random->nextFloat() - random->nextFloat()) * yRota +=
random->nextFloat() * 4; (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4;
if (!singleStep && step == splitPoint && thickness > 1) { if (!singleStep && step == splitPoint && thickness > 1) {
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, addTunnel(random.nextLong(), xOffs, zOffs, blocks, xCave, yCave,
random->nextFloat() * 0.5f + 0.5f, yRot - PI / 2, zCave, random.nextFloat() * 0.5f + 0.5f, yRot - PI / 2,
xRot / 3, step, dist, 1.0); xRot / 3, step, dist, 1.0);
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, addTunnel(random.nextLong(), xOffs, zOffs, blocks, xCave, yCave,
random->nextFloat() * 0.5f + 0.5f, yRot + PI / 2, zCave, random.nextFloat() * 0.5f + 0.5f, yRot + PI / 2,
xRot / 3, step, dist, 1.0); xRot / 3, step, dist, 1.0);
delete random;
return; return;
} }
if (!singleStep && random->nextInt(4) == 0) continue; if (!singleStep && random.nextInt(4) == 0) continue;
{ {
double xd = xCave - xMid; double xd = xCave - xMid;
@ -77,7 +78,6 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks,
double remaining = dist - step; double remaining = dist - step;
double rr = (thickness + 2) + 16; double rr = (thickness + 2) + 16;
if (xd * xd + zd * zd - (remaining * remaining) > rr * rr) { if (xd * xd + zd * zd - (remaining * remaining) > rr * rr) {
delete random;
return; return;
} }
} }
@ -132,7 +132,7 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks,
double yd = (yy + 0.5 - yCave) / yRad; double yd = (yy + 0.5 - yCave) / yRad;
if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) { if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) {
int block = blocks[p]; int block = blocks[p];
if (block == Tile::hellRock_Id || if (block == Tile::netherRack_Id ||
block == Tile::dirt_Id || block == Tile::grass_Id) { block == Tile::dirt_Id || block == Tile::grass_Id) {
blocks[p] = (uint8_t)0; blocks[p] = (uint8_t)0;
} }
@ -143,7 +143,6 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks,
} }
if (singleStep) break; if (singleStep) break;
} }
delete random;
} }
void LargeHellCaveFeature::addFeature(Level* level, int x, int z, int xOffs, void LargeHellCaveFeature::addFeature(Level* level, int x, int z, int xOffs,
@ -158,7 +157,8 @@ void LargeHellCaveFeature::addFeature(Level* level, int x, int z, int xOffs,
int tunnels = 1; int tunnels = 1;
if (random->nextInt(4) == 0) { if (random->nextInt(4) == 0) {
addRoom(xOffs, zOffs, blocks, xCave, yCave, zCave); addRoom(random->nextLong(), xOffs, zOffs, blocks, xCave, yCave,
zCave);
tunnels += random->nextInt(4); tunnels += random->nextInt(4);
} }
@ -167,8 +167,8 @@ void LargeHellCaveFeature::addFeature(Level* level, int x, int z, int xOffs,
float xRot = ((random->nextFloat() - 0.5f) * 2) / 8; float xRot = ((random->nextFloat() - 0.5f) * 2) / 8;
float thickness = random->nextFloat() * 2 + random->nextFloat(); float thickness = random->nextFloat() * 2 + random->nextFloat();
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, thickness * 2, addTunnel(random->nextLong(), xOffs, zOffs, blocks, xCave, yCave,
yRot, xRot, 0, 0, 0.5); zCave, thickness * 2, yRot, xRot, 0, 0, 0.5);
} }
} }
} }

View file

@ -4,11 +4,11 @@
class LargeHellCaveFeature : public LargeFeature { class LargeHellCaveFeature : public LargeFeature {
protected: protected:
void addRoom(int xOffs, int zOffs, byteArray blocks, double xRoom, void addRoom(int64_t seed, int xOffs, int zOffs, byteArray blocks,
double yRoom, double zRoom); double xRoom, double yRoom, double zRoom);
void addTunnel(int xOffs, int zOffs, byteArray blocks, double xCave, void addTunnel(int64_t seed, int xOffs, int zOffs, byteArray blocks,
double yCave, double zCave, float thickness, float yRot, double xCave, double yCave, double zCave, float thickness,
float xRot, int step, int dist, double yScale); float yRot, float xRot, int step, int dist, double yScale);
virtual void addFeature(Level* level, int x, int z, int xOffs, int zOffs, virtual void addFeature(Level* level, int x, int z, int xOffs, int zOffs,
byteArray blocks); byteArray blocks);
}; };

View file

@ -5,8 +5,8 @@
bool LightGemFeature::place(Level* level, Random* random, int x, int y, int z) { bool LightGemFeature::place(Level* level, Random* random, int x, int y, int z) {
if (!level->isEmptyTile(x, y, z)) return false; if (!level->isEmptyTile(x, y, z)) return false;
if (level->getTile(x, y + 1, z) != Tile::hellRock_Id) return false; if (level->getTile(x, y + 1, z) != Tile::netherRack_Id) return false;
level->setTile(x, y, z, Tile::lightGem_Id); level->setTileAndData(x, y, z, Tile::glowstone_Id, 0, Tile::UPDATE_CLIENTS);
for (int i = 0; i < 1500; i++) { for (int i = 0; i < 1500; i++) {
int x2 = x + random->nextInt(8) - random->nextInt(8); int x2 = x + random->nextInt(8) - random->nextInt(8);
@ -24,10 +24,12 @@ bool LightGemFeature::place(Level* level, Random* random, int x, int y, int z) {
if (t == 4) tile = level->getTile(x2, y2, z2 - 1); if (t == 4) tile = level->getTile(x2, y2, z2 - 1);
if (t == 5) tile = level->getTile(x2, y2, z2 + 1); if (t == 5) tile = level->getTile(x2, y2, z2 + 1);
if (tile == Tile::lightGem_Id) count++; if (tile == Tile::glowstone_Id) count++;
} }
if (count == 1) level->setTile(x2, y2, z2, Tile::lightGem_Id); if (count == 1)
level->setTileAndData(x2, y2, z2, Tile::glowstone_Id, 0,
Tile::UPDATE_CLIENTS);
} }
return true; return true;

View file

@ -58,10 +58,13 @@ bool MegaTreeFeature::place(Level* level, Random* random, int x, int y, int z) {
y >= Level::maxBuildHeight - treeHeight - 1) y >= Level::maxBuildHeight - treeHeight - 1)
return false; return false;
level->setTileNoUpdate(x, y - 1, z, Tile::dirt_Id); level->setTileAndData(x, y - 1, z, Tile::dirt_Id, 0, Tile::UPDATE_CLIENTS);
level->setTileNoUpdate(x + 1, y - 1, z, Tile::dirt_Id); level->setTileAndData(x + 1, y - 1, z, Tile::dirt_Id, 0,
level->setTileNoUpdate(x, y - 1, z + 1, Tile::dirt_Id); Tile::UPDATE_CLIENTS);
level->setTileNoUpdate(x + 1, y - 1, z + 1, Tile::dirt_Id); level->setTileAndData(x, y - 1, z + 1, Tile::dirt_Id, 0,
Tile::UPDATE_CLIENTS);
level->setTileAndData(x + 1, y - 1, z + 1, Tile::dirt_Id, 0,
Tile::UPDATE_CLIENTS);
PIXBeginNamedEvent(0, "MegaTree placing leaves, %d, %d, %d", x, z, PIXBeginNamedEvent(0, "MegaTree placing leaves, %d, %d, %d", x, z,
y + treeHeight); y + treeHeight);
@ -191,7 +194,7 @@ void MegaTreeFeature::placeLeaves(Level* level, int x, int z, int topPosition,
PIXBeginNamedEvent(0, "Getting tile"); PIXBeginNamedEvent(0, "Getting tile");
int t = level->getTile(xx, yy, zz); int t = level->getTile(xx, yy, zz);
PIXEndNamedEvent(); PIXEndNamedEvent();
if (!Tile::solid[t]) { if (t == 0 || t == Tile::leaves_Id) {
PIXBeginNamedEvent(0, "Placing block"); PIXBeginNamedEvent(0, "Placing block");
placeBlock(level, xx, yy, zz, Tile::leaves_Id, leafType); placeBlock(level, xx, yy, zz, Tile::leaves_Id, leafType);
PIXEndNamedEvent(); PIXEndNamedEvent();

View file

@ -1,6 +1,24 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.world.level.levelgen.structure.h" #include "../../Headers/net.minecraft.world.level.levelgen.structure.h"
#include "../../Util/JavaMath.h" #include "../../Util/JavaMath.h"
#include "../../Util/Mth.h"
const std::wstring MineShaftFeature::OPTION_CHANCE = L"chance";
MineShaftFeature::MineShaftFeature() { chance = 0.01; }
std::wstring MineShaftFeature::getFeatureName() { return L"Mineshaft"; }
MineShaftFeature::MineShaftFeature(
std::unordered_map<std::wstring, std::wstring> options) {
chance = 0.01;
for (AUTO_VAR(it, options.begin()); it != options.end(); ++it) {
if (it->first.compare(OPTION_CHANCE) == 0) {
chance = Mth::getDouble(it->second, chance);
}
}
}
bool MineShaftFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) { bool MineShaftFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) {
bool forcePlacement = false; bool forcePlacement = false;
@ -10,7 +28,7 @@ bool MineShaftFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) {
levelGenOptions->isFeatureChunk(x, z, eFeature_Mineshaft); levelGenOptions->isFeatureChunk(x, z, eFeature_Mineshaft);
} }
return forcePlacement || (random->nextInt(100) == 0 && return forcePlacement || (random->nextDouble() < chance &&
random->nextInt(80) < std::max(abs(x), abs(z))); random->nextInt(80) < std::max(abs(x), abs(z)));
} }

View file

@ -3,6 +3,19 @@
#include "StructureFeature.h" #include "StructureFeature.h"
class MineShaftFeature : public StructureFeature { class MineShaftFeature : public StructureFeature {
public:
static const std::wstring OPTION_CHANCE;
private:
double chance;
public:
MineShaftFeature();
std::wstring getFeatureName();
MineShaftFeature(std::unordered_map<std::wstring, std::wstring> options);
protected: protected:
virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false); virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false);
virtual StructureStart* createStructureStart(int x, int z); virtual StructureStart* createStructureStart(int x, int z);

View file

@ -4,8 +4,28 @@
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
#include "../../Headers/net.minecraft.world.level.tile.entity.h" #include "../../Headers/net.minecraft.world.level.tile.entity.h"
#include "../../Headers/net.minecraft.world.item.h" #include "../../Headers/net.minecraft.world.item.h"
#include "../../Util/WeighedTreasure.h"
#include "MonsterRoomFeature.h" #include "MonsterRoomFeature.h"
WeighedTreasure* MonsterRoomFeature::monsterRoomTreasure
[MonsterRoomFeature::TREASURE_ITEMS_COUNT] = {
new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 10),
new WeighedTreasure(Item::ironIngot_Id, 0, 1, 4, 10),
new WeighedTreasure(Item::bread_Id, 0, 1, 1, 10),
new WeighedTreasure(Item::wheat_Id, 0, 1, 4, 10),
new WeighedTreasure(Item::gunpowder_Id, 0, 1, 4, 10),
new WeighedTreasure(Item::string_Id, 0, 1, 4, 10),
new WeighedTreasure(Item::bucket_empty_Id, 0, 1, 1, 10),
new WeighedTreasure(Item::apple_gold_Id, 0, 1, 1, 1),
new WeighedTreasure(Item::redStone_Id, 0, 1, 4, 10),
new WeighedTreasure(Item::record_01_Id, 0, 1, 1, 10),
new WeighedTreasure(Item::record_02_Id, 0, 1, 1, 10),
new WeighedTreasure(Item::nameTag_Id, 0, 1, 1, 10),
new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 2),
new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 5),
new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1),
};
bool MonsterRoomFeature::place(Level* level, Random* random, int x, int y, bool MonsterRoomFeature::place(Level* level, Random* random, int x, int y,
int z) { int z) {
int hr = 3; int hr = 3;
@ -40,16 +60,20 @@ bool MonsterRoomFeature::place(Level* level, Random* random, int x, int y,
xx == x + xr + 1 || yy == y + hr + 1 || zz == z + zr + 1) { xx == x + xr + 1 || yy == y + hr + 1 || zz == z + zr + 1) {
if (yy >= 0 && if (yy >= 0 &&
!level->getMaterial(xx, yy - 1, zz)->isSolid()) { !level->getMaterial(xx, yy - 1, zz)->isSolid()) {
level->setTile(xx, yy, zz, 0); level->removeTile(xx, yy, zz);
} else if (level->getMaterial(xx, yy, zz)->isSolid()) { } else if (level->getMaterial(xx, yy, zz)->isSolid()) {
if (yy == y - 1 && random->nextInt(4) != 0) { if (yy == y - 1 && random->nextInt(4) != 0) {
level->setTile(xx, yy, zz, Tile::mossStone_Id); level->setTileAndData(xx, yy, zz,
Tile::mossyCobblestone_Id, 0,
Tile::UPDATE_CLIENTS);
} else { } else {
level->setTile(xx, yy, zz, Tile::stoneBrick_Id); level->setTileAndData(xx, yy, zz,
Tile::cobblestone_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} else { } else {
level->setTile(xx, yy, zz, 0); level->removeTile(xx, yy, zz);
} }
} }
} }
@ -70,72 +94,36 @@ bool MonsterRoomFeature::place(Level* level, Random* random, int x, int y,
if (count != 1) continue; if (count != 1) continue;
level->setTile(xc, yc, zc, Tile::chest_Id); level->setTileAndData(xc, yc, zc, Tile::chest_Id, 0,
Tile::UPDATE_CLIENTS);
WeighedTreasureArray wrapperArray(monsterRoomTreasure,
TREASURE_ITEMS_COUNT);
WeighedTreasureArray treasure = WeighedTreasure::addToTreasure(
wrapperArray,
Item::enchantedBook->createForRandomTreasure(random));
std::shared_ptr<ChestTileEntity> chest = std::shared_ptr<ChestTileEntity> chest =
std::dynamic_pointer_cast<ChestTileEntity>( std::dynamic_pointer_cast<ChestTileEntity>(
level->getTileEntity(xc, yc, zc)); level->getTileEntity(xc, yc, zc));
if (chest != NULL) { if (chest != NULL) {
for (int j = 0; j < 8; j++) { WeighedTreasure::addChestItems(random, treasure, chest, 8);
std::shared_ptr<ItemInstance> item = randomItem(random);
if (item != NULL)
chest->setItem(
random->nextInt(chest->getContainerSize()), item);
}
} }
break; break;
} }
} }
level->setTile(x, y, z, Tile::mobSpawner_Id); level->setTileAndData(x, y, z, Tile::mobSpawner_Id, 0,
Tile::UPDATE_CLIENTS);
std::shared_ptr<MobSpawnerTileEntity> entity = std::shared_ptr<MobSpawnerTileEntity> entity =
std::dynamic_pointer_cast<MobSpawnerTileEntity>( std::dynamic_pointer_cast<MobSpawnerTileEntity>(
level->getTileEntity(x, y, z)); level->getTileEntity(x, y, z));
if (entity != NULL) { if (entity != NULL) {
entity->setEntityId(randomEntityId(random)); entity->getSpawner()->setEntityId(randomEntityId(random));
} }
return true; return true;
} }
std::shared_ptr<ItemInstance> MonsterRoomFeature::randomItem(Random* random) {
int type = random->nextInt(12);
if (type == 0)
return std::shared_ptr<ItemInstance>(new ItemInstance(Item::saddle));
if (type == 1)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::ironIngot, random->nextInt(4) + 1));
if (type == 2)
return std::shared_ptr<ItemInstance>(new ItemInstance(Item::bread));
if (type == 3)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::wheat, random->nextInt(4) + 1));
if (type == 4)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::sulphur, random->nextInt(4) + 1));
if (type == 5)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::string, random->nextInt(4) + 1));
if (type == 6)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::bucket_empty));
if (type == 7 && random->nextInt(100) == 0)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::apple_gold));
if (type == 8 && random->nextInt(2) == 0)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::redStone, random->nextInt(4) + 1));
if (type == 9 && random->nextInt(10) == 0)
return std::shared_ptr<ItemInstance>(new ItemInstance(
Item::items[Item::record_01->id + random->nextInt(2)]));
if (type == 10)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::dye_powder, 1, DyePowderItem::BROWN));
if (type == 11) return Item::enchantedBook->createForRandomLoot(random);
return std::shared_ptr<ItemInstance>();
}
std::wstring MonsterRoomFeature::randomEntityId(Random* random) { std::wstring MonsterRoomFeature::randomEntityId(Random* random) {
int id = random->nextInt(4); int id = random->nextInt(4);
if (id == 0) return std::wstring(L"Skeleton"); if (id == 0) return std::wstring(L"Skeleton");

View file

@ -2,14 +2,16 @@
#include "Feature.h" #include "Feature.h"
#include "../../Blocks/Material.h" #include "../../Blocks/Material.h"
class WeighedTreasure;
class MonsterRoomFeature : public Feature { class MonsterRoomFeature : public Feature {
private: private:
// int tile; static const int TREASURE_ITEMS_COUNT = 15;
static WeighedTreasure* monsterRoomTreasure[TREASURE_ITEMS_COUNT];
public: public:
virtual bool place(Level* level, Random* random, int x, int y, int z); virtual bool place(Level* level, Random* random, int x, int y, int z);
private: private:
std::shared_ptr<ItemInstance> randomItem(Random* random);
std::wstring randomEntityId(Random* random); std::wstring randomEntityId(Random* random);
}; };

View file

@ -10,7 +10,9 @@
NetherBridgeFeature::NetherBridgeFeature() : StructureFeature() { NetherBridgeFeature::NetherBridgeFeature() : StructureFeature() {
bridgeEnemies.push_back(new Biome::MobSpawnerData(eTYPE_BLAZE, 10, 2, 3)); bridgeEnemies.push_back(new Biome::MobSpawnerData(eTYPE_BLAZE, 10, 2, 3));
bridgeEnemies.push_back( bridgeEnemies.push_back(
new Biome::MobSpawnerData(eTYPE_PIGZOMBIE, 10, 4, 4)); new Biome::MobSpawnerData(eTYPE_PIGZOMBIE, 5, 4, 4));
bridgeEnemies.push_back(
new Biome::MobSpawnerData(eTYPE_SKELETON, 10, 4, 4));
bridgeEnemies.push_back( bridgeEnemies.push_back(
new Biome::MobSpawnerData(eTYPE_LAVASLIME, 3, 4, 4)); new Biome::MobSpawnerData(eTYPE_LAVASLIME, 3, 4, 4));
isSpotSelected = false; isSpotSelected = false;
@ -21,6 +23,8 @@ NetherBridgeFeature::~NetherBridgeFeature() {
if (netherFortressPos != NULL) delete netherFortressPos; if (netherFortressPos != NULL) delete netherFortressPos;
} }
std::wstring NetherBridgeFeature::getFeatureName() { return L"Fortress"; }
std::vector<Biome::MobSpawnerData*>* NetherBridgeFeature::getBridgeEnemies() { std::vector<Biome::MobSpawnerData*>* NetherBridgeFeature::getBridgeEnemies() {
return &bridgeEnemies; return &bridgeEnemies;
} }
@ -89,11 +93,15 @@ StructureStart* NetherBridgeFeature::createStructureStart(int x, int z) {
void NetherBridgeFeature::clearCachedBuildings() { cachedStructures.clear(); } void NetherBridgeFeature::clearCachedBuildings() { cachedStructures.clear(); }
NetherBridgeFeature::NetherBridgeStart::NetherBridgeStart() {
// for reflection
}
NetherBridgeFeature::NetherBridgeStart::NetherBridgeStart(Level* level, NetherBridgeFeature::NetherBridgeStart::NetherBridgeStart(Level* level,
Random* random, Random* random,
int chunkX, int chunkX,
int chunkZ) int chunkZ)
: StructureStart() { : StructureStart(chunkX, chunkZ) {
NetherBridgePieces::StartPiece* start = new NetherBridgePieces::StartPiece( NetherBridgePieces::StartPiece* start = new NetherBridgePieces::StartPiece(
random, (chunkX << 4) + 2, (chunkZ << 4) + 2, level); random, (chunkX << 4) + 2, (chunkZ << 4) + 2, level);
pieces.push_back(start); pieces.push_back(start);

View file

@ -13,6 +13,7 @@ private:
public: public:
NetherBridgeFeature(); NetherBridgeFeature();
~NetherBridgeFeature(); ~NetherBridgeFeature();
std::wstring getFeatureName();
std::vector<Biome::MobSpawnerData*>* getBridgeEnemies(); std::vector<Biome::MobSpawnerData*>* getBridgeEnemies();
protected: protected:
@ -22,9 +23,15 @@ protected:
public: public:
void clearCachedBuildings(); void clearCachedBuildings();
private:
class NetherBridgeStart : public StructureStart { class NetherBridgeStart : public StructureStart {
public: public:
static StructureStart* Create() { return new NetherBridgeStart(); }
virtual EStructureStart GetType() {
return eStructureStart_NetherBridgeStart;
}
public:
NetherBridgeStart();
NetherBridgeStart(Level* level, Random* random, int chunkX, int chunkZ); NetherBridgeStart(Level* level, Random* random, int chunkX, int chunkZ);
}; };
}; };

View file

@ -10,7 +10,7 @@ void OreFeature::_init(int tile, int count, int targetTile) {
} }
OreFeature::OreFeature(int tile, int count) { OreFeature::OreFeature(int tile, int count) {
_init(tile, count, Tile::rock_Id); _init(tile, count, Tile::stone_Id);
} }
OreFeature::OreFeature(int tile, int count, int targetTile) { OreFeature::OreFeature(int tile, int count, int targetTile) {
@ -52,6 +52,11 @@ bool OreFeature::place(Level* level, Random* random, int x, int y, int z) {
maxX, maxY, maxZ); maxX, maxY, maxZ);
} }
bool doEarlyRejectTest = false;
if (y0 > level->getSeaLevel()) {
doEarlyRejectTest = true;
}
for (int d = 0; d <= count; d++) { for (int d = 0; d <= count; d++) {
double xx = x0 + (x1 - x0) * d / count; double xx = x0 + (x1 - x0) * d / count;
double yy = y0 + (y1 - y0) * d / count; double yy = y0 + (y1 - y0) * d / count;
@ -59,15 +64,18 @@ bool OreFeature::place(Level* level, Random* random, int x, int y, int z) {
double ss = random->nextDouble() * count / 16; double ss = random->nextDouble() * count / 16;
double r = (Mth::sin(d * PI / count) + 1) * ss + 1; double r = (Mth::sin(d * PI / count) + 1) * ss + 1;
double hr = (Mth::sin(d * PI / count) + 1) * ss + 1; double hr = r; //(Mth::sin(d * PI / count) + 1) * ss + 1;
int xt0 = Mth::floor(xx - r / 2); double halfR = r / 2;
int yt0 = Mth::floor(yy - hr / 2); double halfHR = halfR; // hr/2;
int zt0 = Mth::floor(zz - r / 2);
int xt1 = Mth::floor(xx + r / 2); int xt0 = Mth::floor(xx - halfR);
int yt1 = Mth::floor(yy + hr / 2); int yt0 = Mth::floor(yy - halfHR);
int zt1 = Mth::floor(zz + r / 2); int zt0 = Mth::floor(zz - halfR);
int xt1 = Mth::floor(xx + halfR);
int yt1 = Mth::floor(yy + halfHR);
int zt1 = Mth::floor(zz + halfR);
// 4J Stu Added to stop ore features generating areas previously place // 4J Stu Added to stop ore features generating areas previously place
// by game rule generation // by game rule generation
@ -86,31 +94,43 @@ bool OreFeature::place(Level* level, Random* random, int x, int y, int z) {
// placing in to see if we are going to (very probably) be entirely // placing in to see if we are going to (very probably) be entirely
// above the height stored in the heightmap // above the height stored in the heightmap
bool earlyReject = true; if (doEarlyRejectTest) {
if (level->getHeightmap(xt0, zt0) >= yt0) bool earlyReject = true;
earlyReject = false; if (level->getHeightmap(xt0, zt0) >= yt0)
else if (level->getHeightmap(xt1, zt0) >= yt0) earlyReject = false;
earlyReject = false; else if (level->getHeightmap(xt1, zt0) >= yt0)
else if (level->getHeightmap(xt0, zt1) >= yt0) earlyReject = false;
earlyReject = false; else if (level->getHeightmap(xt0, zt1) >= yt0)
else if (level->getHeightmap(xt1, zt1) >= yt0) earlyReject = false;
earlyReject = false; else if (level->getHeightmap(xt1, zt1) >= yt0)
earlyReject = false;
if (earlyReject) continue; if (earlyReject) continue;
}
for (int x2 = xt0; x2 <= xt1; x2++) { double xdxd, ydyd;
double xd = ((x2 + 0.5) - xx) / (r / 2);
if (xd * xd < 1) { double xd0 = ((xt0 + 0.5) - xx);
for (int y2 = yt0; y2 <= yt1; y2++) { double yd0 = ((yt0 + 0.5) - yy);
double yd = ((y2 + 0.5) - yy) / (hr / 2); double zd0 = ((zt0 + 0.5) - zz);
if (xd * xd + yd * yd < 1) {
for (int z2 = zt0; z2 <= zt1; z2++) { double halfRSq = halfR * halfR;
double zd = ((z2 + 0.5) - zz) / (r / 2);
if (xd * xd + yd * yd + zd * zd < 1) { double xd = xd0;
for (int x2 = xt0; x2 <= xt1; x2++, xd++) {
xdxd = xd * xd;
if (xdxd < halfRSq) {
double yd = yd0;
for (int y2 = yt0; y2 <= yt1; y2++, yd++) {
ydyd = yd * yd;
if (xdxd + ydyd < halfRSq) {
double zd = zd0;
for (int z2 = zt0; z2 <= zt1; z2++, zd++) {
if (xdxd + ydyd + zd * zd < halfRSq) {
if (level->getTile(x2, y2, z2) == targetTile) { if (level->getTile(x2, y2, z2) == targetTile) {
level->setTileNoUpdateNoLightCheck( level->setTileAndData(
x2, y2, z2, tile); // 4J changed from x2, y2, z2, tile, 0,
// setTileNoUpdate Tile::UPDATE_INVISIBLE_NO_LIGHT);
} }
} }
} }

View file

@ -11,8 +11,8 @@ bool PumpkinFeature::place(Level* level, Random* random, int x, int y, int z) {
if (level->isEmptyTile(x2, y2, z2) && if (level->isEmptyTile(x2, y2, z2) &&
level->getTile(x2, y2 - 1, z2) == Tile::grass_Id) { level->getTile(x2, y2 - 1, z2) == Tile::grass_Id) {
if (Tile::pumpkin->mayPlace(level, x2, y2, z2)) { if (Tile::pumpkin->mayPlace(level, x2, y2, z2)) {
level->setTileAndDataNoUpdate(x2, y2, z2, Tile::pumpkin_Id, level->setTileAndData(x2, y2, z2, Tile::pumpkin_Id,
random->nextInt(4)); random->nextInt(4), Tile::UPDATE_CLIENTS);
} }
} }
} }

View file

@ -1,37 +1,58 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.biome.h" #include "../../Headers/net.minecraft.world.level.biome.h"
#include "../../Headers/net.minecraft.world.level.levelgen.structure.h"
#include "../Structures/ScatteredFeaturePieces.h" #include "../Structures/ScatteredFeaturePieces.h"
#include "RandomScatteredLargeFeature.h" #include "RandomScatteredLargeFeature.h"
const std::wstring RandomScatteredLargeFeature::OPTION_SPACING = L"distance";
std::vector<Biome*> RandomScatteredLargeFeature::allowedBiomes; std::vector<Biome*> RandomScatteredLargeFeature::allowedBiomes;
void RandomScatteredLargeFeature::staticCtor() { void RandomScatteredLargeFeature::staticCtor() {
allowedBiomes.push_back(Biome::desert); allowedBiomes.push_back(Biome::desert);
allowedBiomes.push_back(Biome::desertHills); allowedBiomes.push_back(Biome::desertHills);
allowedBiomes.push_back(Biome::jungle); allowedBiomes.push_back(Biome::jungle);
allowedBiomes.push_back(Biome::jungleHills);
allowedBiomes.push_back(Biome::swampland);
} }
RandomScatteredLargeFeature::RandomScatteredLargeFeature() {} void RandomScatteredLargeFeature::_init() {
spacing = 32;
minSeparation = 8;
swamphutEnemies.push_back(new Biome::MobSpawnerData(eTYPE_WITCH, 1, 1, 1));
}
RandomScatteredLargeFeature::RandomScatteredLargeFeature() { _init(); }
RandomScatteredLargeFeature::RandomScatteredLargeFeature(
std::unordered_map<std::wstring, std::wstring> options) {
_init();
for (AUTO_VAR(it, options.begin()); it != options.end(); ++it) {
if (it->first.compare(OPTION_SPACING) == 0) {
spacing = Mth::getInt(it->second, spacing, minSeparation + 1);
}
}
}
std::wstring RandomScatteredLargeFeature::getFeatureName() { return L"Temple"; }
bool RandomScatteredLargeFeature::isFeatureChunk(int x, int z, bool RandomScatteredLargeFeature::isFeatureChunk(int x, int z,
bool bIsSuperflat) { bool bIsSuperflat) {
int featureSpacing = 32;
int minFeatureSeparation = 8;
int xx = x; int xx = x;
int zz = z; int zz = z;
if (x < 0) x -= featureSpacing - 1; if (x < 0) x -= spacing - 1;
if (z < 0) z -= featureSpacing - 1; if (z < 0) z -= spacing - 1;
int xCenterFeatureChunk = x / featureSpacing; int xCenterFeatureChunk = x / spacing;
int zCenterFeatureChunk = z / featureSpacing; int zCenterFeatureChunk = z / spacing;
Random* r = Random* r =
level->getRandomFor(xCenterFeatureChunk, zCenterFeatureChunk, 14357617); level->getRandomFor(xCenterFeatureChunk, zCenterFeatureChunk, 14357617);
xCenterFeatureChunk *= featureSpacing; xCenterFeatureChunk *= spacing;
zCenterFeatureChunk *= featureSpacing; zCenterFeatureChunk *= spacing;
xCenterFeatureChunk += r->nextInt(featureSpacing - minFeatureSeparation); xCenterFeatureChunk += r->nextInt(spacing - minSeparation);
zCenterFeatureChunk += r->nextInt(featureSpacing - minFeatureSeparation); zCenterFeatureChunk += r->nextInt(spacing - minSeparation);
x = xx; x = xx;
z = zz; z = zz;
@ -44,12 +65,14 @@ bool RandomScatteredLargeFeature::isFeatureChunk(int x, int z,
if (forcePlacement || if (forcePlacement ||
(x == xCenterFeatureChunk && z == zCenterFeatureChunk)) { (x == xCenterFeatureChunk && z == zCenterFeatureChunk)) {
bool biomeOk = level->getBiomeSource()->containsOnly( Biome* biome =
x * 16 + 8, z * 16 + 8, 0, allowedBiomes); level->getBiomeSource()->getBiome(x * 16 + 8, z * 16 + 8);
if (biomeOk) { for (AUTO_VAR(it, allowedBiomes.begin()); it != allowedBiomes.end();
// System.out.println("feature at " + (x * 16) + " " ++it) {
// + (z * 16)); Biome* a = *it;
return true; if (biome == a) {
return true;
}
} }
} }
@ -58,27 +81,51 @@ bool RandomScatteredLargeFeature::isFeatureChunk(int x, int z,
StructureStart* RandomScatteredLargeFeature::createStructureStart(int x, StructureStart* RandomScatteredLargeFeature::createStructureStart(int x,
int z) { int z) {
// System.out.println("feature at " + (x * 16) + " " + (z * 16));
return new ScatteredFeatureStart(level, random, x, z); return new ScatteredFeatureStart(level, random, x, z);
} }
RandomScatteredLargeFeature::ScatteredFeatureStart::ScatteredFeatureStart() {
// for reflection
}
RandomScatteredLargeFeature::ScatteredFeatureStart::ScatteredFeatureStart( RandomScatteredLargeFeature::ScatteredFeatureStart::ScatteredFeatureStart(
Level* level, Random* random, int chunkX, int chunkZ) { Level* level, Random* random, int chunkX, int chunkZ)
if (level->getBiome(chunkX * 16 + 8, chunkZ * 16 + 8) == Biome::jungle) { : StructureStart(chunkX, chunkZ) {
Biome* biome = level->getBiome(chunkX * 16 + 8, chunkZ * 16 + 8);
if (biome == Biome::jungle || biome == Biome::jungleHills) {
ScatteredFeaturePieces::JunglePyramidPiece* startRoom = ScatteredFeaturePieces::JunglePyramidPiece* startRoom =
new ScatteredFeaturePieces::JunglePyramidPiece(random, chunkX * 16, new ScatteredFeaturePieces::JunglePyramidPiece(random, chunkX * 16,
chunkZ * 16); chunkZ * 16);
pieces.push_back(startRoom); pieces.push_back(startRoom);
// System.out.println("jungle feature at " + (chunkX * } else if (biome == Biome::swampland) {
// 16) + " " + (chunkZ * 16)); ScatteredFeaturePieces::SwamplandHut* startRoom =
new ScatteredFeaturePieces::SwamplandHut(random, chunkX * 16,
chunkZ * 16);
pieces.push_back(startRoom);
} else { } else {
ScatteredFeaturePieces::DesertPyramidPiece* startRoom = ScatteredFeaturePieces::DesertPyramidPiece* startRoom =
new ScatteredFeaturePieces::DesertPyramidPiece(random, chunkX * 16, new ScatteredFeaturePieces::DesertPyramidPiece(random, chunkX * 16,
chunkZ * 16); chunkZ * 16);
pieces.push_back(startRoom); pieces.push_back(startRoom);
// System.out.println("desert feature at " + (chunkX *
// 16) + " " + (chunkZ * 16));
} }
calculateBoundingBox(); calculateBoundingBox();
}
bool RandomScatteredLargeFeature::isSwamphut(int cellX, int cellY, int cellZ) {
StructureStart* structureAt = getStructureAt(cellX, cellY, cellZ);
if (structureAt == NULL ||
!(dynamic_cast<ScatteredFeatureStart*>(structureAt)) ||
structureAt->pieces.empty()) {
return false;
}
StructurePiece* first = NULL;
AUTO_VAR(it, structureAt->pieces.begin());
if (it != structureAt->pieces.end()) first = *it;
return dynamic_cast<ScatteredFeaturePieces::SwamplandHut*>(first) != NULL;
}
std::vector<Biome::MobSpawnerData*>*
RandomScatteredLargeFeature::getSwamphutEnemies() {
return &swamphutEnemies;
} }

View file

@ -5,17 +5,44 @@
class RandomScatteredLargeFeature : public StructureFeature { class RandomScatteredLargeFeature : public StructureFeature {
public: public:
static const std::wstring OPTION_SPACING;
static void staticCtor(); static void staticCtor();
static std::vector<Biome*> allowedBiomes; static std::vector<Biome*> allowedBiomes;
private:
std::vector<Biome::MobSpawnerData*> swamphutEnemies;
int spacing;
int minSeparation;
void _init();
public:
RandomScatteredLargeFeature(); RandomScatteredLargeFeature();
RandomScatteredLargeFeature(
std::unordered_map<std::wstring, std::wstring> options);
std::wstring getFeatureName();
protected: protected:
virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false); virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false);
StructureStart* createStructureStart(int x, int z); StructureStart* createStructureStart(int x, int z);
public:
class ScatteredFeatureStart : public StructureStart { class ScatteredFeatureStart : public StructureStart {
public: public:
static StructureStart* Create() { return new ScatteredFeatureStart(); }
virtual EStructureStart GetType() {
return eStructureStart_ScatteredFeatureStart;
}
public:
ScatteredFeatureStart();
ScatteredFeatureStart(Level* level, Random* random, int chunkX, ScatteredFeatureStart(Level* level, Random* random, int chunkX,
int chunkZ); int chunkZ);
}; };
public:
bool isSwamphut(int cellX, int cellY, int cellZ);
std::vector<Biome::MobSpawnerData*>* getSwamphutEnemies();
}; };

View file

@ -30,7 +30,8 @@ bool ReedsFeature::place(Level* level, Random* random, int x, int y, int z) {
int h = 2 + random->nextInt(random->nextInt(3) + 1); int h = 2 + random->nextInt(random->nextInt(3) + 1);
for (int yy = 0; yy < h; yy++) { for (int yy = 0; yy < h; yy++) {
if (Tile::reeds->canSurvive(level, x2, y2 + yy, z2)) { if (Tile::reeds->canSurvive(level, x2, y2 + yy, z2)) {
level->setTileNoUpdate(x2, y2 + yy, z2, Tile::reeds_Id); level->setTileAndData(x2, y2 + yy, z2, Tile::reeds_Id,
0, Tile::UPDATE_CLIENTS);
} }
} }
} }

View file

@ -43,7 +43,8 @@ bool SandFeature::place(Level* level, Random* random, int x, int y, int z) {
for (int yy = y - yr; yy <= y + yr; yy++) { for (int yy = y - yr; yy <= y + yr; yy++) {
int t = level->getTile(xx, yy, zz); int t = level->getTile(xx, yy, zz);
if (t == Tile::dirt_Id || t == Tile::grass_Id) { if (t == Tile::dirt_Id || t == Tile::grass_Id) {
level->setTileNoUpdate(xx, yy, zz, tile); level->setTileAndData(xx, yy, zz, tile, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }

View file

@ -34,7 +34,8 @@ bool SpikeFeature::place(Level* level, Random* random, int x, int y, int z) {
int xd = xx - x; int xd = xx - x;
int zd = zz - z; int zd = zz - z;
if (xd * xd + zd * zd <= r * r + 1) { if (xd * xd + zd * zd <= r * r + 1) {
level->setTile(xx, yy, zz, Tile::obsidian_Id); level->setTileAndData(xx, yy, zz, Tile::obsidian_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} else } else
@ -46,7 +47,8 @@ bool SpikeFeature::place(Level* level, Random* random, int x, int y, int z) {
enderCrystal->moveTo(x + 0.5f, y + hh, z + 0.5f, random->nextFloat() * 360, enderCrystal->moveTo(x + 0.5f, y + hh, z + 0.5f, random->nextFloat() * 360,
0); 0);
level->addEntity(enderCrystal); level->addEntity(enderCrystal);
level->setTile(x, y + hh, z, Tile::unbreakable_Id); level->setTileAndData(x, y + hh, z, Tile::unbreakable_Id, 0,
Tile::UPDATE_CLIENTS);
return true; return true;
} }
@ -70,11 +72,13 @@ bool SpikeFeature::placeWithIndex(Level* level, Random* random, int x, int y,
level->getTile(xx, y - iTileBelow, zz) != tile) { level->getTile(xx, y - iTileBelow, zz) != tile) {
if (level->isEmptyTile(xx, y - iTileBelow, zz)) { if (level->isEmptyTile(xx, y - iTileBelow, zz)) {
// empty tile // empty tile
level->setTileNoUpdate(xx, y - iTileBelow, zz, level->setTileAndData(xx, y - iTileBelow, zz,
Tile::obsidian_Id); Tile::obsidian_Id, 0,
Tile::UPDATE_CLIENTS);
} else { } else {
level->setTile(xx, y - iTileBelow, zz, level->setTileAndData(xx, y - iTileBelow, zz,
Tile::obsidian_Id); Tile::obsidian_Id, 0,
Tile::UPDATE_CLIENTS);
} }
iTileBelow++; iTileBelow++;
} }

View file

@ -19,18 +19,18 @@ bool SpringFeature::place(Level* level, Random* random, int x, int y, int z) {
} }
} }
if (level->getTile(x, y + 1, z) != Tile::rock_Id) return false; if (level->getTile(x, y + 1, z) != Tile::stone_Id) return false;
if (level->getTile(x, y - 1, z) != Tile::rock_Id) return false; if (level->getTile(x, y - 1, z) != Tile::stone_Id) return false;
if (level->getTile(x, y, z) != 0 && if (level->getTile(x, y, z) != 0 &&
level->getTile(x, y, z) != Tile::rock_Id) level->getTile(x, y, z) != Tile::stone_Id)
return false; return false;
int rockCount = 0; int rockCount = 0;
if (level->getTile(x - 1, y, z) == Tile::rock_Id) rockCount++; if (level->getTile(x - 1, y, z) == Tile::stone_Id) rockCount++;
if (level->getTile(x + 1, y, z) == Tile::rock_Id) rockCount++; if (level->getTile(x + 1, y, z) == Tile::stone_Id) rockCount++;
if (level->getTile(x, y, z - 1) == Tile::rock_Id) rockCount++; if (level->getTile(x, y, z - 1) == Tile::stone_Id) rockCount++;
if (level->getTile(x, y, z + 1) == Tile::rock_Id) rockCount++; if (level->getTile(x, y, z + 1) == Tile::stone_Id) rockCount++;
int holeCount = 0; int holeCount = 0;
if (level->isEmptyTile(x - 1, y, z)) holeCount++; if (level->isEmptyTile(x - 1, y, z)) holeCount++;
@ -39,7 +39,7 @@ bool SpringFeature::place(Level* level, Random* random, int x, int y, int z) {
if (level->isEmptyTile(x, y, z + 1)) holeCount++; if (level->isEmptyTile(x, y, z + 1)) holeCount++;
if (rockCount == 3 && holeCount == 1) { if (rockCount == 3 && holeCount == 1) {
level->setTile(x, y, z, tile); level->setTileAndData(x, y, z, tile, 0, Tile::UPDATE_CLIENTS);
level->setInstaTick(true); level->setInstaTick(true);
Tile::tiles[tile]->tick(level, x, y, z, random); Tile::tiles[tile]->tick(level, x, y, z, random);
level->setInstaTick(false); level->setInstaTick(false);

View file

@ -4,9 +4,14 @@
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.biome.h" #include "../../Headers/net.minecraft.world.level.biome.h"
#include "../../Headers/net.minecraft.world.level.dimension.h" #include "../../Headers/net.minecraft.world.level.dimension.h"
#include "../../Util/Mth.h"
#include "../../IO/Files/FileHeader.h" #include "../../IO/Files/FileHeader.h"
#include "../../Util/JavaMath.h" #include "../../Util/JavaMath.h"
const std::wstring StrongholdFeature::OPTION_DISTANCE = L"distance";
const std::wstring StrongholdFeature::OPTION_COUNT = L"count";
const std::wstring StrongholdFeature::OPTION_SPREAD = L"spread";
std::vector<Biome*> StrongholdFeature::allowedBiomes; std::vector<Biome*> StrongholdFeature::allowedBiomes;
void StrongholdFeature::staticCtor() { void StrongholdFeature::staticCtor() {
@ -25,7 +30,10 @@ void StrongholdFeature::staticCtor() {
allowedBiomes.push_back(Biome::jungleHills); allowedBiomes.push_back(Biome::jungleHills);
}; };
StrongholdFeature::StrongholdFeature() : StructureFeature() { void StrongholdFeature::_init() {
distance = 32;
spread = 3;
// 4J added initialisers // 4J added initialisers
for (int i = 0; i < strongholdPos_length; i++) { for (int i = 0; i < strongholdPos_length; i++) {
strongholdPos[i] = NULL; strongholdPos[i] = NULL;
@ -33,18 +41,43 @@ StrongholdFeature::StrongholdFeature() : StructureFeature() {
isSpotSelected = false; isSpotSelected = false;
} }
StrongholdFeature::StrongholdFeature() : StructureFeature() { _init(); }
StrongholdFeature::StrongholdFeature(
std::unordered_map<std::wstring, std::wstring> options) {
_init();
for (AUTO_VAR(it, options.begin()); it != options.end(); ++it) {
if (it->first.compare(OPTION_DISTANCE) == 0) {
distance = Mth::getDouble(it->second, distance, 1);
} else if (it->first.compare(OPTION_COUNT) == 0) {
// 4J-JEV: Removed, we only have the one stronghold.
// strongholdPos = new ChunkPos[ Mth::getInt(it->second,
// strongholdPos_length, 1) ];
assert(false);
} else if (it->first.compare(OPTION_SPREAD) == 0) {
spread = Mth::getInt(it->second, spread, 1);
}
}
}
StrongholdFeature::~StrongholdFeature() { StrongholdFeature::~StrongholdFeature() {
for (int i = 0; i < strongholdPos_length; i++) { for (int i = 0; i < strongholdPos_length; i++) {
delete strongholdPos[i]; delete strongholdPos[i];
} }
} }
std::wstring StrongholdFeature::getFeatureName() {
return LargeFeature::STRONGHOLD;
}
bool StrongholdFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) { bool StrongholdFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) {
if (!isSpotSelected) { if (!isSpotSelected) {
Random random; Random random;
random.setSeed(level->getSeed()); random.setSeed(level->getSeed());
double angle = random.nextDouble() * PI * 2.0; double angle = random.nextDouble() * PI * 2.0;
int circle = 1;
// 4J Stu - Changed so that we keep trying more until we have found // 4J Stu - Changed so that we keep trying more until we have found
// somewhere in the world to place a stronghold // somewhere in the world to place a stronghold
@ -60,7 +93,8 @@ bool StrongholdFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) {
(1.25 + random.nextDouble()) * (3 + random.nextInt(4)); (1.25 + random.nextDouble()) * (3 + random.nextInt(4));
} else { } else {
// Original Java // Original Java
dist = (1.25 + random.nextDouble()) * 32.0; dist = (1.25 * circle + random.nextDouble()) *
(distance * circle);
} }
#else #else
// 4J Stu - Design change: Original spawns at *32 chunks rather // 4J Stu - Design change: Original spawns at *32 chunks rather
@ -119,10 +153,6 @@ bool StrongholdFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) {
// 4J Added // 4J Added
hasFoundValidPos = true; hasFoundValidPos = true;
delete position; delete position;
} else {
app.DebugPrintf(
"Placed stronghold in INVALID biome at (%d, %d)\n",
selectedX, selectedZ);
} }
delete strongholdPos[i]; delete strongholdPos[i];
@ -137,7 +167,7 @@ bool StrongholdFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) {
// 4J Stu - Randomise the angles for retries as well // 4J Stu - Randomise the angles for retries as well
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
angle = random.nextDouble() * PI * 2.0; angle = random.nextDouble() * PI * 2.0 * circle / (double)spread;
#endif #endif
} while (!hasFoundValidPos && findAttempts < MAX_STRONGHOLD_ATTEMPTS); } while (!hasFoundValidPos && findAttempts < MAX_STRONGHOLD_ATTEMPTS);
@ -200,10 +230,14 @@ StructureStart* StrongholdFeature::createStructureStart(int x, int z) {
// return new StrongholdStart(level, random, x, z); // return new StrongholdStart(level, random, x, z);
} }
StrongholdFeature::StrongholdStart::StrongholdStart() {
// for reflection
}
StrongholdFeature::StrongholdStart::StrongholdStart(Level* level, StrongholdFeature::StrongholdStart::StrongholdStart(Level* level,
Random* random, int chunkX, Random* random, int chunkX,
int chunkZ) int chunkZ)
: StructureStart() { : StructureStart(chunkX, chunkZ) {
StrongholdPieces::resetPieces(); StrongholdPieces::resetPieces();
StrongholdPieces::StartPiece* startRoom = new StrongholdPieces::StartPiece( StrongholdPieces::StartPiece* startRoom = new StrongholdPieces::StartPiece(
@ -222,4 +256,4 @@ StrongholdFeature::StrongholdStart::StrongholdStart(Level* level,
calculateBoundingBox(); calculateBoundingBox();
moveBelowSeaLevel(level, random, 10); moveBelowSeaLevel(level, random, 10);
} }

View file

@ -16,6 +16,11 @@ class Biome;
#endif #endif
class StrongholdFeature : public StructureFeature { class StrongholdFeature : public StructureFeature {
public:
static const std::wstring OPTION_DISTANCE;
static const std::wstring OPTION_COUNT;
static const std::wstring OPTION_SPREAD;
public: public:
static void staticCtor(); static void staticCtor();
@ -27,19 +32,33 @@ private:
1; // Java game has 3, but xbox game only has 1 because of the world 1; // Java game has 3, but xbox game only has 1 because of the world
// size; // 4J added // size; // 4J added
ChunkPos* strongholdPos[strongholdPos_length]; ChunkPos* strongholdPos[strongholdPos_length];
double distance;
int spread;
void _init();
public: public:
StrongholdFeature(); StrongholdFeature();
StrongholdFeature(std::unordered_map<std::wstring, std::wstring> options);
~StrongholdFeature(); ~StrongholdFeature();
std::wstring getFeatureName();
protected: protected:
virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false); virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false);
std::vector<TilePos>* getGuesstimatedFeaturePositions(); std::vector<TilePos>* getGuesstimatedFeaturePositions();
virtual StructureStart* createStructureStart(int x, int z); virtual StructureStart* createStructureStart(int x, int z);
private: public:
class StrongholdStart : public StructureStart { class StrongholdStart : public StructureStart {
public: public:
static StructureStart* Create() { return new StrongholdStart(); }
virtual EStructureStart GetType() {
return eStructureStart_StrongholdStart;
}
public:
StrongholdStart();
StrongholdStart(Level* level, Random* random, int chunkX, int chunkZ); StrongholdStart(Level* level, Random* random, int chunkX, int chunkZ);
}; };
}; };

View file

@ -7,6 +7,12 @@
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Level/LevelData.h" #include "../../Level/LevelData.h"
StructureFeature::StructureFeature() {
#ifdef ENABLE_STRUCTURE_SAVING
savedData = nullptr;
#endif
}
StructureFeature::~StructureFeature() { StructureFeature::~StructureFeature() {
for (AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); for (AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end();
it++) { it++) {
@ -20,6 +26,8 @@ void StructureFeature::addFeature(Level* level, int x, int z, int xOffs,
// the chunk being generated, but not all chunks are the sources of // the chunk being generated, but not all chunks are the sources of
// structures // structures
restoreSavedData(level);
if (cachedStructures.find(ChunkPos::hashCode(x, z)) != if (cachedStructures.find(ChunkPos::hashCode(x, z)) !=
cachedStructures.end()) { cachedStructures.end()) {
return; return;
@ -35,11 +43,14 @@ void StructureFeature::addFeature(Level* level, int x, int z, int xOffs,
level->getLevelData()->getGenerator() == LevelType::lvl_flat)) { level->getLevelData()->getGenerator() == LevelType::lvl_flat)) {
StructureStart* start = createStructureStart(x, z); StructureStart* start = createStructureStart(x, z);
cachedStructures[ChunkPos::hashCode(x, z)] = start; cachedStructures[ChunkPos::hashCode(x, z)] = start;
saveFeature(x, z, start);
} }
} }
bool StructureFeature::postProcess(Level* level, Random* random, int chunkX, bool StructureFeature::postProcess(Level* level, Random* random, int chunkX,
int chunkZ) { int chunkZ) {
restoreSavedData(level);
// 4J Stu - The x and z used to be offset by (+8) here, but that means we // 4J Stu - The x and z used to be offset by (+8) here, but that means we
// can miss out half structures on the edge of the world Normal feature // can miss out half structures on the edge of the world Normal feature
// generation offsets generation by half a chunk to ensure that it can // generation offsets generation by half a chunk to ensure that it can
@ -62,6 +73,11 @@ bool StructureFeature::postProcess(Level* level, Random* random, int chunkX,
structureStart->postProcess(level, random, bb); structureStart->postProcess(level, random, bb);
delete bb; delete bb;
intersection = true; intersection = true;
// because some feature pieces are modified in the postProcess
// step, we need to save them again
saveFeature(structureStart->getChunkX(),
structureStart->getChunkZ(), structureStart);
} }
} }
} }
@ -70,6 +86,8 @@ bool StructureFeature::postProcess(Level* level, Random* random, int chunkX,
} }
bool StructureFeature::isIntersection(int cellX, int cellZ) { bool StructureFeature::isIntersection(int cellX, int cellZ) {
restoreSavedData(level);
for (AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); for (AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end();
it++) { it++) {
StructureStart* structureStart = it->second; StructureStart* structureStart = it->second;
@ -90,10 +108,13 @@ bool StructureFeature::isIntersection(int cellX, int cellZ) {
return false; return false;
} }
///////////////////////////////////////////
// 4J-PB - Below functions added from 1.2.3
///////////////////////////////////////////
bool StructureFeature::isInsideFeature(int cellX, int cellY, int cellZ) { bool StructureFeature::isInsideFeature(int cellX, int cellY, int cellZ) {
restoreSavedData(level);
return getStructureAt(cellX, cellY, cellZ) != NULL;
}
StructureStart* StructureFeature::getStructureAt(int cellX, int cellY,
int cellZ) {
// for (StructureStart structureStart : cachedStructures.values()) // for (StructureStart structureStart : cachedStructures.values())
for (AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); for (AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end();
++it) { ++it) {
@ -104,10 +125,10 @@ bool StructureFeature::isInsideFeature(int cellX, int cellY, int cellZ) {
cellX, cellZ)) { cellX, cellZ)) {
/* /*
Iterator<StructurePiece> it = Iterator<StructurePiece> it =
structureStart.getPieces().iterator(); while (it.hasNext()) { structureStart.getPieces().iterator(); while (it.hasNext())
StructurePiece next = it.next(); { StructurePiece next = it.next(); if
if (next.getBoundingBox().isInside(cellX, cellY, cellZ)) { (next.getBoundingBox().isInside(cellX, cellY, cellZ)) { return
return true; true;
} }
*/ */
std::list<StructurePiece*>* pieces = std::list<StructurePiece*>* pieces =
@ -118,12 +139,27 @@ bool StructureFeature::isInsideFeature(int cellX, int cellY, int cellZ) {
StructurePiece* piece = *it2; StructurePiece* piece = *it2;
if (piece->getBoundingBox()->isInside(cellX, cellY, if (piece->getBoundingBox()->isInside(cellX, cellY,
cellZ)) { cellZ)) {
return true; return pStructureStart;
} }
} }
} }
} }
} }
return NULL;
}
bool StructureFeature::isInsideBoundingFeature(int cellX, int cellY,
int cellZ) {
restoreSavedData(level);
for (AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end();
++it) {
StructureStart* structureStart = it->second;
if (structureStart->isValid()) {
return (structureStart->getBoundingBox()->intersects(cellX, cellZ,
cellX, cellZ));
}
}
return false; return false;
} }
@ -133,6 +169,8 @@ TilePos* StructureFeature::getNearestGeneratedFeature(Level* level, int cellX,
// even if the player hasn't generated new chunks yet // even if the player hasn't generated new chunks yet
this->level = level; this->level = level;
restoreSavedData(level);
random->setSeed(level->getSeed()); random->setSeed(level->getSeed());
int64_t xScale = random->nextLong(); int64_t xScale = random->nextLong();
int64_t zScale = random->nextLong(); int64_t zScale = random->nextLong();
@ -159,7 +197,7 @@ TilePos* StructureFeature::getNearestGeneratedFeature(Level* level, int cellX,
int dx = locatorPosition->x - cellX; int dx = locatorPosition->x - cellX;
int dy = locatorPosition->y - cellY; int dy = locatorPosition->y - cellY;
int dz = locatorPosition->z - cellZ; int dz = locatorPosition->z - cellZ;
double dist = dx + dx * dy * dy + dz * dz; double dist = dx * dx + dy * dy + dz * dz;
if (dist < minDistance) { if (dist < minDistance) {
minDistance = dist; minDistance = dist;
@ -180,7 +218,7 @@ TilePos* StructureFeature::getNearestGeneratedFeature(Level* level, int cellX,
int dx = (*it).x - cellX; int dx = (*it).x - cellX;
int dy = (*it).y - cellY; int dy = (*it).y - cellY;
int dz = (*it).z - cellZ; int dz = (*it).z - cellZ;
double dist = dx + dx * dy * dy + dz * dz; double dist = dx * dx + dy * dy + dz * dz;
if (dist < minDistance) { if (dist < minDistance) {
minDistance = dist; minDistance = dist;
@ -199,3 +237,50 @@ TilePos* StructureFeature::getNearestGeneratedFeature(Level* level, int cellX,
std::vector<TilePos>* StructureFeature::getGuesstimatedFeaturePositions() { std::vector<TilePos>* StructureFeature::getGuesstimatedFeaturePositions() {
return NULL; return NULL;
} }
void StructureFeature::restoreSavedData(Level* level) {
#ifdef ENABLE_STRUCTURE_SAVING
if (savedData == NULL) {
savedData = std::dynamic_pointer_cast<StructureFeatureSavedData>(
level->getSavedData(typeid(StructureFeatureSavedData),
getFeatureName()));
if (savedData == NULL) {
savedData = std::shared_ptr<StructureFeatureSavedData>(
new StructureFeatureSavedData(getFeatureName()));
level->setSavedData(getFeatureName(), savedData);
} else {
CompoundTag* fullTag = savedData->getFullTag();
std::vector<Tag*>* allTags = fullTag->getAllTags();
for (AUTO_VAR(it, allTags->begin()); it != allTags->end(); ++it) {
Tag* featureTag = *it;
if (featureTag->getId() == Tag::TAG_Compound) {
CompoundTag* ct = (CompoundTag*)featureTag;
if (ct->contains(L"ChunkX") && ct->contains(L"ChunkZ")) {
int cx = ct->getInt(L"ChunkX");
int cz = ct->getInt(L"ChunkZ");
StructureStart* start =
StructureFeatureIO::loadStaticStart(ct, level);
// System.out.println("Loaded " +
// start.getClass().getSimpleName() + " from file");
cachedStructures[ChunkPos::hashCode(cx, cz)] = start;
}
}
}
delete allTags;
}
}
#endif
}
void StructureFeature::saveFeature(int chunkX, int chunkZ,
StructureStart* feature) {
#ifdef ENABLE_STRUCTURE_SAVING
savedData->putFeatureTag(feature->createTag(chunkX, chunkZ), chunkX,
chunkZ);
savedData->setDirty();
#endif
}

View file

@ -1,7 +1,11 @@
#pragma once #pragma once
#include "LargeFeature.h" #include "LargeFeature.h"
#include "../StructureFeatureSavedData.h"
class StructureStart; class StructureStart;
// #define ENABLE_STRUCTURE_SAVING
class StructureFeature : public LargeFeature { class StructureFeature : public LargeFeature {
public: public:
// 4J added - Maps to values in the game rules xml // 4J added - Maps to values in the game rules xml
@ -13,12 +17,20 @@ public:
eFeature_Village, eFeature_Village,
}; };
#ifdef ENABLE_STRUCTURE_SAVING
private:
std::shared_ptr<StructureFeatureSavedData> savedData;
#endif
protected: protected:
std::unordered_map<int64_t, StructureStart*> cachedStructures; std::unordered_map<int64_t, StructureStart*> cachedStructures;
public: public:
StructureFeature();
~StructureFeature(); ~StructureFeature();
virtual std::wstring getFeatureName() = 0;
virtual void addFeature(Level* level, int x, int z, int xOffs, int zOffs, virtual void addFeature(Level* level, int x, int z, int xOffs, int zOffs,
byteArray blocks); byteArray blocks);
@ -26,12 +38,22 @@ public:
bool isIntersection(int cellX, int cellZ); bool isIntersection(int cellX, int cellZ);
bool isInsideFeature(int cellX, int cellY, int cellZ); bool isInsideFeature(int cellX, int cellY, int cellZ);
protected:
StructureStart* getStructureAt(int cellX, int cellY, int cellZ);
public:
bool isInsideBoundingFeature(int cellX, int cellY, int cellZ);
TilePos* getNearestGeneratedFeature(Level* level, int cellX, int cellY, TilePos* getNearestGeneratedFeature(Level* level, int cellX, int cellY,
int cellZ); int cellZ);
protected: protected:
std::vector<TilePos>* getGuesstimatedFeaturePositions(); std::vector<TilePos>* getGuesstimatedFeaturePositions();
private:
virtual void restoreSavedData(Level* level);
virtual void saveFeature(int chunkX, int chunkZ, StructureStart* feature);
/** /**
* Returns true if the given chunk coordinates should hold a structure * Returns true if the given chunk coordinates should hold a structure
* source. * source.

View file

@ -21,7 +21,8 @@ bool TallGrassFeature::place(Level* level, Random* random, int x, int y,
int z2 = z + random->nextInt(8) - random->nextInt(8); int z2 = z + random->nextInt(8) - random->nextInt(8);
if (level->isEmptyTile(x2, y2, z2)) { if (level->isEmptyTile(x2, y2, z2)) {
if (Tile::tiles[tile]->canSurvive(level, x2, y2, z2)) { if (Tile::tiles[tile]->canSurvive(level, x2, y2, z2)) {
level->setTileAndDataNoUpdate(x2, y2, z2, tile, type); level->setTileAndData(x2, y2, z2, tile, type,
Tile::UPDATE_CLIENTS);
} }
} }
} }

View file

@ -83,7 +83,8 @@ bool TreeFeature::place(Level* level, Random* random, int x, int y, int z) {
if (abs(xo) == offs && abs(zo) == offs && if (abs(xo) == offs && abs(zo) == offs &&
(random->nextInt(2) == 0 || yo == 0)) (random->nextInt(2) == 0 || yo == 0))
continue; continue;
if (!Tile::solid[level->getTile(xx, yy, zz)]) int t = level->getTile(xx, yy, zz);
if (t == 0 || t == Tile::leaves_Id)
placeBlock(level, xx, yy, zz, Tile::leaves_Id, leafType); placeBlock(level, xx, yy, zz, Tile::leaves_Id, leafType);
} }
} }

View file

@ -4,9 +4,9 @@
class TreeFeature : public Feature { class TreeFeature : public Feature {
private: private:
const int baseHeight; const int baseHeight;
const bool addJungleFeatures;
const int trunkType; const int trunkType;
const int leafType; const int leafType;
const bool addJungleFeatures;
public: public:
TreeFeature(bool doUpdate); TreeFeature(bool doUpdate);

View file

@ -5,6 +5,9 @@
#include "../../Headers/net.minecraft.world.level.biome.h" #include "../../Headers/net.minecraft.world.level.biome.h"
#include "../../Headers/net.minecraft.world.level.dimension.h" #include "../../Headers/net.minecraft.world.level.dimension.h"
const std::wstring VillageFeature::OPTION_SIZE_MODIFIER = L"size";
const std::wstring VillageFeature::OPTION_SPACING = L"distance";
std::vector<Biome*> VillageFeature::allowedBiomes; std::vector<Biome*> VillageFeature::allowedBiomes;
void VillageFeature::staticCtor() { void VillageFeature::staticCtor() {
@ -12,27 +15,44 @@ void VillageFeature::staticCtor() {
allowedBiomes.push_back(Biome::desert); allowedBiomes.push_back(Biome::desert);
} }
VillageFeature::VillageFeature(int villageSizeModifier, int iXZSize) void VillageFeature::_init(int iXZSize) {
: StructureFeature(), villageSizeModifier(villageSizeModifier) { villageSizeModifier = 0;
townSpacing = 32;
minTownSeparation = 8;
m_iXZSize = iXZSize; m_iXZSize = iXZSize;
} }
bool VillageFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) { VillageFeature::VillageFeature(int iXZSize) { _init(iXZSize); }
int townSpacing;
VillageFeature::VillageFeature(
std::unordered_map<std::wstring, std::wstring> options, int iXZSize) {
_init(iXZSize);
for (AUTO_VAR(it, options.begin()); it != options.end(); ++it) {
if (it->first.compare(OPTION_SIZE_MODIFIER) == 0) {
villageSizeModifier =
Mth::getInt(it->second, villageSizeModifier, 0);
} else if (it->first.compare(OPTION_SPACING) == 0) {
townSpacing =
Mth::getInt(it->second, townSpacing, minTownSeparation + 1);
}
}
}
std::wstring VillageFeature::getFeatureName() { return L"Village"; }
bool VillageFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) {
int townSpacing = this->townSpacing;
if (!bIsSuperflat
#ifdef _LARGE_WORLDS #ifdef _LARGE_WORLDS
if (level->dimension->getXZSize() > 128) { && level->dimension->getXZSize() < 128
townSpacing = 32;
} else
#endif #endif
if (bIsSuperflat) { ) {
townSpacing = 32;
} else {
townSpacing = 16; // 4J change 32; townSpacing = 16; // 4J change 32;
} }
int minTownSeparation = 8;
int xx = x; int xx = x;
int zz = z; int zz = z;
if (x < 0) x -= townSpacing - 1; if (x < 0) x -= townSpacing - 1;
@ -77,6 +97,12 @@ StructureStart* VillageFeature::createStructureStart(int x, int z) {
m_iXZSize); m_iXZSize);
} }
VillageFeature::VillageStart::VillageStart() {
valid = false; // 4J added initialiser
m_iXZSize = 0;
// for reflection
}
VillageFeature::VillageStart::VillageStart(Level* level, Random* random, VillageFeature::VillageStart::VillageStart(Level* level, Random* random,
int chunkX, int chunkZ, int chunkX, int chunkZ,
int villageSizeModifier, int villageSizeModifier,
@ -136,3 +162,14 @@ bool VillageFeature::VillageStart::isValid() {
} }
return valid; return valid;
} }
void VillageFeature::VillageStart::addAdditonalSaveData(CompoundTag* tag) {
StructureStart::addAdditonalSaveData(tag);
tag->putBoolean(L"Valid", valid);
}
void VillageFeature::VillageStart::readAdditonalSaveData(CompoundTag* tag) {
StructureStart::readAdditonalSaveData(tag);
valid = tag->getBoolean(L"Valid");
}

View file

@ -4,28 +4,48 @@
class Biome; class Biome;
class VillageFeature : public StructureFeature { class VillageFeature : public StructureFeature {
public:
static const std::wstring OPTION_SIZE_MODIFIER;
static const std::wstring OPTION_SPACING;
private: private:
const int villageSizeModifier; int villageSizeModifier;
int townSpacing;
int minTownSeparation;
void _init(int iXZSize);
public: public:
static void staticCtor(); static void staticCtor();
static std::vector<Biome*> allowedBiomes; static std::vector<Biome*> allowedBiomes;
VillageFeature(int villageSizeModifier, int iXZSize); VillageFeature(int iXZSize);
VillageFeature(std::unordered_map<std::wstring, std::wstring> options,
int iXZSize);
std::wstring getFeatureName();
protected: protected:
virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false); virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false);
virtual StructureStart* createStructureStart(int x, int z); virtual StructureStart* createStructureStart(int x, int z);
private: public:
class VillageStart : public StructureStart { class VillageStart : public StructureStart {
public:
static StructureStart* Create() { return new VillageStart(); }
virtual EStructureStart GetType() {
return eStructureStart_VillageStart;
}
private: private:
bool valid; bool valid;
int m_iXZSize; int m_iXZSize;
public: public:
VillageStart();
VillageStart(Level* level, Random* random, int chunkX, int chunkZ, VillageStart(Level* level, Random* random, int chunkX, int chunkZ,
int villageSizeModifier, int iXZSize); int villageSizeModifier, int iXZSize);
bool isValid(); bool isValid();
void addAdditonalSaveData(CompoundTag* tag);
void readAdditonalSaveData(CompoundTag* tag);
}; };
int m_iXZSize; int m_iXZSize;

View file

@ -14,10 +14,11 @@ bool VinesFeature::place(Level* level, Random* random, int x, int y, int z) {
if (level->isEmptyTile(x, y, z)) { if (level->isEmptyTile(x, y, z)) {
for (int face = Facing::NORTH; face <= Facing::EAST; face++) { for (int face = Facing::NORTH; face <= Facing::EAST; face++) {
if (Tile::vine->mayPlace(level, x, y, z, face)) { if (Tile::vine->mayPlace(level, x, y, z, face)) {
level->setTileAndDataNoUpdate( level->setTileAndData(
x, y, z, Tile::vine_Id, x, y, z, Tile::vine_Id,
1 << Direction::FACING_DIRECTION 1 << Direction::FACING_DIRECTION
[Facing::OPPOSITE_FACING[face]]); [Facing::OPPOSITE_FACING[face]],
Tile::UPDATE_CLIENTS);
break; break;
} }
} }

View file

@ -11,7 +11,8 @@ bool WaterlilyFeature::place(Level* level, Random* random, int x, int y,
int z2 = z + random->nextInt(8) - random->nextInt(8); int z2 = z + random->nextInt(8) - random->nextInt(8);
if (level->isEmptyTile(x2, y2, z2)) { if (level->isEmptyTile(x2, y2, z2)) {
if (Tile::waterLily->mayPlace(level, x2, y2, z2)) { if (Tile::waterLily->mayPlace(level, x2, y2, z2)) {
level->setTileNoUpdate(x2, y2, z2, Tile::waterLily_Id); level->setTileAndData(x2, y2, z2, Tile::waterLily_Id, 0,
Tile::UPDATE_CLIENTS);
} }
} }
} }

View file

@ -0,0 +1,233 @@
#include "../../Platform/stdafx.h"
#include "../../Util/StringHelpers.h"
#include "../../Headers/net.minecraft.world.level.levelgen.flat.h"
#include "../../Headers/net.minecraft.world.level.tile.h"
#include "FlatGeneratorInfo.h"
const std::wstring FlatGeneratorInfo::STRUCTURE_VILLAGE = L"village";
const std::wstring FlatGeneratorInfo::STRUCTURE_BIOME_SPECIFIC = L"biome_1";
const std::wstring FlatGeneratorInfo::STRUCTURE_STRONGHOLD = L"stronghold";
const std::wstring FlatGeneratorInfo::STRUCTURE_MINESHAFT = L"mineshaft";
const std::wstring FlatGeneratorInfo::STRUCTURE_BIOME_DECORATION =
L"decoration";
const std::wstring FlatGeneratorInfo::STRUCTURE_LAKE = L"lake";
const std::wstring FlatGeneratorInfo::STRUCTURE_LAVA_LAKE = L"lava_lake";
const std::wstring FlatGeneratorInfo::STRUCTURE_DUNGEON = L"dungeon";
FlatGeneratorInfo::FlatGeneratorInfo() { biome = 0; }
FlatGeneratorInfo::~FlatGeneratorInfo() {
for (AUTO_VAR(it, layers.begin()); it != layers.end(); ++it) {
delete *it;
}
}
int FlatGeneratorInfo::getBiome() { return biome; }
void FlatGeneratorInfo::setBiome(int biome) { this->biome = biome; }
std::unordered_map<std::wstring,
std::unordered_map<std::wstring, std::wstring> >*
FlatGeneratorInfo::getStructures() {
return &structures;
}
std::vector<FlatLayerInfo*>* FlatGeneratorInfo::getLayers() { return &layers; }
void FlatGeneratorInfo::updateLayers() {
int y = 0;
for (AUTO_VAR(it, layers.begin()); it != layers.end(); ++it) {
FlatLayerInfo* layer = *it;
layer->setStart(y);
y += layer->getHeight();
}
}
std::wstring FlatGeneratorInfo::toString() {
return L"";
#if 0
StringBuilder builder = new StringBuilder();
builder.append(SERIALIZATION_VERSION);
builder.append(";");
for (int i = 0; i < layers.size(); i++)
{
if (i > 0) builder.append(",");
builder.append(layers.get(i).toString());
}
builder.append(";");
builder.append(biome);
if (!structures.isEmpty())
{
builder.append(";");
int structCount = 0;
for (Map.Entry<String, Map<String, String>> structure : structures.entrySet())
{
if (structCount++ > 0) builder.append(",");
builder.append(structure.getKey().toLowerCase());
Map<String, String> options = structure.getValue();
if (!options.isEmpty())
{
builder.append("(");
int optionCount = 0;
for (Map.Entry<String, String> option : options.entrySet())
{
if (optionCount++ > 0) builder.append(" ");
builder.append(option.getKey());
builder.append("=");
builder.append(option.getValue());
}
builder.append(")");
}
}
}
else
{
builder.append(";");
}
return builder.toString();
#endif
}
FlatLayerInfo* FlatGeneratorInfo::getLayerFromString(const std::wstring& input,
int yOffset) {
return NULL;
#if 0
std::vector<std::wstring> parts = stringSplit(input, L'x');
int height = 1;
int id;
int data = 0;
if (parts.size() == 2)
{
height = _fromString<int>(parts[0]);
if (yOffset + height >= Level::maxBuildHeight) height = Level::maxBuildHeight - yOffset;
if (height < 0) height = 0;
}
std::wstring identity = parts[parts.size() - 1];
parts = stringSplit(identity, L':');
id = _fromString<int>(parts[0]);
if (parts.size() > 1) data = _from_String<int>(parts[1]);
if (Tile::tiles[id] == NULL)
{
id = 0;
data = 0;
}
if (data < 0 || data > 15) data = 0;
FlatLayerInfo *result = new FlatLayerInfo(height, id, data);
result->setStart(yOffset);
return result;
#endif
}
std::vector<FlatLayerInfo*>* FlatGeneratorInfo::getLayersFromString(
const std::wstring& input) {
if (input.empty()) return NULL;
std::vector<FlatLayerInfo*>* result = new std::vector<FlatLayerInfo*>();
std::vector<std::wstring> depths = stringSplit(input, L',');
int yOffset = 0;
for (AUTO_VAR(it, depths.begin()); it != depths.end(); ++it) {
FlatLayerInfo* layer = getLayerFromString(*it, yOffset);
if (layer == NULL) return NULL;
result->push_back(layer);
yOffset += layer->getHeight();
}
return result;
}
FlatGeneratorInfo* FlatGeneratorInfo::fromValue(const std::wstring& input) {
return getDefault();
#if 0
if (input.empty()) return getDefault();
std::vector<std::wstring> parts = stringSplit(input, L';');
int version = parts.size() == 1 ? 0 : Mth::getInt(parts[0], 0);
if (version < 0 || version > SERIALIZATION_VERSION) return getDefault();
FlatGeneratorInfo *result = new FlatGeneratorInfo();
int index = parts.size() == 1 ? 0 : 1;
std::vector<FlatLayerInfo *> *layers = getLayersFromString(parts[index++]);
if (layers == NULL || layers->isEmpty())
{
delete layers;
return getDefault();
}
result->getLayers()->addAll(layers);
delete layers;
result->updateLayers();
int biome = Biome::plains_Id;
if (version > 0 && parts.size() > index) biome = Mth::getInt(parts[index++], biome);
result->setBiome(biome);
if (version > 0 && parts.size() > index)
{
std::vector<std::wstring> structures = stringSplit(parts[index++], L',');
for(AUTO_VAR(it, structures.begin()); it != structures.end(); ++it)
{
std::vector<std::wstring> separated = stringSplit(parts[index++], L"\\(");
std::unordered_map<std::wstring, std::wstring> structureOptions;
if (separated[0].length() > 0)
{
(*result->getStructures())[separated[0]] = structureOptions;
if (separated.size() > 1 && separated[1].endsWith(L")") && separated[1].length() > 1)
{
String[] options = separated[1].substring(0, separated[1].length() - 1).split(" ");
for (int option = 0; option < options.length; option++)
{
String[] split = options[option].split("=", 2);
if (split.length == 2) structureOptions[split[0]] = split[1];
}
}
}
}
}
else
{
(* (result->getStructures()) )[STRUCTURE_VILLAGE] = std::unordered_map<std::wstring, std::wstring>();
}
return result;
#endif
}
FlatGeneratorInfo* FlatGeneratorInfo::getDefault() {
FlatGeneratorInfo* result = new FlatGeneratorInfo();
result->setBiome(Biome::plains->id);
result->getLayers()->push_back(new FlatLayerInfo(1, Tile::unbreakable_Id));
result->getLayers()->push_back(new FlatLayerInfo(2, Tile::dirt_Id));
result->getLayers()->push_back(new FlatLayerInfo(1, Tile::grass_Id));
result->updateLayers();
(*(result->getStructures()))[STRUCTURE_VILLAGE] =
std::unordered_map<std::wstring, std::wstring>();
return result;
}

View file

@ -0,0 +1,46 @@
#pragma once
class FlatLayerInfo;
class FlatGeneratorInfo {
public:
static const int SERIALIZATION_VERSION = 2;
static const std::wstring STRUCTURE_VILLAGE;
static const std::wstring STRUCTURE_BIOME_SPECIFIC;
static const std::wstring STRUCTURE_STRONGHOLD;
static const std::wstring STRUCTURE_MINESHAFT;
static const std::wstring STRUCTURE_BIOME_DECORATION;
static const std::wstring STRUCTURE_LAKE;
static const std::wstring STRUCTURE_LAVA_LAKE;
static const std::wstring STRUCTURE_DUNGEON;
private:
std::vector<FlatLayerInfo*> layers;
std::unordered_map<std::wstring,
std::unordered_map<std::wstring, std::wstring> >
structures;
int biome;
public:
FlatGeneratorInfo();
~FlatGeneratorInfo();
int getBiome();
void setBiome(int biome);
std::unordered_map<std::wstring,
std::unordered_map<std::wstring, std::wstring> >*
getStructures();
std::vector<FlatLayerInfo*>* getLayers();
void updateLayers();
std::wstring toString();
private:
static FlatLayerInfo* getLayerFromString(const std::wstring& input,
int yOffset);
static std::vector<FlatLayerInfo*>* getLayersFromString(
const std::wstring& input);
public:
static FlatGeneratorInfo* fromValue(const std::wstring& input);
static FlatGeneratorInfo* getDefault();
};

View file

@ -0,0 +1,46 @@
#include "../../Platform/stdafx.h"
#include "FlatLayerInfo.h"
void FlatLayerInfo::_init(int height, int id) {
this->height = height;
this->id = id;
data = 0;
start = 0;
}
FlatLayerInfo::FlatLayerInfo(int height, int id) { _init(height, id); }
FlatLayerInfo::FlatLayerInfo(int height, int id, int data) {
_init(height, id);
this->data = data;
}
int FlatLayerInfo::getHeight() { return height; }
void FlatLayerInfo::setHeight(int height) { this->height = height; }
int FlatLayerInfo::getId() { return id; }
void FlatLayerInfo::setId(int id) { this->id = id; }
int FlatLayerInfo::getData() { return data; }
void FlatLayerInfo::setData(int data) { this->data = data; }
int FlatLayerInfo::getStart() { return start; }
void FlatLayerInfo::setStart(int start) { this->start = start; }
std::wstring FlatLayerInfo::toString() {
std::wstring result = _toString<int>(id);
if (height > 1) {
result = _toString<int>(height) + L"x" + result;
}
if (data > 0) {
result += L":" + _toString<int>(data);
}
return result;
}

View file

@ -0,0 +1,25 @@
#pragma once
class FlatLayerInfo {
private:
int height;
int id;
int data;
int start;
void _init(int height, int id);
public:
FlatLayerInfo(int height, int id);
FlatLayerInfo(int height, int id, int data);
int getHeight();
void setHeight(int height);
int getId();
void setId(int id);
int getData();
void setData(int data);
int getStart();
void setStart(int start);
std::wstring toString();
};

View file

@ -1,5 +1,4 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Util/PortableFileIO.h"
#include "../../Headers/net.minecraft.world.level.biome.h" #include "../../Headers/net.minecraft.world.level.biome.h"
#include "../../Headers/net.minecraft.world.level.newbiome.layer.h" #include "../../Headers/net.minecraft.world.level.newbiome.layer.h"
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
@ -8,23 +7,44 @@
BiomeOverrideLayer::BiomeOverrideLayer(int seedMixup) : Layer(seedMixup) { BiomeOverrideLayer::BiomeOverrideLayer(int seedMixup) : Layer(seedMixup) {
m_biomeOverride = byteArray(width * height); m_biomeOverride = byteArray(width * height);
#ifdef _WINDOWS64 #ifdef _UNICODE
const std::wstring path = L"GameRules\\biomemap.bin"; std::wstring path = L"GAME:\\GameRules\\biomemap.bin";
HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
#else #else
const std::wstring path = L"GAME:\\GameRules\\biomemap.bin"; #ifdef _WINDOWS64
std::string path = "GameRules\\biomemap.bin";
#else
std::string path = "GAME:\\GameRules\\biomemap.bin";
#endif #endif
const PortableFileIO::BinaryReadResult readResult = HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING,
PortableFileIO::ReadBinaryFile(path, m_biomeOverride.data, FILE_ATTRIBUTE_NORMAL, NULL);
m_biomeOverride.length); #endif
if (readResult.status == PortableFileIO::BinaryReadStatus::not_found) { if (file == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
// assert(false);
app.DebugPrintf("Biome override not found, using plains as default\n"); app.DebugPrintf("Biome override not found, using plains as default\n");
memset(m_biomeOverride.data, Biome::plains->id, m_biomeOverride.length); memset(m_biomeOverride.data, Biome::plains->id, m_biomeOverride.length);
} else if (readResult.status == } else {
PortableFileIO::BinaryReadStatus::too_large) { #ifdef _DURANGO
app.DebugPrintf("Biomemap binary is too large!!\n"); __debugbreak(); // TODO
__debugbreak(); DWORD bytesRead, dwFileSize = 0;
} else if (readResult.status != PortableFileIO::BinaryReadStatus::ok) { #else
app.FatalLoadError(); DWORD bytesRead, dwFileSize = GetFileSize(file, NULL);
#endif
if (dwFileSize > m_biomeOverride.length) {
app.DebugPrintf("Biomemap binary is too large!!\n");
__debugbreak();
}
BOOL bSuccess =
ReadFile(file, m_biomeOverride.data, dwFileSize, &bytesRead, NULL);
if (bSuccess == FALSE) {
app.FatalLoadError();
}
CloseHandle(file);
} }
} }
@ -50,4 +70,4 @@ intArray BiomeOverrideLayer::getArea(int xo, int yo, int w, int h) {
} }
} }
return result; return result;
} }

View file

@ -34,7 +34,7 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType) {
islandLayer = std::shared_ptr<Layer>(new ZoomLayer(2003, islandLayer)); islandLayer = std::shared_ptr<Layer>(new ZoomLayer(2003, islandLayer));
islandLayer = std::shared_ptr<Layer>(new AddIslandLayer(4, islandLayer)); islandLayer = std::shared_ptr<Layer>(new AddIslandLayer(4, islandLayer));
// islandLayer = std::shared_ptr<Layer>(new AddMushroomIslandLayer(5, // islandLayer = std::shared_ptr<Layer>(new AddMushroomIslandLayer(5,
//islandLayer)); // 4J - old position of mushroom island layer // islandLayer)); // 4J - old position of mushroom island layer
int zoomLevel = 4; int zoomLevel = 4;
if (levelType == LevelType::lvl_largeBiomes) { if (levelType == LevelType::lvl_largeBiomes) {
@ -105,7 +105,7 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType) {
#ifdef _BIOME_OVERRIDE #ifdef _BIOME_OVERRIDE
if (app.DebugSettingsOn() && if (app.DebugSettingsOn() &&
app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) & app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) &
(1L << eDebugSetting_EnableHeightWaterBiomeOverride)) { (1L << eDebugSetting_EnableBiomeOverride)) {
biomeLayer = biomeLayer =
std::shared_ptr<BiomeOverrideLayer>(new BiomeOverrideLayer(1)); std::shared_ptr<BiomeOverrideLayer>(new BiomeOverrideLayer(1));
} }

View file

@ -23,7 +23,6 @@ public:
static LayerArray getDefaultLayers(int64_t seed, LevelType* levelType); static LayerArray getDefaultLayers(int64_t seed, LevelType* levelType);
Layer(int64_t seedMixup); Layer(int64_t seedMixup);
virtual ~Layer() {}
virtual void init(int64_t seed); virtual void init(int64_t seed);
virtual void initRandom(int64_t x, int64_t y); virtual void initRandom(int64_t x, int64_t y);
@ -33,4 +32,4 @@ protected:
public: public:
virtual intArray getArea(int xo, int yo, int w, int h) = 0; virtual intArray getArea(int xo, int yo, int w, int h) = 0;
}; };

View file

@ -21,7 +21,7 @@ FlatLevelSource::FlatLevelSource(Level* level, int64_t seed,
seed); // 4J - added, so that we can have a separate random for doing seed); // 4J - added, so that we can have a separate random for doing
// post-processing in parallel with creation // post-processing in parallel with creation
villageFeature = new VillageFeature(0, m_XZSize); villageFeature = new VillageFeature(m_XZSize);
} }
FlatLevelSource::~FlatLevelSource() { FlatLevelSource::~FlatLevelSource() {
@ -124,3 +124,7 @@ TilePos* FlatLevelSource::findNearestMapFeature(Level* level,
int x, int y, int z) { int x, int y, int z) {
return NULL; return NULL;
} }
void FlatLevelSource::recreateLogicStructuresForChunk(int chunkX, int chunkZ) {
// TODO
}

View file

@ -43,4 +43,5 @@ public:
virtual TilePos* findNearestMapFeature(Level* level, virtual TilePos* findNearestMapFeature(Level* level,
const std::wstring& featureName, const std::wstring& featureName,
int x, int y, int z); int x, int y, int z);
virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ);
}; };

View file

@ -29,7 +29,7 @@ void HellFlatLevelSource::prepareHeights(int xOffs, int zOffs,
for (int yc = 0; yc < height; yc++) { for (int yc = 0; yc < height; yc++) {
int block = 0; int block = 0;
if ((yc <= 6) || (yc >= 121)) { if ((yc <= 6) || (yc >= 121)) {
block = Tile::hellRock_Id; block = Tile::netherRack_Id;
} }
blocks[xc << 11 | zc << 7 | yc] = (uint8_t)block; blocks[xc << 11 | zc << 7 | yc] = (uint8_t)block;
@ -194,3 +194,6 @@ TilePos* HellFlatLevelSource::findNearestMapFeature(
Level* level, const std::wstring& featureName, int x, int y, int z) { Level* level, const std::wstring& featureName, int x, int y, int z) {
return NULL; return NULL;
} }
void HellFlatLevelSource::recreateLogicStructuresForChunk(int chunkX,
int chunkZ) {}

View file

@ -50,4 +50,5 @@ public:
virtual TilePos* findNearestMapFeature(Level* level, virtual TilePos* findNearestMapFeature(Level* level,
const std::wstring& featureName, const std::wstring& featureName,
int x, int y, int z); int x, int y, int z);
virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ);
}; };

View file

@ -115,7 +115,7 @@ void HellRandomLevelSource::prepareHeights(int xOffs, int zOffs,
tileId = Tile::calmLava_Id; tileId = Tile::calmLava_Id;
} }
if (val > 0) { if (val > 0) {
tileId = Tile::hellRock_Id; tileId = Tile::netherRack_Id;
} }
blocks[offs] = (uint8_t)tileId; blocks[offs] = (uint8_t)tileId;
@ -167,8 +167,8 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs,
int run = -1; int run = -1;
uint8_t top = (uint8_t)Tile::hellRock_Id; uint8_t top = (uint8_t)Tile::netherRack_Id;
uint8_t material = (uint8_t)Tile::hellRock_Id; uint8_t material = (uint8_t)Tile::netherRack_Id;
for (int y = Level::genDepthMinusOne; y >= 0; y--) { for (int y = Level::genDepthMinusOne; y >= 0; y--) {
int offs = (z * 16 + x) * Level::genDepth + y; int offs = (z * 16 + x) * Level::genDepth + y;
@ -214,18 +214,18 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs,
if (old == 0) { if (old == 0) {
run = -1; run = -1;
} else if (old == Tile::hellRock_Id) { } else if (old == Tile::netherRack_Id) {
if (run == -1) { if (run == -1) {
if (runDepth <= 0) { if (runDepth <= 0) {
top = 0; top = 0;
material = (uint8_t)Tile::hellRock_Id; material = (uint8_t)Tile::netherRack_Id;
} else if (y >= waterHeight - 4 && } else if (y >= waterHeight - 4 &&
y <= waterHeight + 1) { y <= waterHeight + 1) {
top = (uint8_t)Tile::hellRock_Id; top = (uint8_t)Tile::netherRack_Id;
material = (uint8_t)Tile::hellRock_Id; material = (uint8_t)Tile::netherRack_Id;
if (gravel) top = (uint8_t)Tile::gravel_Id; if (gravel) top = (uint8_t)Tile::gravel_Id;
if (gravel) if (gravel)
material = (uint8_t)Tile::hellRock_Id; material = (uint8_t)Tile::netherRack_Id;
if (sand) { if (sand) {
// 4J Stu - Make some nether wart spawn // 4J Stu - Make some nether wart spawn
// outside of the nether fortresses // outside of the nether fortresses
@ -251,10 +251,10 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs,
offs = offs =
(z * 16 + x) * Level::genDepth + y; (z * 16 + x) * Level::genDepth + y;
} else { } else {
top = (uint8_t)Tile::hellSand_Id; top = (uint8_t)Tile::soulsand_Id;
} }
} }
if (sand) material = (uint8_t)Tile::hellSand_Id; if (sand) material = (uint8_t)Tile::soulsand_Id;
} }
if (y < waterHeight && top == 0) if (y < waterHeight && top == 0)
@ -451,10 +451,7 @@ void HellRandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
pprandom->setSeed(level->getSeed()); pprandom->setSeed(level->getSeed());
int64_t xScale = pprandom->nextLong() / 2 * 2 + 1; int64_t xScale = pprandom->nextLong() / 2 * 2 + 1;
int64_t zScale = pprandom->nextLong() / 2 * 2 + 1; int64_t zScale = pprandom->nextLong() / 2 * 2 + 1;
// 4jcraft added casts to a higher int and unsigned pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed());
pprandom->setSeed((((uint64_t)xt * (uint64_t)xScale) +
((uint64_t)zt * (uint64_t)zScale)) ^
level->getSeed());
netherBridgeFeature->postProcess(level, pprandom, xt, zt); netherBridgeFeature->postProcess(level, pprandom, xt, zt);
@ -462,7 +459,7 @@ void HellRandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
int x = xo + pprandom->nextInt(16) + 8; int x = xo + pprandom->nextInt(16) + 8;
int y = pprandom->nextInt(Level::genDepth - 8) + 4; int y = pprandom->nextInt(Level::genDepth - 8) + 4;
int z = zo + pprandom->nextInt(16) + 8; int z = zo + pprandom->nextInt(16) + 8;
HellSpringFeature(Tile::lava_Id).place(level, pprandom, x, y, z); HellSpringFeature(Tile::lava_Id, false).place(level, pprandom, x, y, z);
} }
int count = pprandom->nextInt(pprandom->nextInt(10) + 1) + 1; int count = pprandom->nextInt(pprandom->nextInt(10) + 1) + 1;
@ -493,17 +490,17 @@ void HellRandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
int x = xo + pprandom->nextInt(16) + 8; int x = xo + pprandom->nextInt(16) + 8;
int y = pprandom->nextInt(Level::genDepth); int y = pprandom->nextInt(Level::genDepth);
int z = zo + pprandom->nextInt(16) + 8; int z = zo + pprandom->nextInt(16) + 8;
FlowerFeature(Tile::mushroom1_Id).place(level, pprandom, x, y, z); FlowerFeature(Tile::mushroom_brown_Id).place(level, pprandom, x, y, z);
} }
if (pprandom->nextInt(1) == 0) { if (pprandom->nextInt(1) == 0) {
int x = xo + pprandom->nextInt(16) + 8; int x = xo + pprandom->nextInt(16) + 8;
int y = pprandom->nextInt(Level::genDepth); int y = pprandom->nextInt(Level::genDepth);
int z = zo + pprandom->nextInt(16) + 8; int z = zo + pprandom->nextInt(16) + 8;
FlowerFeature(Tile::mushroom2_Id).place(level, pprandom, x, y, z); FlowerFeature(Tile::mushroom_red_Id).place(level, pprandom, x, y, z);
} }
OreFeature quartzFeature(Tile::netherQuartz_Id, 13, Tile::hellRock_Id); OreFeature quartzFeature(Tile::netherQuartz_Id, 13, Tile::netherRack_Id);
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
int x = xo + pprandom->nextInt(16); int x = xo + pprandom->nextInt(16);
int y = pprandom->nextInt(Level::genDepth - 20) + 10; int y = pprandom->nextInt(Level::genDepth - 20) + 10;
@ -511,6 +508,14 @@ void HellRandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
quartzFeature.place(level, pprandom, x, y, z); quartzFeature.place(level, pprandom, x, y, z);
} }
for (int i = 0; i < 16; i++) {
int x = xo + random->nextInt(16);
int y = random->nextInt(Level::genDepth - 20) + 10;
int z = zo + random->nextInt(16);
HellSpringFeature hellSpringFeature(Tile::lava_Id, true);
hellSpringFeature.place(level, random, x, y, z);
}
HeavyTile::instaFall = false; HeavyTile::instaFall = false;
app.processSchematics(parent->getChunk(xt, zt)); app.processSchematics(parent->getChunk(xt, zt));
@ -532,9 +537,14 @@ std::wstring HellRandomLevelSource::gatherStats() {
std::vector<Biome::MobSpawnerData*>* HellRandomLevelSource::getMobsAt( std::vector<Biome::MobSpawnerData*>* HellRandomLevelSource::getMobsAt(
MobCategory* mobCategory, int x, int y, int z) { MobCategory* mobCategory, int x, int y, int z) {
// check if the coordinates is within a netherbridge // check if the coordinates is within a netherbridge
if (mobCategory == MobCategory::monster && if (mobCategory == MobCategory::monster) {
netherBridgeFeature->isInsideFeature(x, y, z)) { if (netherBridgeFeature->isInsideFeature(x, y, z)) {
return netherBridgeFeature->getBridgeEnemies(); return netherBridgeFeature->getBridgeEnemies();
}
if ((netherBridgeFeature->isInsideBoundingFeature(x, y, z) &&
level->getTile(x, y - 1, z) == Tile::netherBrick_Id)) {
return netherBridgeFeature->getBridgeEnemies();
}
} }
Biome* biome = level->getBiome(x, z); Biome* biome = level->getBiome(x, z);
@ -548,3 +558,8 @@ TilePos* HellRandomLevelSource::findNearestMapFeature(
Level* level, const std::wstring& featureName, int x, int y, int z) { Level* level, const std::wstring& featureName, int x, int y, int z) {
return NULL; return NULL;
} }
void HellRandomLevelSource::recreateLogicStructuresForChunk(int chunkX,
int chunkZ) {
netherBridgeFeature->apply(this, level, chunkX, chunkZ, NULL);
}

View file

@ -72,4 +72,5 @@ public:
virtual TilePos* findNearestMapFeature(Level* level, virtual TilePos* findNearestMapFeature(Level* level,
const std::wstring& featureName, const std::wstring& featureName,
int x, int y, int z); int x, int y, int z);
virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ);
}; };

View file

@ -101,7 +101,7 @@ void TheEndLevelRandomLevelSource::prepareHeights(int xOffs, int zOffs,
for (int z = 0; z < CHUNK_WIDTH; z++) { for (int z = 0; z < CHUNK_WIDTH; z++) {
int tileId = 0; int tileId = 0;
if (val > 0) { if (val > 0) {
tileId = Tile::whiteStone_Id; tileId = Tile::endStone_Id;
} else { } else {
} }
@ -132,8 +132,8 @@ void TheEndLevelRandomLevelSource::buildSurfaces(int xOffs, int zOffs,
int runDepth = 1; int runDepth = 1;
int run = -1; int run = -1;
uint8_t top = (uint8_t)Tile::whiteStone_Id; uint8_t top = (uint8_t)Tile::endStone_Id;
uint8_t material = (uint8_t)Tile::whiteStone_Id; uint8_t material = (uint8_t)Tile::endStone_Id;
for (int y = Level::genDepthMinusOne; y >= 0; y--) { for (int y = Level::genDepthMinusOne; y >= 0; y--) {
int offs = (z * 16 + x) * Level::genDepth + y; int offs = (z * 16 + x) * Level::genDepth + y;
@ -142,11 +142,11 @@ void TheEndLevelRandomLevelSource::buildSurfaces(int xOffs, int zOffs,
if (old == 0) { if (old == 0) {
run = -1; run = -1;
} else if (old == Tile::rock_Id) { } else if (old == Tile::stone_Id) {
if (run == -1) { if (run == -1) {
if (runDepth <= 0) { if (runDepth <= 0) {
top = 0; top = 0;
material = (uint8_t)Tile::whiteStone_Id; material = (uint8_t)Tile::endStone_Id;
} }
run = runDepth; run = runDepth;
@ -199,8 +199,8 @@ LevelChunk* TheEndLevelRandomLevelSource::getChunk(int xOffs, int zOffs) {
levelChunk->recalcHeightmap(); levelChunk->recalcHeightmap();
// delete blocks.data; // Don't delete the blocks as the array data is // delete blocks.data; // Don't delete the blocks as the array data is
// actually owned by the chunk now 4jcraft changed to [] // actually owned by the chunk now
delete[] biomes.data; delete biomes.data;
return levelChunk; return levelChunk;
} }
@ -354,19 +354,21 @@ void TheEndLevelRandomLevelSource::calcWaterDepths(ChunkSource* parent, int xt,
int od = int od =
level->getData(xp + x2, y, zp + z2); level->getData(xp + x2, y, zp + z2);
if (od < 7 && od < d) { if (od < 7 && od < d) {
level->setData(xp + x2, y, zp + z2, level->setData(
d); xp + x2, y, zp + z2, d,
Tile::UPDATE_CLIENTS);
} }
} }
} }
} }
} }
if (hadWater) { if (hadWater) {
level->setTileAndDataNoUpdate( level->setTileAndData(xp, y, zp, Tile::calmWater_Id,
xp, y, zp, Tile::calmWater_Id, 7); 7, Tile::UPDATE_CLIENTS);
for (int y2 = 0; y2 < y; y2++) { for (int y2 = 0; y2 < y; y2++) {
level->setTileAndDataNoUpdate( level->setTileAndData(xp, y2, zp,
xp, y2, zp, Tile::calmWater_Id, 8); Tile::calmWater_Id, 8,
Tile::UPDATE_CLIENTS);
} }
} }
} }
@ -391,9 +393,7 @@ void TheEndLevelRandomLevelSource::postProcess(ChunkSource* parent, int xt,
pprandom->setSeed(level->getSeed()); pprandom->setSeed(level->getSeed());
int64_t xScale = pprandom->nextLong() / 2 * 2 + 1; int64_t xScale = pprandom->nextLong() / 2 * 2 + 1;
int64_t zScale = pprandom->nextLong() / 2 * 2 + 1; int64_t zScale = pprandom->nextLong() / 2 * 2 + 1;
// 4jcraft added cast to higher int and unsigned pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed());
pprandom->setSeed((((uint64_t)xt * xScale) + ((uint64_t)zt * zScale)) ^
level->getSeed());
Biome* biome = level->getBiome(xo + 16, zo + 16); Biome* biome = level->getBiome(xo + 16, zo + 16);
biome->decorate( biome->decorate(
@ -432,3 +432,7 @@ TilePos* TheEndLevelRandomLevelSource::findNearestMapFeature(
Level* level, const std::wstring& featureName, int x, int y, int z) { Level* level, const std::wstring& featureName, int x, int y, int z) {
return NULL; return NULL;
} }
void TheEndLevelRandomLevelSource::recreateLogicStructuresForChunk(int chunkX,
int chunkZ) {
}

View file

@ -65,4 +65,5 @@ public:
virtual TilePos* findNearestMapFeature(Level* level, virtual TilePos* findNearestMapFeature(Level* level,
const std::wstring& featureName, const std::wstring& featureName,
int x, int y, int z); int x, int y, int z);
virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ);
}; };

View file

@ -0,0 +1,101 @@
#include "../Platform/stdafx.h"
#include "../Headers/net.minecraft.world.level.levelgen.structure.h"
#include "StructureFeatureIO.h"
std::unordered_map<std::wstring, structureStartCreateFn>
StructureFeatureIO::startIdClassMap;
std::unordered_map<unsigned int, std::wstring>
StructureFeatureIO::startClassIdMap;
std::unordered_map<std::wstring, structurePieceCreateFn>
StructureFeatureIO::pieceIdClassMap;
std::unordered_map<unsigned int, std::wstring>
StructureFeatureIO::pieceClassIdMap;
void StructureFeatureIO::setStartId(EStructureStart clas,
structureStartCreateFn createFn,
const std::wstring& id) {
startIdClassMap[id] = createFn;
startClassIdMap[clas] = id;
}
void StructureFeatureIO::setPieceId(EStructurePiece clas,
structurePieceCreateFn createFn,
const std::wstring& id) {
pieceIdClassMap[id] = createFn;
pieceClassIdMap[clas] = id;
}
void StructureFeatureIO::staticCtor() {
setStartId(eStructureStart_MineShaftStart, MineShaftStart::Create,
L"Mineshaft");
setStartId(eStructureStart_VillageStart,
VillageFeature::VillageStart::Create, L"Village");
setStartId(eStructureStart_NetherBridgeStart,
NetherBridgeFeature::NetherBridgeStart::Create, L"Fortress");
setStartId(eStructureStart_StrongholdStart,
StrongholdFeature::StrongholdStart::Create, L"Stronghold");
setStartId(eStructureStart_ScatteredFeatureStart,
RandomScatteredLargeFeature::ScatteredFeatureStart::Create,
L"Temple");
MineShaftPieces::loadStatic();
VillagePieces::loadStatic();
NetherBridgePieces::loadStatic();
StrongholdPieces::loadStatic();
ScatteredFeaturePieces::loadStatic();
}
std::wstring StructureFeatureIO::getEncodeId(StructureStart* start) {
AUTO_VAR(it, startClassIdMap.find(start->GetType()));
if (it != startClassIdMap.end()) {
return it->second;
} else {
return L"";
}
}
std::wstring StructureFeatureIO::getEncodeId(StructurePiece* piece) {
AUTO_VAR(it, pieceClassIdMap.find(piece->GetType()));
if (it != pieceClassIdMap.end()) {
return it->second;
} else {
return L"";
}
}
StructureStart* StructureFeatureIO::loadStaticStart(CompoundTag* tag,
Level* level) {
StructureStart* start = NULL;
AUTO_VAR(it, startIdClassMap.find(tag->getString(L"id")));
if (it != startIdClassMap.end()) {
start = (it->second)();
}
if (start != NULL) {
start->load(level, tag);
} else {
app.DebugPrintf("Skipping Structure with id %ls",
tag->getString(L"id").c_str());
}
return start;
}
StructurePiece* StructureFeatureIO::loadStaticPiece(CompoundTag* tag,
Level* level) {
StructurePiece* piece = NULL;
AUTO_VAR(it, pieceIdClassMap.find(tag->getString(L"id")));
if (it != pieceIdClassMap.end()) {
piece = (it->second)();
}
if (piece != NULL) {
piece->load(level, tag);
} else {
app.DebugPrintf("Skipping Piece with id %ls",
tag->getString(L"id").c_str());
}
return piece;
}

View file

@ -0,0 +1,96 @@
#pragma once
class StructurePiece;
class StructureStart;
typedef StructurePiece* (*structurePieceCreateFn)();
typedef StructureStart* (*structureStartCreateFn)();
enum EStructureStart {
eStructureStart_MineShaftStart,
eStructureStart_VillageStart,
eStructureStart_NetherBridgeStart,
eStructureStart_StrongholdStart,
eStructureStart_ScatteredFeatureStart,
};
enum EStructurePiece {
eStructurePiece_MineShaftRoom,
eStructurePiece_MineShaftCorridor,
eStructurePiece_MineShaftCrossing,
eStructurePiece_MineShaftStairs,
eStructurePiece_BridgeStraight,
eStructurePiece_BridgeEndFiller,
eStructurePiece_BridgeCrossing,
eStructurePiece_RoomCrossing,
eStructurePiece_StairsRoom,
eStructurePiece_MonsterThrone,
eStructurePiece_CastleEntrance,
eStructurePiece_CastleStalkRoom,
eStructurePiece_CastleSmallCorridorPiece,
eStructurePiece_CastleSmallCorridorCrossingPiece,
eStructurePiece_CastleSmallCorridorRightTurnPiece,
eStructurePiece_CastleSmallCorridorLeftTurnPiece,
eStructurePiece_CastleCorridorStairsPiece,
eStructurePiece_CastleCorridorTBalconyPiece,
eStructurePiece_NetherBridgeStartPiece,
eStructurePiece_DesertPyramidPiece,
eStructurePiece_JunglePyramidPiece,
eStructurePiece_SwamplandHut,
eStructurePiece_FillerCorridor,
eStructurePiece_StairsDown,
eStructurePiece_Straight,
eStructurePiece_ChestCorridor,
eStructurePiece_StraightStairsDown,
eStructurePiece_LeftTurn,
eStructurePiece_RightTurn,
eStructurePiece_StrongholdRoomCrossing,
eStructurePiece_PrisonHall,
eStructurePiece_Library,
eStructurePiece_FiveCrossing,
eStructurePiece_PortalRoom,
eStructurePiece_StrongholdStartPiece,
eStructurePiece_Well,
eStructurePiece_StraightRoad,
eStructurePiece_SimpleHouse,
eStructurePiece_SmallTemple,
eStructurePiece_BookHouse,
eStructurePiece_SmallHut,
eStructurePiece_PigHouse,
eStructurePiece_TwoRoomHouse,
eStructurePiece_Smithy,
eStructurePiece_Farmland,
eStructurePiece_DoubleFarmland,
eStructurePiece_LightPost,
eStructurePiece_VillageStartPiece,
};
class StructureFeatureIO {
private:
static std::unordered_map<std::wstring, structureStartCreateFn>
startIdClassMap;
static std::unordered_map<unsigned int, std::wstring> startClassIdMap;
static std::unordered_map<std::wstring, structurePieceCreateFn>
pieceIdClassMap;
static std::unordered_map<unsigned int, std::wstring> pieceClassIdMap;
public:
static void setStartId(EStructureStart clas,
structureStartCreateFn createFn,
const std::wstring& id);
static void setPieceId(EStructurePiece clas,
structurePieceCreateFn createFn,
const std::wstring& id);
public:
static void staticCtor();
static std::wstring getEncodeId(StructureStart* start);
static std::wstring getEncodeId(StructurePiece* piece);
static StructureStart* loadStaticStart(CompoundTag* tag, Level* level);
static StructurePiece* loadStaticPiece(CompoundTag* tag, Level* level);
};

View file

@ -0,0 +1,38 @@
#include "../Platform/stdafx.h"
#include "StructureFeatureSavedData.h"
std::wstring StructureFeatureSavedData::TAG_FEATURES = L"Features";
StructureFeatureSavedData::StructureFeatureSavedData(const std::wstring& idName)
: SavedData(idName) {
this->pieceTags = new CompoundTag(TAG_FEATURES);
}
StructureFeatureSavedData::~StructureFeatureSavedData() { delete pieceTags; }
void StructureFeatureSavedData::load(CompoundTag* tag) {
this->pieceTags = tag->getCompound(TAG_FEATURES);
}
void StructureFeatureSavedData::save(CompoundTag* tag) {
tag->put(TAG_FEATURES, pieceTags->copy());
}
CompoundTag* StructureFeatureSavedData::getFeatureTag(int chunkX, int chunkZ) {
return pieceTags->getCompound(createFeatureTagId(chunkX, chunkZ));
}
void StructureFeatureSavedData::putFeatureTag(CompoundTag* tag, int chunkX,
int chunkZ) {
std::wstring name = createFeatureTagId(chunkX, chunkZ);
tag->setName(name);
pieceTags->put(name, tag);
}
std::wstring StructureFeatureSavedData::createFeatureTagId(int chunkX,
int chunkZ) {
return L"[" + _toString<int>(chunkX) + L"," + _toString<int>(chunkZ) + L"]";
}
CompoundTag* StructureFeatureSavedData::getFullTag() { return pieceTags; }

View file

@ -0,0 +1,20 @@
#pragma once
#include "../Level/Storage/SavedData.h"
class StructureFeatureSavedData : public SavedData {
private:
static std::wstring TAG_FEATURES;
CompoundTag* pieceTags;
public:
StructureFeatureSavedData(const std::wstring& idName);
~StructureFeatureSavedData();
void load(CompoundTag* tag);
void save(CompoundTag* tag);
CompoundTag* getFeatureTag(int chunkX, int chunkZ);
void putFeatureTag(CompoundTag* tag, int chunkX, int chunkZ);
std::wstring createFeatureTagId(int chunkX, int chunkZ);
CompoundTag* getFullTag();
};

View file

@ -1,4 +1,5 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.world.entity.item.h"
#include "../../Headers/net.minecraft.world.level.levelgen.structure.h" #include "../../Headers/net.minecraft.world.level.levelgen.structure.h"
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
@ -12,7 +13,7 @@ WeighedTreasureArray MineShaftPieces::smallTreasureItems;
; ;
void MineShaftPieces::staticCtor() { void MineShaftPieces::staticCtor() {
smallTreasureItems = WeighedTreasureArray(11); smallTreasureItems = WeighedTreasureArray(13);
smallTreasureItems[0] = smallTreasureItems[0] =
new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10); new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10);
smallTreasureItems[1] = new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5); smallTreasureItems[1] = new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5);
@ -28,9 +29,23 @@ void MineShaftPieces::staticCtor() {
smallTreasureItems[8] = new WeighedTreasure(Tile::rail_Id, 0, 4, 8, 1); smallTreasureItems[8] = new WeighedTreasure(Tile::rail_Id, 0, 4, 8, 1);
smallTreasureItems[9] = smallTreasureItems[9] =
new WeighedTreasure(Item::seeds_melon_Id, 0, 2, 4, 10); new WeighedTreasure(Item::seeds_melon_Id, 0, 2, 4, 10);
// 4J-PB - Adding from 1.2.3
smallTreasureItems[10] = smallTreasureItems[10] =
new WeighedTreasure(Item::seeds_pumpkin_Id, 0, 2, 4, 10); new WeighedTreasure(Item::seeds_pumpkin_Id, 0, 2, 4, 10);
// very rare for shafts ...
smallTreasureItems[11] = new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 3);
smallTreasureItems[12] =
new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1);
}
void MineShaftPieces::loadStatic() {
StructureFeatureIO::setPieceId(eStructurePiece_MineShaftCorridor,
MineShaftCorridor::Create, L"MSCorridor");
StructureFeatureIO::setPieceId(eStructurePiece_MineShaftCrossing,
MineShaftCrossing::Create, L"MSCrossing");
StructureFeatureIO::setPieceId(eStructurePiece_MineShaftRoom,
MineShaftRoom::Create, L"MSRoom");
StructureFeatureIO::setPieceId(eStructurePiece_MineShaftStairs,
MineShaftStairs::Create, L"MSStairs");
} }
StructurePiece* MineShaftPieces::createRandomShaftPiece( StructurePiece* MineShaftPieces::createRandomShaftPiece(
@ -85,6 +100,10 @@ StructurePiece* MineShaftPieces::generateAndAddPiece(
return newPiece; return newPiece;
} }
MineShaftPieces::MineShaftRoom::MineShaftRoom() {
// for reflection
}
MineShaftPieces::MineShaftRoom::MineShaftRoom(int genDepth, Random* random, MineShaftPieces::MineShaftRoom::MineShaftRoom(int genDepth, Random* random,
int west, int north) int west, int north)
: StructurePiece(genDepth) { : StructurePiece(genDepth) {
@ -221,6 +240,44 @@ bool MineShaftPieces::MineShaftRoom::postProcess(Level* level, Random* random,
return true; return true;
} }
void MineShaftPieces::MineShaftRoom::addAdditonalSaveData(CompoundTag* tag) {
ListTag<IntArrayTag>* entrances = new ListTag<IntArrayTag>(L"Entrances");
for (AUTO_VAR(it, childEntranceBoxes.begin());
it != childEntranceBoxes.end(); ++it) {
BoundingBox* bb = *it;
entrances->add(bb->createTag(L""));
}
tag->put(L"Entrances", entrances);
}
void MineShaftPieces::MineShaftRoom::readAdditonalSaveData(CompoundTag* tag) {
ListTag<IntArrayTag>* entrances =
(ListTag<IntArrayTag>*)tag->getList(L"Entrances");
for (int i = 0; i < entrances->size(); i++) {
childEntranceBoxes.push_back(new BoundingBox(entrances->get(i)->data));
}
}
MineShaftPieces::MineShaftCorridor::MineShaftCorridor() {
// for reflection
}
void MineShaftPieces::MineShaftCorridor::addAdditonalSaveData(
CompoundTag* tag) {
tag->putBoolean(L"hr", hasRails);
tag->putBoolean(L"sc", spiderCorridor);
tag->putBoolean(L"hps", hasPlacedSpider);
tag->putInt(L"Num", numSections);
}
void MineShaftPieces::MineShaftCorridor::readAdditonalSaveData(
CompoundTag* tag) {
hasRails = tag->getBoolean(L"hr");
spiderCorridor = tag->getBoolean(L"sc");
hasPlacedSpider = tag->getBoolean(L"hps");
numSections = tag->getInt(L"Num");
}
MineShaftPieces::MineShaftCorridor::MineShaftCorridor(int genDepth, MineShaftPieces::MineShaftCorridor::MineShaftCorridor(int genDepth,
Random* random, Random* random,
BoundingBox* corridorBox, BoundingBox* corridorBox,
@ -404,6 +461,33 @@ void MineShaftPieces::MineShaftCorridor::addChildren(
} }
} }
bool MineShaftPieces::MineShaftCorridor::createChest(
Level* level, BoundingBox* chunkBB, Random* random, int x, int y, int z,
WeighedTreasureArray treasure, int numRolls) {
int worldX = getWorldX(x, z);
int worldY = getWorldY(y);
int worldZ = getWorldZ(x, z);
if (chunkBB->isInside(worldX, worldY, worldZ)) {
if (level->getTile(worldX, worldY, worldZ) == 0) {
level->setTileAndData(
worldX, worldY, worldZ, Tile::rail_Id,
getOrientationData(Tile::rail_Id, random->nextBoolean()
? RailTile::DIR_FLAT_X
: RailTile::DIR_FLAT_Z),
Tile::UPDATE_CLIENTS);
std::shared_ptr<MinecartChest> chest =
std::shared_ptr<MinecartChest>(new MinecartChest(
level, worldX + 0.5f, worldY + 0.5f, worldZ + 0.5f));
WeighedTreasure::addChestItems(random, treasure, chest, numRolls);
level->addEntity(chest);
return true;
}
}
return false;
}
bool MineShaftPieces::MineShaftCorridor::postProcess(Level* level, bool MineShaftPieces::MineShaftCorridor::postProcess(Level* level,
Random* random, Random* random,
BoundingBox* chunkBB) { BoundingBox* chunkBB) {
@ -490,11 +574,13 @@ bool MineShaftPieces::MineShaftCorridor::postProcess(Level* level,
newZ = getWorldZ(x0 + 1, newZ); newZ = getWorldZ(x0 + 1, newZ);
if (chunkBB->isInside(x, y, newZ)) { if (chunkBB->isInside(x, y, newZ)) {
hasPlacedSpider = true; hasPlacedSpider = true;
level->setTile(x, y, newZ, Tile::mobSpawner_Id); level->setTileAndData(x, y, newZ, Tile::mobSpawner_Id, 0,
Tile::UPDATE_CLIENTS);
std::shared_ptr<MobSpawnerTileEntity> entity = std::shared_ptr<MobSpawnerTileEntity> entity =
std::dynamic_pointer_cast<MobSpawnerTileEntity>( std::dynamic_pointer_cast<MobSpawnerTileEntity>(
level->getTileEntity(x, y, newZ)); level->getTileEntity(x, y, newZ));
if (entity != NULL) entity->setEntityId(L"CaveSpider"); if (entity != NULL)
entity->getSpawner()->setEntityId(L"CaveSpider");
} }
} }
} }
@ -515,7 +601,8 @@ bool MineShaftPieces::MineShaftCorridor::postProcess(Level* level,
if (floor > 0 && Tile::solid[floor]) { if (floor > 0 && Tile::solid[floor]) {
maybeGenerateBlock( maybeGenerateBlock(
level, chunkBB, random, .7f, x0 + 1, y0, z, Tile::rail_Id, level, chunkBB, random, .7f, x0 + 1, y0, z, Tile::rail_Id,
getOrientationData(Tile::rail_Id, RailTile::DIR_FLAT_Z)); getOrientationData(Tile::rail_Id,
BaseRailTile::DIR_FLAT_Z));
} }
} }
} }
@ -523,6 +610,22 @@ bool MineShaftPieces::MineShaftCorridor::postProcess(Level* level,
return true; return true;
} }
MineShaftPieces::MineShaftCrossing::MineShaftCrossing() {
// for reflection
}
void MineShaftPieces::MineShaftCrossing::addAdditonalSaveData(
CompoundTag* tag) {
tag->putBoolean(L"tf", isTwoFloored);
tag->putInt(L"D", direction);
}
void MineShaftPieces::MineShaftCrossing::readAdditonalSaveData(
CompoundTag* tag) {
isTwoFloored = tag->getBoolean(L"tf");
direction = tag->getInt(L"D");
}
MineShaftPieces::MineShaftCrossing::MineShaftCrossing(int genDepth, MineShaftPieces::MineShaftCrossing::MineShaftCrossing(int genDepth,
Random* random, Random* random,
BoundingBox* crossingBox, BoundingBox* crossingBox,
@ -716,6 +819,10 @@ bool MineShaftPieces::MineShaftCrossing::postProcess(Level* level,
return true; return true;
} }
MineShaftPieces::MineShaftStairs::MineShaftStairs() {
// for reflection
}
MineShaftPieces::MineShaftStairs::MineShaftStairs(int genDepth, Random* random, MineShaftPieces::MineShaftStairs::MineShaftStairs(int genDepth, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
int direction) int direction)
@ -724,6 +831,11 @@ MineShaftPieces::MineShaftStairs::MineShaftStairs(int genDepth, Random* random,
boundingBox = stairsBox; boundingBox = stairsBox;
} }
void MineShaftPieces::MineShaftStairs::addAdditonalSaveData(CompoundTag* tag) {}
void MineShaftPieces::MineShaftStairs::readAdditonalSaveData(CompoundTag* tag) {
}
BoundingBox* MineShaftPieces::MineShaftStairs::findStairs( BoundingBox* MineShaftPieces::MineShaftStairs::findStairs(
std::list<StructurePiece*>* pieces, Random* random, int footX, int footY, std::list<StructurePiece*>* pieces, Random* random, int footX, int footY,
int footZ, int direction) { int footZ, int direction) {

View file

@ -10,6 +10,10 @@ private:
static const int MAX_DEPTH = 8; // 1.2.3 change static const int MAX_DEPTH = 8; // 1.2.3 change
public:
static void loadStatic();
private:
static StructurePiece* createRandomShaftPiece( static StructurePiece* createRandomShaftPiece(
std::list<StructurePiece*>* pieces, Random* random, int footX, std::list<StructurePiece*>* pieces, Random* random, int footX,
int footY, int footZ, int direction, int genDepth); int footY, int footZ, int direction, int genDepth);
@ -24,10 +28,17 @@ private:
*/ */
public: public:
class MineShaftRoom : public StructurePiece { class MineShaftRoom : public StructurePiece {
public:
static StructurePiece* Create() { return new MineShaftRoom(); }
virtual EStructurePiece GetType() {
return eStructurePiece_MineShaftRoom;
}
private: private:
std::list<BoundingBox*> childEntranceBoxes; std::list<BoundingBox*> childEntranceBoxes;
public: public:
MineShaftRoom();
MineShaftRoom(int genDepth, Random* random, int west, int north); MineShaftRoom(int genDepth, Random* random, int west, int north);
~MineShaftRoom(); ~MineShaftRoom();
@ -36,6 +47,10 @@ public:
Random* random); Random* random);
virtual bool postProcess(Level* level, Random* random, virtual bool postProcess(Level* level, Random* random,
BoundingBox* chunkBB); BoundingBox* chunkBB);
protected:
void addAdditonalSaveData(CompoundTag* tag);
void readAdditonalSaveData(CompoundTag* tag);
}; };
/** /**
@ -43,12 +58,25 @@ public:
* *
*/ */
class MineShaftCorridor : public StructurePiece { class MineShaftCorridor : public StructurePiece {
public:
static StructurePiece* Create() { return new MineShaftCorridor(); }
virtual EStructurePiece GetType() {
return eStructurePiece_MineShaftCorridor;
}
private: private:
bool hasRails; // was final bool hasRails; // was final
bool spiderCorridor; // was final bool spiderCorridor; // was final
bool hasPlacedSpider; bool hasPlacedSpider;
int numSections; int numSections;
public:
MineShaftCorridor();
protected:
void addAdditonalSaveData(CompoundTag* tag);
void readAdditonalSaveData(CompoundTag* tag);
public: public:
MineShaftCorridor(int genDepth, Random* random, MineShaftCorridor(int genDepth, Random* random,
BoundingBox* corridorBox, int direction); BoundingBox* corridorBox, int direction);
@ -60,6 +88,13 @@ public:
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, std::list<StructurePiece*>* pieces,
Random* random); Random* random);
protected:
virtual bool createChest(Level* level, BoundingBox* chunkBB,
Random* random, int x, int y, int z,
WeighedTreasureArray treasure, int numRolls);
public:
virtual bool postProcess(Level* level, Random* random, virtual bool postProcess(Level* level, Random* random,
BoundingBox* chunkBB); BoundingBox* chunkBB);
}; };
@ -69,9 +104,22 @@ public:
* *
*/ */
class MineShaftCrossing : public StructurePiece { class MineShaftCrossing : public StructurePiece {
public:
static StructurePiece* Create() { return new MineShaftCrossing(); }
virtual EStructurePiece GetType() {
return eStructurePiece_MineShaftCrossing;
}
private: private:
const int direction; int direction;
const bool isTwoFloored; bool isTwoFloored;
public:
MineShaftCrossing();
protected:
void addAdditonalSaveData(CompoundTag* tag);
void readAdditonalSaveData(CompoundTag* tag);
public: public:
MineShaftCrossing(int genDepth, Random* random, MineShaftCrossing(int genDepth, Random* random,
@ -93,9 +141,21 @@ public:
*/ */
class MineShaftStairs : public StructurePiece { class MineShaftStairs : public StructurePiece {
public: public:
static StructurePiece* Create() { return new MineShaftStairs(); }
virtual EStructurePiece GetType() {
return eStructurePiece_MineShaftStairs;
}
public:
MineShaftStairs();
MineShaftStairs(int genDepth, Random* random, BoundingBox* stairsBox, MineShaftStairs(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
protected:
void addAdditonalSaveData(CompoundTag* tag);
void readAdditonalSaveData(CompoundTag* tag);
public:
static BoundingBox* findStairs(std::list<StructurePiece*>* pieces, static BoundingBox* findStairs(std::list<StructurePiece*>* pieces,
Random* random, int footX, int footY, Random* random, int footX, int footY,
int footZ, int direction); int footZ, int direction);

View file

@ -1,16 +1,19 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.world.level.levelgen.structure.h" #include "../../Headers/net.minecraft.world.level.levelgen.structure.h"
MineShaftStart::MineShaftStart() {
// for reflection
}
MineShaftStart::MineShaftStart(Level* level, Random* random, int chunkX, MineShaftStart::MineShaftStart(Level* level, Random* random, int chunkX,
int chunkZ) { int chunkZ)
// 4jcraft added to unsigned : StructureStart(chunkX, chunkZ) {
MineShaftPieces::MineShaftRoom* mineShaftRoom = MineShaftPieces::MineShaftRoom* mineShaftRoom =
new MineShaftPieces::MineShaftRoom(0, random, new MineShaftPieces::MineShaftRoom(0, random, (chunkX << 4) + 2,
((unsigned)chunkX << 4) + 2, (chunkZ << 4) + 2);
((unsigned)chunkZ << 4) + 2);
pieces.push_back(mineShaftRoom); pieces.push_back(mineShaftRoom);
mineShaftRoom->addChildren(mineShaftRoom, &pieces, random); mineShaftRoom->addChildren(mineShaftRoom, &pieces, random);
calculateBoundingBox(); calculateBoundingBox();
moveBelowSeaLevel(level, random, 10); moveBelowSeaLevel(level, random, 10);
} }

View file

@ -4,5 +4,10 @@
class MineShaftStart : public StructureStart { class MineShaftStart : public StructureStart {
public: public:
static StructureStart* Create() { return new MineShaftStart(); }
virtual EStructureStart GetType() { return eStructureStart_MineShaftStart; }
public:
MineShaftStart();
MineShaftStart(Level* level, Random* random, int chunkX, int chunkZ); MineShaftStart(Level* level, Random* random, int chunkX, int chunkZ);
}; };

View file

@ -1,12 +1,52 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.world.item.h"
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
#include "../../Headers/net.minecraft.world.level.tile.entity.h" #include "../../Headers/net.minecraft.world.level.tile.entity.h"
#include "../../Headers/net.minecraft.world.level.levelgen.h" #include "../../Headers/net.minecraft.world.level.levelgen.h"
#include "../../Headers/net.minecraft.world.level.storage.h" #include "../../Headers/net.minecraft.world.level.storage.h"
#include "../../Headers/net.minecraft.world.level.levelgen.structure.h"
#include "../../Util/WeighedTreasure.h"
#include "NetherBridgePieces.h" #include "NetherBridgePieces.h"
#include "../../Util/Direction.h" #include "../../Util/Direction.h"
void NetherBridgePieces::loadStatic() {
StructureFeatureIO::setPieceId(eStructurePiece_BridgeCrossing,
BridgeCrossing::Create, L"NeBCr");
StructureFeatureIO::setPieceId(eStructurePiece_BridgeEndFiller,
BridgeEndFiller::Create, L"NeBEF");
StructureFeatureIO::setPieceId(eStructurePiece_BridgeStraight,
BridgeStraight::Create, L"NeBS");
StructureFeatureIO::setPieceId(eStructurePiece_CastleCorridorStairsPiece,
CastleCorridorStairsPiece::Create, L"NeCCS");
StructureFeatureIO::setPieceId(eStructurePiece_CastleCorridorTBalconyPiece,
CastleCorridorTBalconyPiece::Create,
L"NeCTB");
StructureFeatureIO::setPieceId(eStructurePiece_CastleEntrance,
CastleEntrance::Create, L"NeCE");
StructureFeatureIO::setPieceId(
eStructurePiece_CastleSmallCorridorCrossingPiece,
CastleSmallCorridorCrossingPiece::Create, L"NeSCSC");
StructureFeatureIO::setPieceId(
eStructurePiece_CastleSmallCorridorLeftTurnPiece,
CastleSmallCorridorLeftTurnPiece::Create, L"NeSCLT");
StructureFeatureIO::setPieceId(eStructurePiece_CastleSmallCorridorPiece,
CastleSmallCorridorPiece::Create, L"NeSC");
StructureFeatureIO::setPieceId(
eStructurePiece_CastleSmallCorridorRightTurnPiece,
CastleSmallCorridorRightTurnPiece::Create, L"NeSCRT");
StructureFeatureIO::setPieceId(eStructurePiece_CastleStalkRoom,
CastleStalkRoom::Create, L"NeCSR");
StructureFeatureIO::setPieceId(eStructurePiece_MonsterThrone,
MonsterThrone::Create, L"NeMT");
StructureFeatureIO::setPieceId(eStructurePiece_RoomCrossing,
RoomCrossing::Create, L"NeRC");
StructureFeatureIO::setPieceId(eStructurePiece_StairsRoom,
StairsRoom::Create, L"NeSR");
StructureFeatureIO::setPieceId(eStructurePiece_NetherBridgeStartPiece,
StartPiece::Create, L"NeStart");
}
NetherBridgePieces::PieceWeight::PieceWeight(EPieceClass pieceClass, int weight, NetherBridgePieces::PieceWeight::PieceWeight(EPieceClass pieceClass, int weight,
int maxPlaceCount, bool allowInRow) int maxPlaceCount, bool allowInRow)
: weight(weight) { : weight(weight) {
@ -113,9 +153,34 @@ NetherBridgePieces::findAndCreateBridgePieceFactory(
return structurePiece; return structurePiece;
} }
WeighedTreasure* NetherBridgePieces::NetherBridgePiece::fortressTreasureItems
[FORTRESS_TREASURE_ITEMS_COUNT] = {
new WeighedTreasure(Item::diamond_Id, 0, 1, 3, 5),
new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 5),
new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 15),
new WeighedTreasure(Item::sword_gold_Id, 0, 1, 1, 5),
new WeighedTreasure(Item::chestplate_gold_Id, 0, 1, 1, 5),
new WeighedTreasure(Item::flintAndSteel_Id, 0, 1, 1, 5),
new WeighedTreasure(Item::netherwart_seeds_Id, 0, 3, 7, 5),
new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 10),
new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 8),
new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 5),
new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 3),
};
NetherBridgePieces::NetherBridgePiece::NetherBridgePiece() {
// for reflection
}
NetherBridgePieces::NetherBridgePiece::NetherBridgePiece(int genDepth) NetherBridgePieces::NetherBridgePiece::NetherBridgePiece(int genDepth)
: StructurePiece(genDepth) {} : StructurePiece(genDepth) {}
void NetherBridgePieces::NetherBridgePiece::readAdditonalSaveData(
CompoundTag* tag) {}
void NetherBridgePieces::NetherBridgePiece::addAdditonalSaveData(
CompoundTag* tag) {}
int NetherBridgePieces::NetherBridgePiece::updatePieceWeight( int NetherBridgePieces::NetherBridgePiece::updatePieceWeight(
std::list<PieceWeight*>* currentPieces) { std::list<PieceWeight*>* currentPieces) {
bool hasAnyPieces = false; bool hasAnyPieces = false;
@ -323,17 +388,17 @@ void NetherBridgePieces::NetherBridgePiece::generateLightPost(
level->isEmptyTile(worldX, worldY + 1, worldZ) && level->isEmptyTile(worldX, worldY + 1, worldZ) &&
level->isEmptyTile(worldX, worldY + 2, worldZ) && level->isEmptyTile(worldX, worldY + 2, worldZ) &&
level->isEmptyTile(worldX, worldY + 3, worldZ)) { level->isEmptyTile(worldX, worldY + 3, worldZ)) {
level->setTileAndDataNoUpdate(worldX, worldY, worldZ, level->setTileAndData(worldX, worldY, worldZ, Tile::netherFence_Id, 0,
Tile::netherFence_Id, 0); Tile::UPDATE_CLIENTS);
level->setTileAndDataNoUpdate(worldX, worldY + 1, worldZ, level->setTileAndData(worldX, worldY + 1, worldZ, Tile::netherFence_Id,
Tile::netherFence_Id, 0); 0, Tile::UPDATE_CLIENTS);
level->setTileAndDataNoUpdate(worldX, worldY + 2, worldZ, level->setTileAndData(worldX, worldY + 2, worldZ, Tile::netherFence_Id,
Tile::netherFence_Id, 0); 0, Tile::UPDATE_CLIENTS);
level->setTileAndDataNoUpdate(worldX, worldY + 3, worldZ, level->setTileAndData(worldX, worldY + 3, worldZ, Tile::netherFence_Id,
Tile::netherFence_Id, 0); 0, Tile::UPDATE_CLIENTS);
placeBlock(level, Tile::netherFence_Id, 0, x + xOff, y + 3, z + zOff, placeBlock(level, Tile::netherFence_Id, 0, x + xOff, y + 3, z + zOff,
chunkBB); chunkBB);
placeBlock(level, Tile::lightGem_Id, 0, x + xOff, y + 2, z + zOff, placeBlock(level, Tile::glowstone_Id, 0, x + xOff, y + 2, z + zOff,
chunkBB); chunkBB);
} }
} }
@ -358,6 +423,10 @@ void NetherBridgePieces::NetherBridgePiece::generateLightPostFacingDown(
generateLightPost(level, random, chunkBB, x, y, z, 0, -1); generateLightPost(level, random, chunkBB, x, y, z, 0, -1);
} }
NetherBridgePieces::BridgeStraight::BridgeStraight() {
// for reflection
}
NetherBridgePieces::BridgeStraight::BridgeStraight(int genDepth, Random* random, NetherBridgePieces::BridgeStraight::BridgeStraight(int genDepth, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
int direction) int direction)
@ -445,6 +514,10 @@ bool NetherBridgePieces::BridgeStraight::postProcess(Level* level,
return true; return true;
} }
NetherBridgePieces::BridgeEndFiller::BridgeEndFiller() {
// for reflection
}
NetherBridgePieces::BridgeEndFiller::BridgeEndFiller(int genDepth, NetherBridgePieces::BridgeEndFiller::BridgeEndFiller(int genDepth,
Random* random, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
@ -520,6 +593,24 @@ bool NetherBridgePieces::BridgeEndFiller::postProcess(Level* level,
return true; return true;
} }
void NetherBridgePieces::BridgeEndFiller::readAdditonalSaveData(
CompoundTag* tag) {
NetherBridgePiece::readAdditonalSaveData(tag);
selfSeed = tag->getInt(L"Seed");
}
void NetherBridgePieces::BridgeEndFiller::addAdditonalSaveData(
CompoundTag* tag) {
NetherBridgePiece::addAdditonalSaveData(tag);
tag->putInt(L"Seed", selfSeed);
}
NetherBridgePieces::BridgeCrossing::BridgeCrossing() {
// for reflection
}
NetherBridgePieces::BridgeCrossing::BridgeCrossing(int genDepth, Random* random, NetherBridgePieces::BridgeCrossing::BridgeCrossing(int genDepth, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
int direction) int direction)
@ -639,10 +730,14 @@ bool NetherBridgePieces::BridgeCrossing::postProcess(Level* level,
return true; return true;
} }
NetherBridgePieces::StartPiece::StartPiece() {
// for reflection
previousPiece = NULL;
}
NetherBridgePieces::StartPiece::StartPiece(Random* random, int west, int north, NetherBridgePieces::StartPiece::StartPiece(Random* random, int west, int north,
Level* level) Level* level)
: BridgeCrossing(random, west, north) { : BridgeCrossing(random, west, north) {
isLibraryAdded = false;
previousPiece = NULL; previousPiece = NULL;
m_level = level; m_level = level;
@ -660,6 +755,18 @@ NetherBridgePieces::StartPiece::StartPiece(Random* random, int west, int north,
} }
} }
void NetherBridgePieces::StartPiece::readAdditonalSaveData(CompoundTag* tag) {
BridgeCrossing::readAdditonalSaveData(tag);
}
void NetherBridgePieces::StartPiece::addAdditonalSaveData(CompoundTag* tag) {
BridgeCrossing::addAdditonalSaveData(tag);
}
NetherBridgePieces::RoomCrossing::RoomCrossing() {
// for reflection
}
NetherBridgePieces::RoomCrossing::RoomCrossing(int genDepth, Random* random, NetherBridgePieces::RoomCrossing::RoomCrossing(int genDepth, Random* random,
BoundingBox* box, int direction) BoundingBox* box, int direction)
: NetherBridgePiece(genDepth) { : NetherBridgePiece(genDepth) {
@ -747,6 +854,10 @@ bool NetherBridgePieces::RoomCrossing::postProcess(Level* level, Random* random,
return true; return true;
} }
NetherBridgePieces::StairsRoom::StairsRoom() {
// for reflection
}
NetherBridgePieces::StairsRoom::StairsRoom(int genDepth, Random* random, NetherBridgePieces::StairsRoom::StairsRoom(int genDepth, Random* random,
BoundingBox* box, int direction) BoundingBox* box, int direction)
: NetherBridgePiece(genDepth) { : NetherBridgePiece(genDepth) {
@ -838,6 +949,10 @@ bool NetherBridgePieces::StairsRoom::postProcess(Level* level, Random* random,
return true; return true;
} }
NetherBridgePieces::MonsterThrone::MonsterThrone() {
// for reflection
}
NetherBridgePieces::MonsterThrone::MonsterThrone(int genDepth, Random* random, NetherBridgePieces::MonsterThrone::MonsterThrone(int genDepth, Random* random,
BoundingBox* box, BoundingBox* box,
int direction) int direction)
@ -867,6 +982,19 @@ NetherBridgePieces::MonsterThrone::createPiece(
return new MonsterThrone(genDepth, random, box, direction); return new MonsterThrone(genDepth, random, box, direction);
} }
void NetherBridgePieces::MonsterThrone::readAdditonalSaveData(
CompoundTag* tag) {
NetherBridgePiece::readAdditonalSaveData(tag);
hasPlacedMobSpawner = tag->getBoolean(L"Mob");
}
void NetherBridgePieces::MonsterThrone::addAdditonalSaveData(CompoundTag* tag) {
NetherBridgePiece::addAdditonalSaveData(tag);
tag->putBoolean(L"Mob", hasPlacedMobSpawner);
}
bool NetherBridgePieces::MonsterThrone::postProcess(Level* level, bool NetherBridgePieces::MonsterThrone::postProcess(Level* level,
Random* random, Random* random,
BoundingBox* chunkBB) { BoundingBox* chunkBB) {
@ -913,11 +1041,12 @@ bool NetherBridgePieces::MonsterThrone::postProcess(Level* level,
int y = getWorldY(5), x = getWorldX(3, 5), z = getWorldZ(3, 5); int y = getWorldY(5), x = getWorldX(3, 5), z = getWorldZ(3, 5);
if (chunkBB->isInside(x, y, z)) { if (chunkBB->isInside(x, y, z)) {
hasPlacedMobSpawner = true; hasPlacedMobSpawner = true;
level->setTile(x, y, z, Tile::mobSpawner_Id); level->setTileAndData(x, y, z, Tile::mobSpawner_Id, 0,
Tile::UPDATE_CLIENTS);
std::shared_ptr<MobSpawnerTileEntity> entity = std::shared_ptr<MobSpawnerTileEntity> entity =
std::dynamic_pointer_cast<MobSpawnerTileEntity>( std::dynamic_pointer_cast<MobSpawnerTileEntity>(
level->getTileEntity(x, y, z)); level->getTileEntity(x, y, z));
if (entity != NULL) entity->setEntityId(L"Blaze"); if (entity != NULL) entity->getSpawner()->setEntityId(L"Blaze");
} }
} }
@ -930,6 +1059,10 @@ bool NetherBridgePieces::MonsterThrone::postProcess(Level* level,
return true; return true;
} }
NetherBridgePieces::CastleEntrance::CastleEntrance() {
// for reflection
}
NetherBridgePieces::CastleEntrance::CastleEntrance(int genDepth, Random* random, NetherBridgePieces::CastleEntrance::CastleEntrance(int genDepth, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
int direction) int direction)
@ -1080,6 +1213,10 @@ bool NetherBridgePieces::CastleEntrance::postProcess(Level* level,
return true; return true;
} }
NetherBridgePieces::CastleStalkRoom::CastleStalkRoom() {
// for reflection
}
NetherBridgePieces::CastleStalkRoom::CastleStalkRoom(int genDepth, NetherBridgePieces::CastleStalkRoom::CastleStalkRoom(int genDepth,
Random* random, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
@ -1241,10 +1378,10 @@ bool NetherBridgePieces::CastleStalkRoom::postProcess(Level* level,
chunkBB); chunkBB);
// farmlands // farmlands
generateBox(level, chunkBB, 3, 4, 4, 4, 4, 8, Tile::hellSand_Id, generateBox(level, chunkBB, 3, 4, 4, 4, 4, 8, Tile::soulsand_Id,
Tile::hellSand_Id, false); Tile::soulsand_Id, false);
generateBox(level, chunkBB, 8, 4, 4, 9, 4, 8, Tile::hellSand_Id, generateBox(level, chunkBB, 8, 4, 4, 9, 4, 8, Tile::soulsand_Id,
Tile::hellSand_Id, false); Tile::soulsand_Id, false);
generateBox(level, chunkBB, 3, 5, 4, 4, 5, 8, Tile::netherStalk_Id, generateBox(level, chunkBB, 3, 5, 4, 4, 5, 8, Tile::netherStalk_Id,
Tile::netherStalk_Id, false); Tile::netherStalk_Id, false);
generateBox(level, chunkBB, 8, 5, 4, 9, 5, 8, Tile::netherStalk_Id, generateBox(level, chunkBB, 8, 5, 4, 9, 5, 8, Tile::netherStalk_Id,
@ -1283,6 +1420,10 @@ bool NetherBridgePieces::CastleStalkRoom::postProcess(Level* level,
return true; return true;
} }
NetherBridgePieces::CastleSmallCorridorPiece::CastleSmallCorridorPiece() {
// for reflection
}
NetherBridgePieces::CastleSmallCorridorPiece::CastleSmallCorridorPiece( NetherBridgePieces::CastleSmallCorridorPiece::CastleSmallCorridorPiece(
int genDepth, Random* random, BoundingBox* stairsBox, int direction) int genDepth, Random* random, BoundingBox* stairsBox, int direction)
: NetherBridgePiece(genDepth) { : NetherBridgePiece(genDepth) {
@ -1352,6 +1493,11 @@ bool NetherBridgePieces::CastleSmallCorridorPiece::postProcess(
return true; return true;
} }
NetherBridgePieces::CastleSmallCorridorCrossingPiece::
CastleSmallCorridorCrossingPiece() {
// for reflection
}
NetherBridgePieces::CastleSmallCorridorCrossingPiece:: NetherBridgePieces::CastleSmallCorridorCrossingPiece::
CastleSmallCorridorCrossingPiece(int genDepth, Random* random, CastleSmallCorridorCrossingPiece(int genDepth, Random* random,
BoundingBox* stairsBox, int direction) BoundingBox* stairsBox, int direction)
@ -1421,12 +1567,33 @@ bool NetherBridgePieces::CastleSmallCorridorCrossingPiece::postProcess(
return true; return true;
} }
NetherBridgePieces::CastleSmallCorridorRightTurnPiece::
CastleSmallCorridorRightTurnPiece() {
// for reflection
isNeedingChest = false;
}
NetherBridgePieces::CastleSmallCorridorRightTurnPiece:: NetherBridgePieces::CastleSmallCorridorRightTurnPiece::
CastleSmallCorridorRightTurnPiece(int genDepth, Random* random, CastleSmallCorridorRightTurnPiece(int genDepth, Random* random,
BoundingBox* stairsBox, int direction) BoundingBox* stairsBox, int direction)
: NetherBridgePiece(genDepth) { : NetherBridgePiece(genDepth) {
orientation = direction; orientation = direction;
boundingBox = stairsBox; boundingBox = stairsBox;
isNeedingChest = random->nextInt(3) == 0;
}
void NetherBridgePieces::CastleSmallCorridorRightTurnPiece::
readAdditonalSaveData(CompoundTag* tag) {
NetherBridgePiece::readAdditonalSaveData(tag);
isNeedingChest = tag->getBoolean(L"Chest");
}
void NetherBridgePieces::CastleSmallCorridorRightTurnPiece::
addAdditonalSaveData(CompoundTag* tag) {
NetherBridgePiece::addAdditonalSaveData(tag);
tag->putBoolean(L"Chest", isNeedingChest);
} }
void NetherBridgePieces::CastleSmallCorridorRightTurnPiece::addChildren( void NetherBridgePieces::CastleSmallCorridorRightTurnPiece::addChildren(
@ -1482,6 +1649,18 @@ bool NetherBridgePieces::CastleSmallCorridorRightTurnPiece::postProcess(
generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, Tile::netherFence_Id, generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, Tile::netherFence_Id,
Tile::netherBrick_Id, false); Tile::netherBrick_Id, false);
if (isNeedingChest) {
int y = getWorldY(2);
int x = getWorldX(1, 3), z = getWorldZ(1, 3);
if (chunkBB->isInside(x, y, z)) {
isNeedingChest = false;
createChest(level, chunkBB, random, 1, 2, 3,
WeighedTreasureArray(fortressTreasureItems,
FORTRESS_TREASURE_ITEMS_COUNT),
2 + random->nextInt(4));
}
}
// roof // roof
generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::netherBrick_Id, generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::netherBrick_Id,
Tile::netherBrick_Id, false); Tile::netherBrick_Id, false);
@ -1496,12 +1675,33 @@ bool NetherBridgePieces::CastleSmallCorridorRightTurnPiece::postProcess(
return true; return true;
} }
NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::
CastleSmallCorridorLeftTurnPiece() {
isNeedingChest = false;
// for reflection
}
NetherBridgePieces::CastleSmallCorridorLeftTurnPiece:: NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::
CastleSmallCorridorLeftTurnPiece(int genDepth, Random* random, CastleSmallCorridorLeftTurnPiece(int genDepth, Random* random,
BoundingBox* stairsBox, int direction) BoundingBox* stairsBox, int direction)
: NetherBridgePiece(genDepth) { : NetherBridgePiece(genDepth) {
orientation = direction; orientation = direction;
boundingBox = stairsBox; boundingBox = stairsBox;
isNeedingChest = random->nextInt(3) == 0;
}
void NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::
readAdditonalSaveData(CompoundTag* tag) {
NetherBridgePiece::readAdditonalSaveData(tag);
isNeedingChest = tag->getBoolean(L"Chest");
}
void NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::addAdditonalSaveData(
CompoundTag* tag) {
NetherBridgePiece::addAdditonalSaveData(tag);
tag->putBoolean(L"Chest", isNeedingChest);
} }
void NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::addChildren( void NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::addChildren(
@ -1557,6 +1757,18 @@ bool NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::postProcess(
generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, Tile::netherFence_Id, generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, Tile::netherFence_Id,
Tile::netherBrick_Id, false); Tile::netherBrick_Id, false);
if (isNeedingChest) {
int y = getWorldY(2);
int x = getWorldX(3, 3), z = getWorldZ(3, 3);
if (chunkBB->isInside(x, y, z)) {
isNeedingChest = false;
createChest(level, chunkBB, random, 3, 2, 3,
WeighedTreasureArray(fortressTreasureItems,
FORTRESS_TREASURE_ITEMS_COUNT),
2 + random->nextInt(4));
}
}
// roof // roof
generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::netherBrick_Id, generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::netherBrick_Id,
Tile::netherBrick_Id, false); Tile::netherBrick_Id, false);
@ -1571,6 +1783,10 @@ bool NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::postProcess(
return true; return true;
} }
NetherBridgePieces::CastleCorridorStairsPiece::CastleCorridorStairsPiece() {
// for reflection
}
NetherBridgePieces::CastleCorridorStairsPiece::CastleCorridorStairsPiece( NetherBridgePieces::CastleCorridorStairsPiece::CastleCorridorStairsPiece(
int genDepth, Random* random, BoundingBox* stairsBox, int direction) int genDepth, Random* random, BoundingBox* stairsBox, int direction)
: NetherBridgePiece(genDepth) { : NetherBridgePiece(genDepth) {
@ -1651,6 +1867,10 @@ bool NetherBridgePieces::CastleCorridorStairsPiece::postProcess(
return true; return true;
} }
NetherBridgePieces::CastleCorridorTBalconyPiece::CastleCorridorTBalconyPiece() {
// for reflection
}
NetherBridgePieces::CastleCorridorTBalconyPiece::CastleCorridorTBalconyPiece( NetherBridgePieces::CastleCorridorTBalconyPiece::CastleCorridorTBalconyPiece(
int genDepth, Random* random, BoundingBox* stairsBox, int direction) int genDepth, Random* random, BoundingBox* stairsBox, int direction)
: NetherBridgePiece(genDepth) { : NetherBridgePiece(genDepth) {

View file

@ -26,6 +26,10 @@ private:
EPieceClass_CastleCorridorTBalconyPiece EPieceClass_CastleCorridorTBalconyPiece
}; };
public:
static void loadStatic();
private:
class PieceWeight { class PieceWeight {
public: public:
EPieceClass pieceClass; EPieceClass pieceClass;
@ -64,9 +68,20 @@ public:
private: private:
class NetherBridgePiece : public StructurePiece { class NetherBridgePiece : public StructurePiece {
protected:
static const int FORTRESS_TREASURE_ITEMS_COUNT = 11;
static WeighedTreasure*
fortressTreasureItems[FORTRESS_TREASURE_ITEMS_COUNT];
public:
NetherBridgePiece();
protected: protected:
NetherBridgePiece(int genDepth); NetherBridgePiece(int genDepth);
virtual void readAdditonalSaveData(CompoundTag* tag);
virtual void addAdditonalSaveData(CompoundTag* tag);
private: private:
int updatePieceWeight(std::list<PieceWeight*>* currentPieces); int updatePieceWeight(std::list<PieceWeight*>* currentPieces);
@ -120,12 +135,19 @@ private:
* *
*/ */
class BridgeStraight : public NetherBridgePiece { class BridgeStraight : public NetherBridgePiece {
public:
static StructurePiece* Create() { return new BridgeStraight(); }
virtual EStructurePiece GetType() {
return eStructurePiece_BridgeStraight;
}
private: private:
static const int width = 5; static const int width = 5;
static const int height = 10; static const int height = 10;
static const int depth = 19; static const int depth = 19;
public: public:
BridgeStraight();
BridgeStraight(int genDepth, Random* random, BoundingBox* stairsBox, BridgeStraight(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -140,6 +162,12 @@ private:
}; };
class BridgeEndFiller : public NetherBridgePiece { class BridgeEndFiller : public NetherBridgePiece {
public:
static StructurePiece* Create() { return new BridgeEndFiller(); }
virtual EStructurePiece GetType() {
return eStructurePiece_BridgeEndFiller;
}
private: private:
static const int width = 5; static const int width = 5;
static const int height = 10; static const int height = 10;
@ -148,23 +176,36 @@ private:
int selfSeed; int selfSeed;
public: public:
BridgeEndFiller();
BridgeEndFiller(int genDepth, Random* random, BoundingBox* stairsBox, BridgeEndFiller(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
static BridgeEndFiller* createPiece(std::list<StructurePiece*>* pieces, static BridgeEndFiller* createPiece(std::list<StructurePiece*>* pieces,
Random* random, int footX, Random* random, int footX,
int footY, int footZ, int direction, int footY, int footZ, int direction,
int genDepth); int genDepth);
virtual bool postProcess(Level* level, Random* random, virtual bool postProcess(Level* level, Random* random,
BoundingBox* chunkBB); BoundingBox* chunkBB);
protected:
void readAdditonalSaveData(CompoundTag* tag);
void addAdditonalSaveData(CompoundTag* tag);
}; };
class BridgeCrossing : public NetherBridgePiece { class BridgeCrossing : public NetherBridgePiece {
public:
static StructurePiece* Create() { return new BridgeCrossing(); }
virtual EStructurePiece GetType() {
return eStructurePiece_BridgeCrossing;
}
private: private:
static const int width = 19; static const int width = 19;
static const int height = 10; static const int height = 10;
static const int depth = 19; static const int depth = 19;
public: public:
BridgeCrossing();
BridgeCrossing(int genDepth, Random* random, BoundingBox* stairsBox, BridgeCrossing(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
@ -186,7 +227,11 @@ private:
public: public:
class StartPiece : public BridgeCrossing { class StartPiece : public BridgeCrossing {
public: public:
bool isLibraryAdded; virtual EStructurePiece GetType() {
return eStructurePiece_NetherBridgeStartPiece;
}
public:
PieceWeight* previousPiece; PieceWeight* previousPiece;
Level* m_level; Level* m_level;
@ -197,18 +242,30 @@ public:
// called in a random order // called in a random order
std::vector<StructurePiece*> pendingChildren; std::vector<StructurePiece*> pendingChildren;
StartPiece();
StartPiece(Random* random, int west, int north, StartPiece(Random* random, int west, int north,
Level* level); // 4J Added level param Level* level); // 4J Added level param
protected:
virtual void readAdditonalSaveData(CompoundTag* tag);
virtual void addAdditonalSaveData(CompoundTag* tag);
}; };
private: private:
class RoomCrossing : public NetherBridgePiece { class RoomCrossing : public NetherBridgePiece {
public:
static StructurePiece* Create() { return new RoomCrossing(); }
virtual EStructurePiece GetType() {
return eStructurePiece_RoomCrossing;
}
private: private:
static const int width = 7; static const int width = 7;
static const int height = 9; static const int height = 9;
static const int depth = 7; static const int depth = 7;
public: public:
RoomCrossing();
RoomCrossing(int genDepth, Random* random, BoundingBox* box, RoomCrossing(int genDepth, Random* random, BoundingBox* box,
int direction); int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -223,12 +280,17 @@ private:
}; };
class StairsRoom : public NetherBridgePiece { class StairsRoom : public NetherBridgePiece {
public:
static StructurePiece* Create() { return new StairsRoom(); }
virtual EStructurePiece GetType() { return eStructurePiece_StairsRoom; }
private: private:
static const int width = 7; static const int width = 7;
static const int height = 11; static const int height = 11;
static const int depth = 7; static const int depth = 7;
public: public:
StairsRoom();
StairsRoom(int genDepth, Random* random, BoundingBox* box, StairsRoom(int genDepth, Random* random, BoundingBox* box,
int direction); int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -242,6 +304,12 @@ private:
}; };
class MonsterThrone : public NetherBridgePiece { class MonsterThrone : public NetherBridgePiece {
public:
static StructurePiece* Create() { return new MonsterThrone(); }
virtual EStructurePiece GetType() {
return eStructurePiece_MonsterThrone;
}
private: private:
static const int width = 7; static const int width = 7;
static const int height = 8; static const int height = 8;
@ -250,8 +318,15 @@ private:
bool hasPlacedMobSpawner; bool hasPlacedMobSpawner;
public: public:
MonsterThrone();
MonsterThrone(int genDepth, Random* random, BoundingBox* box, MonsterThrone(int genDepth, Random* random, BoundingBox* box,
int direction); int direction);
protected:
virtual void readAdditonalSaveData(CompoundTag* tag);
virtual void addAdditonalSaveData(CompoundTag* tag);
public:
static MonsterThrone* createPiece(std::list<StructurePiece*>* pieces, static MonsterThrone* createPiece(std::list<StructurePiece*>* pieces,
Random* random, int footX, int footY, Random* random, int footX, int footY,
int footZ, int direction, int footZ, int direction,
@ -265,12 +340,19 @@ private:
* *
*/ */
class CastleEntrance : public NetherBridgePiece { class CastleEntrance : public NetherBridgePiece {
public:
static StructurePiece* Create() { return new CastleEntrance(); }
virtual EStructurePiece GetType() {
return eStructurePiece_CastleEntrance;
}
private: private:
static const int width = 13; static const int width = 13;
static const int height = 14; static const int height = 14;
static const int depth = 13; static const int depth = 13;
public: public:
CastleEntrance();
CastleEntrance(int genDepth, Random* random, BoundingBox* stairsBox, CastleEntrance(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -289,12 +371,19 @@ private:
* *
*/ */
class CastleStalkRoom : public NetherBridgePiece { class CastleStalkRoom : public NetherBridgePiece {
public:
static StructurePiece* Create() { return new CastleStalkRoom(); }
virtual EStructurePiece GetType() {
return eStructurePiece_CastleStalkRoom;
}
private: private:
static const int width = 13; static const int width = 13;
static const int height = 14; static const int height = 14;
static const int depth = 13; static const int depth = 13;
public: public:
CastleStalkRoom();
CastleStalkRoom(int genDepth, Random* random, BoundingBox* stairsBox, CastleStalkRoom(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -313,12 +402,21 @@ private:
* *
*/ */
class CastleSmallCorridorPiece : public NetherBridgePiece { class CastleSmallCorridorPiece : public NetherBridgePiece {
public:
static StructurePiece* Create() {
return new CastleSmallCorridorPiece();
}
virtual EStructurePiece GetType() {
return eStructurePiece_CastleSmallCorridorPiece;
}
private: private:
static const int width = 5; static const int width = 5;
static const int height = 7; static const int height = 7;
static const int depth = 5; static const int depth = 5;
public: public:
CastleSmallCorridorPiece();
CastleSmallCorridorPiece(int genDepth, Random* random, CastleSmallCorridorPiece(int genDepth, Random* random,
BoundingBox* stairsBox, int direction); BoundingBox* stairsBox, int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -336,12 +434,21 @@ private:
* *
*/ */
class CastleSmallCorridorCrossingPiece : public NetherBridgePiece { class CastleSmallCorridorCrossingPiece : public NetherBridgePiece {
public:
static StructurePiece* Create() {
return new CastleSmallCorridorCrossingPiece();
}
virtual EStructurePiece GetType() {
return eStructurePiece_CastleSmallCorridorCrossingPiece;
}
private: private:
static const int width = 5; static const int width = 5;
static const int height = 7; static const int height = 7;
static const int depth = 5; static const int depth = 5;
public: public:
CastleSmallCorridorCrossingPiece();
CastleSmallCorridorCrossingPiece(int genDepth, Random* random, CastleSmallCorridorCrossingPiece(int genDepth, Random* random,
BoundingBox* stairsBox, int direction); BoundingBox* stairsBox, int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -359,15 +466,32 @@ private:
* *
*/ */
class CastleSmallCorridorRightTurnPiece : public NetherBridgePiece { class CastleSmallCorridorRightTurnPiece : public NetherBridgePiece {
public:
static StructurePiece* Create() {
return new CastleSmallCorridorRightTurnPiece();
}
virtual EStructurePiece GetType() {
return eStructurePiece_CastleSmallCorridorRightTurnPiece;
}
private: private:
static const int width = 5; static const int width = 5;
static const int height = 7; static const int height = 7;
static const int depth = 5; static const int depth = 5;
bool isNeedingChest;
public: public:
CastleSmallCorridorRightTurnPiece();
CastleSmallCorridorRightTurnPiece(int genDepth, Random* random, CastleSmallCorridorRightTurnPiece(int genDepth, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
int direction); int direction);
protected:
virtual void readAdditonalSaveData(CompoundTag* tag);
virtual void addAdditonalSaveData(CompoundTag* tag);
public:
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, std::list<StructurePiece*>* pieces,
Random* random); Random* random);
@ -383,14 +507,30 @@ private:
* *
*/ */
class CastleSmallCorridorLeftTurnPiece : public NetherBridgePiece { class CastleSmallCorridorLeftTurnPiece : public NetherBridgePiece {
public:
static StructurePiece* Create() {
return new CastleSmallCorridorLeftTurnPiece();
}
virtual EStructurePiece GetType() {
return eStructurePiece_CastleSmallCorridorLeftTurnPiece;
}
private: private:
static const int width = 5; static const int width = 5;
static const int height = 7; static const int height = 7;
static const int depth = 5; static const int depth = 5;
bool isNeedingChest;
public: public:
CastleSmallCorridorLeftTurnPiece();
CastleSmallCorridorLeftTurnPiece(int genDepth, Random* random, CastleSmallCorridorLeftTurnPiece(int genDepth, Random* random,
BoundingBox* stairsBox, int direction); BoundingBox* stairsBox, int direction);
protected:
virtual void readAdditonalSaveData(CompoundTag* tag);
virtual void addAdditonalSaveData(CompoundTag* tag);
public:
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, std::list<StructurePiece*>* pieces,
Random* random); Random* random);
@ -406,12 +546,21 @@ private:
* *
*/ */
class CastleCorridorStairsPiece : public NetherBridgePiece { class CastleCorridorStairsPiece : public NetherBridgePiece {
public:
static StructurePiece* Create() {
return new CastleCorridorStairsPiece();
}
virtual EStructurePiece GetType() {
return eStructurePiece_CastleCorridorStairsPiece;
}
private: private:
static const int width = 5; static const int width = 5;
static const int height = 14; static const int height = 14;
static const int depth = 10; static const int depth = 10;
public: public:
CastleCorridorStairsPiece();
CastleCorridorStairsPiece(int genDepth, Random* random, CastleCorridorStairsPiece(int genDepth, Random* random,
BoundingBox* stairsBox, int direction); BoundingBox* stairsBox, int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -429,12 +578,21 @@ private:
* *
*/ */
class CastleCorridorTBalconyPiece : public NetherBridgePiece { class CastleCorridorTBalconyPiece : public NetherBridgePiece {
public:
static StructurePiece* Create() {
return new CastleCorridorTBalconyPiece();
}
virtual EStructurePiece GetType() {
return eStructurePiece_CastleCorridorTBalconyPiece;
}
private: private:
static const int width = 9; static const int width = 9;
static const int height = 7; static const int height = 7;
static const int depth = 9; static const int depth = 9;
public: public:
CastleCorridorTBalconyPiece();
CastleCorridorTBalconyPiece(int genDepth, Random* random, CastleCorridorTBalconyPiece(int genDepth, Random* random,
BoundingBox* stairsBox, int direction); BoundingBox* stairsBox, int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,

View file

@ -1,12 +1,31 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.h" #include "../../Headers/net.minecraft.h"
#include "../../Headers/net.minecraft.world.entity.monster.h"
#include "../../Headers/net.minecraft.world.item.h" #include "../../Headers/net.minecraft.world.item.h"
#include "../../Headers/net.minecraft.world.level.dimension.h" #include "../../Headers/net.minecraft.world.level.dimension.h"
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
#include "../../Headers/net.minecraft.world.level.levelgen.structure.h"
#include "../../Util/WeighedTreasure.h" #include "../../Util/WeighedTreasure.h"
#include "ScatteredFeaturePieces.h" #include "ScatteredFeaturePieces.h"
void ScatteredFeaturePieces::loadStatic() {
StructureFeatureIO::setPieceId(eStructurePiece_DesertPyramidPiece,
DesertPyramidPiece::Create, L"TeDP");
StructureFeatureIO::setPieceId(eStructurePiece_JunglePyramidPiece,
DesertPyramidPiece::Create, L"TeJP");
StructureFeatureIO::setPieceId(eStructurePiece_SwamplandHut,
DesertPyramidPiece::Create, L"TeSH");
}
ScatteredFeaturePieces::ScatteredFeaturePiece::ScatteredFeaturePiece() {
width = 0;
height = 0;
depth = 0;
heightPosition = 0;
// for reflection
}
ScatteredFeaturePieces::ScatteredFeaturePiece::ScatteredFeaturePiece( ScatteredFeaturePieces::ScatteredFeaturePiece::ScatteredFeaturePiece(
Random* random, int west, int floor, int north, int width, int height, Random* random, int west, int floor, int north, int width, int height,
int depth) int depth)
@ -18,6 +37,16 @@ ScatteredFeaturePieces::ScatteredFeaturePiece::ScatteredFeaturePiece(
orientation = random->nextInt(4); orientation = random->nextInt(4);
LevelGenerationOptions* levelGenOptions = app.getLevelGenerationOptions();
if (levelGenOptions != NULL) {
int tempOrientation = 0;
if (levelGenOptions->isFeatureChunk(west >> 4, north >> 4,
StructureFeature::eFeature_Temples,
&tempOrientation)) {
orientation = tempOrientation;
}
}
switch (orientation) { switch (orientation) {
case Direction::NORTH: case Direction::NORTH:
case Direction::SOUTH: case Direction::SOUTH:
@ -33,6 +62,22 @@ ScatteredFeaturePieces::ScatteredFeaturePiece::ScatteredFeaturePiece(
} }
} }
void ScatteredFeaturePieces::ScatteredFeaturePiece::addAdditonalSaveData(
CompoundTag* tag) {
tag->putInt(L"Width", width);
tag->putInt(L"Height", height);
tag->putInt(L"Depth", depth);
tag->putInt(L"HPos", heightPosition);
}
void ScatteredFeaturePieces::ScatteredFeaturePiece::readAdditonalSaveData(
CompoundTag* tag) {
width = tag->getInt(L"Width");
height = tag->getInt(L"Height");
depth = tag->getInt(L"Depth");
heightPosition = tag->getInt(L"HPos");
}
bool ScatteredFeaturePieces::ScatteredFeaturePiece::updateAverageGroundHeight( bool ScatteredFeaturePieces::ScatteredFeaturePiece::updateAverageGroundHeight(
Level* level, BoundingBox* chunkBB, int offset) { Level* level, BoundingBox* chunkBB, int offset) {
if (heightPosition >= 0) { if (heightPosition >= 0) {
@ -67,8 +112,22 @@ WeighedTreasure* ScatteredFeaturePieces::DesertPyramidPiece::treasureItems
new WeighedTreasure(Item::emerald_Id, 0, 1, 3, 2), new WeighedTreasure(Item::emerald_Id, 0, 1, 3, 2),
new WeighedTreasure(Item::bone_Id, 0, 4, 6, 20), new WeighedTreasure(Item::bone_Id, 0, 4, 6, 20),
new WeighedTreasure(Item::rotten_flesh_Id, 0, 3, 7, 16), new WeighedTreasure(Item::rotten_flesh_Id, 0, 3, 7, 16),
// very rare for pyramids ...
new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 3),
new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1),
new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 1),
new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1),
// ...
}; };
ScatteredFeaturePieces::DesertPyramidPiece::DesertPyramidPiece() {
hasPlacedChest[0] = false;
hasPlacedChest[1] = false;
hasPlacedChest[2] = false;
hasPlacedChest[3] = false;
// for reflection
}
ScatteredFeaturePieces::DesertPyramidPiece::DesertPyramidPiece(Random* random, ScatteredFeaturePieces::DesertPyramidPiece::DesertPyramidPiece(Random* random,
int west, int west,
int north) int north)
@ -79,6 +138,24 @@ ScatteredFeaturePieces::DesertPyramidPiece::DesertPyramidPiece(Random* random,
hasPlacedChest[3] = false; hasPlacedChest[3] = false;
} }
void ScatteredFeaturePieces::DesertPyramidPiece::addAdditonalSaveData(
CompoundTag* tag) {
ScatteredFeaturePiece::addAdditonalSaveData(tag);
tag->putBoolean(L"hasPlacedChest0", hasPlacedChest[0]);
tag->putBoolean(L"hasPlacedChest1", hasPlacedChest[1]);
tag->putBoolean(L"hasPlacedChest2", hasPlacedChest[2]);
tag->putBoolean(L"hasPlacedChest3", hasPlacedChest[3]);
}
void ScatteredFeaturePieces::DesertPyramidPiece::readAdditonalSaveData(
CompoundTag* tag) {
ScatteredFeaturePiece::readAdditonalSaveData(tag);
hasPlacedChest[0] = tag->getBoolean(L"hasPlacedChest0");
hasPlacedChest[1] = tag->getBoolean(L"hasPlacedChest1");
hasPlacedChest[2] = tag->getBoolean(L"hasPlacedChest2");
hasPlacedChest[3] = tag->getBoolean(L"hasPlacedChest3");
}
bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess( bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess(
Level* level, Random* random, BoundingBox* chunkBB) { Level* level, Random* random, BoundingBox* chunkBB) {
// pyramid // pyramid
@ -232,48 +309,48 @@ bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess(
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS,
width - 5, 2, z, chunkBB); width - 5, 2, z, chunkBB);
} }
placeBlock(level, Tile::cloth_Id, baseDecoColor, 10, 0, 7, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 10, 0, 7, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 10, 0, 8, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 10, 0, 8, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 9, 0, 9, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 9, 0, 9, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 11, 0, 9, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 11, 0, 9, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 8, 0, 10, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 8, 0, 10, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 12, 0, 10, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 12, 0, 10, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 7, 0, 10, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 7, 0, 10, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 13, 0, 10, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 13, 0, 10, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 9, 0, 11, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 9, 0, 11, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 11, 0, 11, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 11, 0, 11, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 10, 0, 12, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 10, 0, 12, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 10, 0, 13, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 10, 0, 13, chunkBB);
placeBlock(level, Tile::cloth_Id, blue, 10, 0, 10, chunkBB); placeBlock(level, Tile::wool_Id, blue, 10, 0, 10, chunkBB);
// outdoor decoration // outdoor decoration
for (int x = 0; x <= width - 1; x += width - 1) { for (int x = 0; x <= width - 1; x += width - 1) {
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x,
2, 1, chunkBB); 2, 1, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 2, 2, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 2, 2, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x,
2, 3, chunkBB); 2, 3, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x,
3, 1, chunkBB); 3, 1, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 3, 2, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 3, 2, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x,
3, 3, chunkBB); 3, 3, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 4, 1, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 4, 1, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS,
x, 4, 2, chunkBB); x, 4, 2, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 4, 3, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 4, 3, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x,
5, 1, chunkBB); 5, 1, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 5, 2, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 5, 2, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x,
5, 3, chunkBB); 5, 3, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 6, 1, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 6, 1, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS,
x, 6, 2, chunkBB); x, 6, 2, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 6, 3, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 6, 3, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 7, 1, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 7, 1, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 7, 2, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 7, 2, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 7, 3, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 7, 3, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x,
8, 1, chunkBB); 8, 1, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x,
@ -284,30 +361,30 @@ bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess(
for (int x = 2; x <= width - 3; x += width - 3 - 2) { for (int x = 2; x <= width - 3; x += width - 3 - 2) {
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE,
x - 1, 2, 0, chunkBB); x - 1, 2, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 2, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 2, 0, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE,
x + 1, 2, 0, chunkBB); x + 1, 2, 0, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE,
x - 1, 3, 0, chunkBB); x - 1, 3, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 3, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 3, 0, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE,
x + 1, 3, 0, chunkBB); x + 1, 3, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x - 1, 4, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x - 1, 4, 0, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS,
x, 4, 0, chunkBB); x, 4, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x + 1, 4, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x + 1, 4, 0, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE,
x - 1, 5, 0, chunkBB); x - 1, 5, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 5, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 5, 0, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE,
x + 1, 5, 0, chunkBB); x + 1, 5, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x - 1, 6, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x - 1, 6, 0, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS,
x, 6, 0, chunkBB); x, 6, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x + 1, 6, 00, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x + 1, 6, 00, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x - 1, 7, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x - 1, 7, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 7, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x, 7, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, x + 1, 7, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, x + 1, 7, 0, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE,
x - 1, 8, 0, chunkBB); x - 1, 8, 0, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x,
@ -320,10 +397,10 @@ bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess(
SandStoneTile::TYPE_SMOOTHSIDE, false); SandStoneTile::TYPE_SMOOTHSIDE, false);
placeBlock(level, 0, 0, 8, 6, 0, chunkBB); placeBlock(level, 0, 0, 8, 6, 0, chunkBB);
placeBlock(level, 0, 0, 12, 6, 0, chunkBB); placeBlock(level, 0, 0, 12, 6, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 9, 5, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 9, 5, 0, chunkBB);
placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 10, placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, 10,
5, 0, chunkBB); 5, 0, chunkBB);
placeBlock(level, Tile::cloth_Id, baseDecoColor, 11, 5, 0, chunkBB); placeBlock(level, Tile::wool_Id, baseDecoColor, 11, 5, 0, chunkBB);
// tombs // tombs
generateBox(level, chunkBB, 8, -14, 8, 12, -11, 12, Tile::sandStone_Id, generateBox(level, chunkBB, 8, -14, 8, 12, -11, 12, Tile::sandStone_Id,
@ -390,6 +467,12 @@ WeighedTreasure* ScatteredFeaturePieces::JunglePyramidPiece::treasureItems
new WeighedTreasure(Item::emerald_Id, 0, 1, 3, 2), new WeighedTreasure(Item::emerald_Id, 0, 1, 3, 2),
new WeighedTreasure(Item::bone_Id, 0, 4, 6, 20), new WeighedTreasure(Item::bone_Id, 0, 4, 6, 20),
new WeighedTreasure(Item::rotten_flesh_Id, 0, 3, 7, 16), new WeighedTreasure(Item::rotten_flesh_Id, 0, 3, 7, 16),
// very rare for pyramids ...
new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 3),
new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1),
new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 1),
new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1),
// ...
}; };
WeighedTreasure* ScatteredFeaturePieces::JunglePyramidPiece::dispenserItems WeighedTreasure* ScatteredFeaturePieces::JunglePyramidPiece::dispenserItems
@ -398,6 +481,10 @@ WeighedTreasure* ScatteredFeaturePieces::JunglePyramidPiece::dispenserItems
// new WeighedTreasure(Item.fireball.id, 0, 1, 1, 10), // new WeighedTreasure(Item.fireball.id, 0, 1, 1, 10),
}; };
ScatteredFeaturePieces::JunglePyramidPiece::JunglePyramidPiece() {
// for reflection
}
ScatteredFeaturePieces::JunglePyramidPiece::JunglePyramidPiece(Random* random, ScatteredFeaturePieces::JunglePyramidPiece::JunglePyramidPiece(Random* random,
int west, int west,
int north) int north)
@ -408,6 +495,24 @@ ScatteredFeaturePieces::JunglePyramidPiece::JunglePyramidPiece(Random* random,
placedTrap2 = false; placedTrap2 = false;
} }
void ScatteredFeaturePieces::JunglePyramidPiece::addAdditonalSaveData(
CompoundTag* tag) {
ScatteredFeaturePiece::addAdditonalSaveData(tag);
tag->putBoolean(L"placedMainChest", placedMainChest);
tag->putBoolean(L"placedHiddenChest", placedHiddenChest);
tag->putBoolean(L"placedTrap1", placedTrap1);
tag->putBoolean(L"placedTrap2", placedTrap2);
}
void ScatteredFeaturePieces::JunglePyramidPiece::readAdditonalSaveData(
CompoundTag* tag) {
ScatteredFeaturePiece::readAdditonalSaveData(tag);
placedMainChest = tag->getBoolean(L"placedMainChest");
placedHiddenChest = tag->getBoolean(L"placedHiddenChest");
placedTrap1 = tag->getBoolean(L"placedTrap1");
placedTrap2 = tag->getBoolean(L"placedTrap2");
}
bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess( bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(
Level* level, Random* random, BoundingBox* chunkBB) { Level* level, Random* random, BoundingBox* chunkBB) {
if (!updateAverageGroundHeight(level, chunkBB, 0)) { if (!updateAverageGroundHeight(level, chunkBB, 0)) {
@ -593,7 +698,7 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(
placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 2, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 2, chunkBB);
placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 1, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 5, -3, 1, chunkBB);
placeBlock(level, Tile::redStoneDust_Id, 0, 4, -3, 1, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 4, -3, 1, chunkBB);
placeBlock(level, Tile::mossStone_Id, 0, 3, -3, 1, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 3, -3, 1, chunkBB);
if (!placedTrap1) { if (!placedTrap1) {
placedTrap1 = createDispenser( placedTrap1 = createDispenser(
level, chunkBB, random, 3, -2, 1, Facing::NORTH, level, chunkBB, random, 3, -2, 1, Facing::NORTH,
@ -619,7 +724,7 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(
placeBlock(level, Tile::redStoneDust_Id, 0, 8, -3, 6, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 8, -3, 6, chunkBB);
placeBlock(level, Tile::redStoneDust_Id, 0, 9, -3, 6, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 9, -3, 6, chunkBB);
placeBlock(level, Tile::redStoneDust_Id, 0, 9, -3, 5, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 9, -3, 5, chunkBB);
placeBlock(level, Tile::mossStone_Id, 0, 9, -3, 4, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 9, -3, 4, chunkBB);
placeBlock(level, Tile::redStoneDust_Id, 0, 9, -2, 4, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 9, -2, 4, chunkBB);
if (!placedTrap2) { if (!placedTrap2) {
placedTrap2 = createDispenser( placedTrap2 = createDispenser(
@ -636,26 +741,26 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(
Item::enchantedBook->createForRandomTreasure(random)), Item::enchantedBook->createForRandomTreasure(random)),
2 + random->nextInt(5)); 2 + random->nextInt(5));
} }
placeBlock(level, Tile::mossStone_Id, 0, 9, -3, 2, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 9, -3, 2, chunkBB);
placeBlock(level, Tile::mossStone_Id, 0, 8, -3, 1, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 8, -3, 1, chunkBB);
placeBlock(level, Tile::mossStone_Id, 0, 4, -3, 5, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 4, -3, 5, chunkBB);
placeBlock(level, Tile::mossStone_Id, 0, 5, -2, 5, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 5, -2, 5, chunkBB);
placeBlock(level, Tile::mossStone_Id, 0, 5, -1, 5, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 5, -1, 5, chunkBB);
placeBlock(level, Tile::mossStone_Id, 0, 6, -3, 5, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 6, -3, 5, chunkBB);
placeBlock(level, Tile::mossStone_Id, 0, 7, -2, 5, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 7, -2, 5, chunkBB);
placeBlock(level, Tile::mossStone_Id, 0, 7, -1, 5, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 7, -1, 5, chunkBB);
placeBlock(level, Tile::mossStone_Id, 0, 8, -3, 5, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 8, -3, 5, chunkBB);
generateBox(level, chunkBB, 9, -1, 1, 9, -1, 5, false, random, generateBox(level, chunkBB, 9, -1, 1, 9, -1, 5, false, random,
&stoneSelector); &stoneSelector);
// hidden room // hidden room
generateAirBox(level, chunkBB, 8, -3, 8, 10, -1, 10); generateAirBox(level, chunkBB, 8, -3, 8, 10, -1, 10);
placeBlock(level, Tile::stoneBrickSmooth_Id, placeBlock(level, Tile::stoneBrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, 8,
SmoothStoneBrickTile::TYPE_DETAIL, 8, -2, 11, chunkBB); -2, 11, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, placeBlock(level, Tile::stoneBrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, 9,
SmoothStoneBrickTile::TYPE_DETAIL, 9, -2, 11, chunkBB); -2, 11, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, placeBlock(level, Tile::stoneBrick_Id, SmoothStoneBrickTile::TYPE_DETAIL,
SmoothStoneBrickTile::TYPE_DETAIL, 10, -2, 11, chunkBB); 10, -2, 11, chunkBB);
placeBlock(level, Tile::lever_Id, placeBlock(level, Tile::lever_Id,
LeverTile::getLeverFacing( LeverTile::getLeverFacing(
getOrientationData(Tile::lever_Id, Facing::NORTH)), getOrientationData(Tile::lever_Id, Facing::NORTH)),
@ -672,7 +777,7 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(
&stoneSelector); &stoneSelector);
generateBox(level, chunkBB, 10, -3, 8, 10, -3, 10, false, random, generateBox(level, chunkBB, 10, -3, 8, 10, -3, 10, false, random,
&stoneSelector); &stoneSelector);
placeBlock(level, Tile::mossStone_Id, 0, 10, -2, 9, chunkBB); placeBlock(level, Tile::mossyCobblestone_Id, 0, 10, -2, 9, chunkBB);
placeBlock(level, Tile::redStoneDust_Id, 0, 8, -2, 9, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 8, -2, 9, chunkBB);
placeBlock(level, Tile::redStoneDust_Id, 0, 8, -2, 10, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 8, -2, 10, chunkBB);
placeBlock(level, Tile::redStoneDust_Id, 0, 10, -1, 9, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 10, -1, 9, chunkBB);
@ -701,11 +806,136 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess(
void ScatteredFeaturePieces::JunglePyramidPiece::MossStoneSelector::next( void ScatteredFeaturePieces::JunglePyramidPiece::MossStoneSelector::next(
Random* random, int worldX, int worldY, int worldZ, bool isEdge) { Random* random, int worldX, int worldY, int worldZ, bool isEdge) {
if (random->nextFloat() < .4f) { if (random->nextFloat() < .4f) {
nextId = Tile::stoneBrick_Id; nextId = Tile::cobblestone_Id;
} else { } else {
nextId = Tile::mossStone_Id; nextId = Tile::mossyCobblestone_Id;
} }
} }
ScatteredFeaturePieces::JunglePyramidPiece::MossStoneSelector ScatteredFeaturePieces::JunglePyramidPiece::MossStoneSelector
ScatteredFeaturePieces::JunglePyramidPiece::stoneSelector; ScatteredFeaturePieces::JunglePyramidPiece::stoneSelector;
ScatteredFeaturePieces::SwamplandHut::SwamplandHut() {
spawnedWitch = false;
// for reflection
}
ScatteredFeaturePieces::SwamplandHut::SwamplandHut(Random* random, int west,
int north)
: ScatteredFeaturePiece(random, west, 64, north, 7, 5, 9) {
spawnedWitch = false;
}
void ScatteredFeaturePieces::SwamplandHut::addAdditonalSaveData(
CompoundTag* tag) {
ScatteredFeaturePiece::addAdditonalSaveData(tag);
tag->putBoolean(L"Witch", spawnedWitch);
}
void ScatteredFeaturePieces::SwamplandHut::readAdditonalSaveData(
CompoundTag* tag) {
ScatteredFeaturePiece::readAdditonalSaveData(tag);
spawnedWitch = tag->getBoolean(L"Witch");
}
bool ScatteredFeaturePieces::SwamplandHut::postProcess(Level* level,
Random* random,
BoundingBox* chunkBB) {
if (!updateAverageGroundHeight(level, chunkBB, 0)) {
return false;
}
// floor and ceiling
generateBox(level, chunkBB, 1, 1, 1, 5, 1, 7, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
generateBox(level, chunkBB, 1, 4, 2, 5, 4, 7, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
generateBox(level, chunkBB, 2, 1, 0, 4, 1, 0, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
// walls
generateBox(level, chunkBB, 2, 2, 2, 3, 3, 2, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
generateBox(level, chunkBB, 1, 2, 3, 1, 3, 6, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
generateBox(level, chunkBB, 5, 2, 3, 5, 3, 6, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
generateBox(level, chunkBB, 2, 2, 7, 4, 3, 7, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
// pillars
generateBox(level, chunkBB, 1, 0, 2, 1, 3, 2, Tile::treeTrunk_Id,
Tile::treeTrunk_Id, false);
generateBox(level, chunkBB, 5, 0, 2, 5, 3, 2, Tile::treeTrunk_Id,
Tile::treeTrunk_Id, false);
generateBox(level, chunkBB, 1, 0, 7, 1, 3, 7, Tile::treeTrunk_Id,
Tile::treeTrunk_Id, false);
generateBox(level, chunkBB, 5, 0, 7, 5, 3, 7, Tile::treeTrunk_Id,
Tile::treeTrunk_Id, false);
// windows
placeBlock(level, Tile::fence_Id, 0, 2, 3, 2, chunkBB);
placeBlock(level, Tile::fence_Id, 0, 3, 3, 7, chunkBB);
placeBlock(level, 0, 0, 1, 3, 4, chunkBB);
placeBlock(level, 0, 0, 5, 3, 4, chunkBB);
placeBlock(level, 0, 0, 5, 3, 5, chunkBB);
placeBlock(level, Tile::flowerPot_Id, FlowerPotTile::TYPE_MUSHROOM_RED, 1,
3, 5, chunkBB);
// decoration
placeBlock(level, Tile::workBench_Id, 0, 3, 2, 6, chunkBB);
placeBlock(level, Tile::cauldron_Id, 0, 4, 2, 6, chunkBB);
// front railings
placeBlock(level, Tile::fence_Id, 0, 1, 2, 1, chunkBB);
placeBlock(level, Tile::fence_Id, 0, 5, 2, 1, chunkBB);
// placeBlock(level, Tile.torch.id, 0, 1, 3, 1, chunkBB);
// placeBlock(level, Tile.torch.id, 0, 5, 3, 1, chunkBB);
// ceiling edges
int south = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_NORTH);
int east = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_WEST);
int west = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_EAST);
int north = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_SOUTH);
generateBox(level, chunkBB, 0, 4, 1, 6, 4, 1, Tile::stairs_sprucewood_Id,
south, Tile::stairs_sprucewood_Id, south, false);
generateBox(level, chunkBB, 0, 4, 2, 0, 4, 7, Tile::stairs_sprucewood_Id,
west, Tile::stairs_sprucewood_Id, west, false);
generateBox(level, chunkBB, 6, 4, 2, 6, 4, 7, Tile::stairs_sprucewood_Id,
east, Tile::stairs_sprucewood_Id, east, false);
generateBox(level, chunkBB, 0, 4, 8, 6, 4, 8, Tile::stairs_sprucewood_Id,
north, Tile::stairs_sprucewood_Id, north, false);
// fill pillars down to solid ground
for (int z = 2; z <= 7; z += 5) {
for (int x = 1; x <= 5; x += 4) {
fillColumnDown(level, Tile::treeTrunk_Id, 0, x, -1, z, chunkBB);
}
}
if (!spawnedWitch) {
int wx = getWorldX(2, 5);
int wy = getWorldY(2);
int wz = getWorldZ(2, 5);
if (chunkBB->isInside(wx, wy, wz)) {
spawnedWitch = true;
std::shared_ptr<Witch> witch =
std::shared_ptr<Witch>(new Witch(level));
witch->moveTo(wx + .5, wy, wz + .5, 0, 0);
witch->finalizeMobSpawn(NULL);
level->addEntity(witch);
}
}
return true;
}

View file

@ -3,6 +3,9 @@
#include "StructurePiece.h" #include "StructurePiece.h"
class ScatteredFeaturePieces { class ScatteredFeaturePieces {
public:
static void loadStatic();
private: private:
class ScatteredFeaturePiece : public StructurePiece { class ScatteredFeaturePiece : public StructurePiece {
protected: protected:
@ -12,9 +15,12 @@ private:
int heightPosition; int heightPosition;
ScatteredFeaturePiece();
ScatteredFeaturePiece(Random* random, int west, int floor, int north, ScatteredFeaturePiece(Random* random, int west, int floor, int north,
int width, int height, int depth); int width, int height, int depth);
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
bool updateAverageGroundHeight(Level* level, BoundingBox* chunkBB, bool updateAverageGroundHeight(Level* level, BoundingBox* chunkBB,
int offset); int offset);
}; };
@ -22,21 +28,38 @@ private:
public: public:
class DesertPyramidPiece : public ScatteredFeaturePiece { class DesertPyramidPiece : public ScatteredFeaturePiece {
public: public:
static const int TREASURE_ITEMS_COUNT = 6; static StructurePiece* Create() { return new DesertPyramidPiece(); }
virtual EStructurePiece GetType() {
return eStructurePiece_DesertPyramidPiece;
}
public:
static const int TREASURE_ITEMS_COUNT = 10;
private: private:
bool hasPlacedChest[4]; bool hasPlacedChest[4];
static WeighedTreasure* treasureItems[TREASURE_ITEMS_COUNT]; static WeighedTreasure* treasureItems[TREASURE_ITEMS_COUNT];
public: public:
DesertPyramidPiece();
DesertPyramidPiece(Random* random, int west, int north); DesertPyramidPiece(Random* random, int west, int north);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
bool postProcess(Level* level, Random* random, BoundingBox* chunkBB); bool postProcess(Level* level, Random* random, BoundingBox* chunkBB);
}; };
class JunglePyramidPiece : public ScatteredFeaturePiece { class JunglePyramidPiece : public ScatteredFeaturePiece {
public: public:
static const int TREASURE_ITEMS_COUNT = 6; static StructurePiece* Create() { return new JunglePyramidPiece(); }
virtual EStructurePiece GetType() {
return eStructurePiece_JunglePyramidPiece;
}
public:
static const int TREASURE_ITEMS_COUNT = 10;
static const int DISPENSER_ITEMS_COUNT = 1; static const int DISPENSER_ITEMS_COUNT = 1;
private: private:
@ -49,8 +72,14 @@ public:
static WeighedTreasure* dispenserItems[DISPENSER_ITEMS_COUNT]; static WeighedTreasure* dispenserItems[DISPENSER_ITEMS_COUNT];
public: public:
JunglePyramidPiece();
JunglePyramidPiece(Random* random, int west, int north); JunglePyramidPiece(Random* random, int west, int north);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
public:
bool postProcess(Level* level, Random* random, BoundingBox* chunkBB); bool postProcess(Level* level, Random* random, BoundingBox* chunkBB);
private: private:
@ -62,4 +91,26 @@ public:
static MossStoneSelector stoneSelector; static MossStoneSelector stoneSelector;
}; };
class SwamplandHut : public ScatteredFeaturePiece {
public:
static StructurePiece* Create() { return new SwamplandHut(); }
virtual EStructurePiece GetType() {
return eStructurePiece_SwamplandHut;
}
private:
bool spawnedWitch;
public:
SwamplandHut();
SwamplandHut(Random* random, int west, int north);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
public:
bool postProcess(Level* level, Random* random, BoundingBox* chunkBB);
};
}; };

View file

@ -5,6 +5,7 @@
#include "../../Headers/net.minecraft.world.level.tile.entity.h" #include "../../Headers/net.minecraft.world.level.tile.entity.h"
#include "../../Headers/net.minecraft.world.level.storage.h" #include "../../Headers/net.minecraft.world.level.storage.h"
#include "../../Headers/net.minecraft.world.level.levelgen.h" #include "../../Headers/net.minecraft.world.level.levelgen.h"
#include "../../Headers/net.minecraft.world.level.levelgen.structure.h"
#include "../../Headers/net.minecraft.world.item.h" #include "../../Headers/net.minecraft.world.item.h"
#include "../../Util/WeighedTreasure.h" #include "../../Util/WeighedTreasure.h"
#include "../../IO/Files/FileHeader.h" #include "../../IO/Files/FileHeader.h"
@ -15,6 +16,35 @@ std::list<StrongholdPieces::PieceWeight*> StrongholdPieces::currentPieces;
StrongholdPieces::EPieceClass StrongholdPieces::imposedPiece; StrongholdPieces::EPieceClass StrongholdPieces::imposedPiece;
const bool StrongholdPieces::CHECK_AIR = true; const bool StrongholdPieces::CHECK_AIR = true;
void StrongholdPieces::loadStatic() {
StructureFeatureIO::setPieceId(eStructurePiece_ChestCorridor,
ChestCorridor::Create, L"SHCC");
StructureFeatureIO::setPieceId(eStructurePiece_FillerCorridor,
FillerCorridor::Create, L"SHFC");
StructureFeatureIO::setPieceId(eStructurePiece_FiveCrossing,
FiveCrossing::Create, L"SH5C");
StructureFeatureIO::setPieceId(eStructurePiece_LeftTurn, LeftTurn::Create,
L"SHLT");
StructureFeatureIO::setPieceId(eStructurePiece_Library, Library::Create,
L"SHLi");
StructureFeatureIO::setPieceId(eStructurePiece_PortalRoom,
PortalRoom::Create, L"SHPR");
StructureFeatureIO::setPieceId(eStructurePiece_PrisonHall,
PrisonHall::Create, L"SHPH");
StructureFeatureIO::setPieceId(eStructurePiece_RightTurn, RightTurn::Create,
L"SHRT");
StructureFeatureIO::setPieceId(eStructurePiece_StrongholdRoomCrossing,
RoomCrossing::Create, L"SHRC");
StructureFeatureIO::setPieceId(eStructurePiece_StairsDown,
StairsDown::Create, L"SHSD");
StructureFeatureIO::setPieceId(eStructurePiece_StrongholdStartPiece,
StartPiece::Create, L"SHStart");
StructureFeatureIO::setPieceId(eStructurePiece_Straight, Straight::Create,
L"SHS");
StructureFeatureIO::setPieceId(eStructurePiece_StraightStairsDown,
StraightStairsDown::Create, L"SHSSD");
}
StrongholdPieces::PieceWeight::PieceWeight(EPieceClass pieceClass, int weight, StrongholdPieces::PieceWeight::PieceWeight(EPieceClass pieceClass, int weight,
int maxPlaceCount) int maxPlaceCount)
: weight(weight) { : weight(weight) {
@ -223,8 +253,24 @@ StructurePiece* StrongholdPieces::generateAndAddPiece(
return newPiece; return newPiece;
} }
StrongholdPieces::StrongholdPiece::StrongholdPiece() {
entryDoor = OPENING;
// for reflection
}
StrongholdPieces::StrongholdPiece::StrongholdPiece(int genDepth) StrongholdPieces::StrongholdPiece::StrongholdPiece(int genDepth)
: StructurePiece(genDepth) {} : StructurePiece(genDepth) {
entryDoor = OPENING;
}
void StrongholdPieces::StrongholdPiece::addAdditonalSaveData(CompoundTag* tag) {
tag->putString(L"EntryDoor", _toString<int>(entryDoor));
}
void StrongholdPieces::StrongholdPiece::readAdditonalSaveData(
CompoundTag* tag) {
entryDoor = (SmallDoorType)_fromString<int>(tag->getString(L"EntryDoor"));
}
void StrongholdPieces::StrongholdPiece::generateSmallDoor( void StrongholdPieces::StrongholdPiece::generateSmallDoor(
Level* level, Random* random, BoundingBox* chunkBB, Level* level, Random* random, BoundingBox* chunkBB,
@ -238,20 +284,20 @@ void StrongholdPieces::StrongholdPiece::generateSmallDoor(
footY + SMALL_DOOR_HEIGHT - 1, footZ, 0, 0, false); footY + SMALL_DOOR_HEIGHT - 1, footZ, 0, 0, false);
break; break;
case WOOD_DOOR: case WOOD_DOOR:
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX, footY, footZ, placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY, footZ,
chunkBB); chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX, footY + 1, placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 1, footZ,
chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 2, footZ,
chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, footX + 1, footY + 2,
footZ, chunkBB); footZ, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX, footY + 2, placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 2,
footZ, chunkBB); footZ, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX + 1, placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 1,
footY + 2, footZ, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX + 2,
footY + 2, footZ, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX + 2,
footY + 1, footZ, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX + 2, footY,
footZ, chunkBB); footZ, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY, footZ,
chunkBB);
placeBlock(level, Tile::door_wood_Id, 0, footX + 1, footY, footZ, placeBlock(level, Tile::door_wood_Id, 0, footX + 1, footY, footZ,
chunkBB); chunkBB);
placeBlock(level, Tile::door_wood_Id, DoorTile::UPPER_BIT, placeBlock(level, Tile::door_wood_Id, DoorTile::UPPER_BIT,
@ -276,20 +322,20 @@ void StrongholdPieces::StrongholdPiece::generateSmallDoor(
chunkBB); chunkBB);
break; break;
case IRON_DOOR: case IRON_DOOR:
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX, footY, footZ, placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY, footZ,
chunkBB); chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX, footY + 1, placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 1, footZ,
chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY + 2, footZ,
chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, footX + 1, footY + 2,
footZ, chunkBB); footZ, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX, footY + 2, placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 2,
footZ, chunkBB); footZ, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX + 1, placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 1,
footY + 2, footZ, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX + 2,
footY + 2, footZ, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX + 2,
footY + 1, footZ, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX + 2, footY,
footZ, chunkBB); footZ, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY, footZ,
chunkBB);
placeBlock(level, Tile::door_iron_Id, 0, footX + 1, footY, footZ, placeBlock(level, Tile::door_iron_Id, 0, footX + 1, footY, footZ,
chunkBB); chunkBB);
placeBlock(level, Tile::door_iron_Id, DoorTile::UPPER_BIT, placeBlock(level, Tile::door_iron_Id, DoorTile::UPPER_BIT,
@ -431,6 +477,10 @@ bool StrongholdPieces::StrongholdPiece::isOkBox(BoundingBox* box,
return bIsOk; return bIsOk;
} }
StrongholdPieces::FillerCorridor::FillerCorridor() : steps(0) {
// for reflection
}
StrongholdPieces::FillerCorridor::FillerCorridor(int genDepth, Random* random, StrongholdPieces::FillerCorridor::FillerCorridor(int genDepth, Random* random,
BoundingBox* corridorBox, BoundingBox* corridorBox,
int direction) int direction)
@ -442,6 +492,16 @@ StrongholdPieces::FillerCorridor::FillerCorridor(int genDepth, Random* random,
boundingBox = corridorBox; boundingBox = corridorBox;
} }
void StrongholdPieces::FillerCorridor::addAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::addAdditonalSaveData(tag);
tag->putInt(L"Steps", steps);
}
void StrongholdPieces::FillerCorridor::readAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::readAdditonalSaveData(tag);
steps = tag->getInt(L"Steps");
}
BoundingBox* StrongholdPieces::FillerCorridor::findPieceBox( BoundingBox* StrongholdPieces::FillerCorridor::findPieceBox(
std::list<StructurePiece*>* pieces, Random* random, int footX, int footY, std::list<StructurePiece*>* pieces, Random* random, int footX, int footY,
int footZ, int direction) { int footZ, int direction) {
@ -469,8 +529,7 @@ BoundingBox* StrongholdPieces::FillerCorridor::findPieceBox(
if (!collisionPiece->getBoundingBox()->intersects(box)) { if (!collisionPiece->getBoundingBox()->intersects(box)) {
delete box; delete box;
// the corridor has shrunk enough to fit, but make it // the corridor has shrunk enough to fit, but make it
// one step too big to build an entrance into the other // one step too big to build an entrance into the other block
// block
return BoundingBox::orientBox(footX, footY, footZ, -1, -1, 0, 5, return BoundingBox::orientBox(footX, footY, footZ, -1, -1, 0, 5,
5, depth, direction); 5, depth, direction);
} }
@ -490,34 +549,39 @@ bool StrongholdPieces::FillerCorridor::postProcess(Level* level, Random* random,
// filler corridor // filler corridor
for (int i = 0; i < steps; i++) { for (int i = 0; i < steps; i++) {
// row 0 // row 0
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 0, 0, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 0, 0, i, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 0, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 1, 0, i, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, 0, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 2, 0, i, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 0, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 3, 0, i, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 4, 0, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 4, 0, i, chunkBB);
// row 1-3 // row 1-3
for (int y = 1; y <= 3; y++) { for (int y = 1; y <= 3; y++) {
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 0, y, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 0, y, i, chunkBB);
placeBlock(level, 0, 0, 1, y, i, chunkBB); placeBlock(level, 0, 0, 1, y, i, chunkBB);
placeBlock(level, 0, 0, 2, y, i, chunkBB); placeBlock(level, 0, 0, 2, y, i, chunkBB);
placeBlock(level, 0, 0, 3, y, i, chunkBB); placeBlock(level, 0, 0, 3, y, i, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 4, y, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 4, y, i, chunkBB);
} }
// row 4 // row 4
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 0, 4, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 0, 4, i, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 4, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 1, 4, i, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, 4, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 2, 4, i, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 4, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 3, 4, i, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 4, 4, i, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 4, 4, i, chunkBB);
} }
return true; return true;
} }
StrongholdPieces::StairsDown::StairsDown() {
// for reflection
}
StrongholdPieces::StairsDown::StairsDown(int genDepth, Random* random, int west, StrongholdPieces::StairsDown::StairsDown(int genDepth, Random* random, int west,
int north) int north)
: StrongholdPiece(genDepth), isSource(true), entryDoor(OPENING) { : StrongholdPiece(genDepth), isSource(true) {
orientation = random->nextInt(4); orientation = random->nextInt(4);
entryDoor = OPENING;
switch (orientation) { switch (orientation) {
case Direction::NORTH: case Direction::NORTH:
@ -534,13 +598,22 @@ StrongholdPieces::StairsDown::StairsDown(int genDepth, Random* random, int west,
StrongholdPieces::StairsDown::StairsDown(int genDepth, Random* random, StrongholdPieces::StairsDown::StairsDown(int genDepth, Random* random,
BoundingBox* stairsBox, int direction) BoundingBox* stairsBox, int direction)
: StrongholdPiece(genDepth), : StrongholdPiece(genDepth), isSource(false) {
isSource(false), entryDoor = randomSmallDoor(random);
entryDoor(randomSmallDoor(random)) {
orientation = direction; orientation = direction;
boundingBox = stairsBox; boundingBox = stairsBox;
} }
void StrongholdPieces::StairsDown::addAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::addAdditonalSaveData(tag);
tag->putBoolean(L"Source", isSource);
}
void StrongholdPieces::StairsDown::readAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::readAdditonalSaveData(tag);
isSource = tag->getBoolean(L"Source");
}
void StrongholdPieces::StairsDown::addChildren( void StrongholdPieces::StairsDown::addChildren(
StructurePiece* startPiece, std::list<StructurePiece*>* pieces, StructurePiece* startPiece, std::list<StructurePiece*>* pieces,
Random* random) { Random* random) {
@ -587,33 +660,37 @@ bool StrongholdPieces::StairsDown::postProcess(Level* level, Random* random,
generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1);
// stair steps // stair steps
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, 6, 1, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 2, 6, 1, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 5, 1, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 1, 5, 1, chunkBB);
placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 6, placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 6,
1, chunkBB); 1, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 5, 2, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 1, 5, 2, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 4, 3, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 1, 4, 3, chunkBB);
placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 5, placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 5,
3, chunkBB); 3, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, 4, 3, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 2, 4, 3, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 3, 3, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 3, 3, 3, chunkBB);
placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 3, 4, placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 3, 4,
3, chunkBB); 3, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 3, 2, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 3, 3, 2, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 2, 1, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 3, 2, 1, chunkBB);
placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 3, 3, placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 3, 3,
1, chunkBB); 1, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, 2, 1, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 2, 2, 1, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 1, 1, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 1, 1, 1, chunkBB);
placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 2, placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 2,
1, chunkBB); 1, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 1, 2, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 1, 1, 2, chunkBB);
placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 1, placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 1,
3, chunkBB); 3, chunkBB);
return true; return true;
} }
StrongholdPieces::StartPiece::StartPiece() {
// for reflection
}
StrongholdPieces::StartPiece::StartPiece(int genDepth, Random* random, int west, StrongholdPieces::StartPiece::StartPiece(int genDepth, Random* random, int west,
int north, Level* level) int north, Level* level)
: StairsDown(0, random, west, north) { : StairsDown(0, random, west, north) {
@ -632,16 +709,32 @@ TilePos* StrongholdPieces::StartPiece::getLocatorPosition() {
return StairsDown::getLocatorPosition(); return StairsDown::getLocatorPosition();
} }
StrongholdPieces::Straight::Straight() {
// for reflection
}
StrongholdPieces::Straight::Straight(int genDepth, Random* random, StrongholdPieces::Straight::Straight(int genDepth, Random* random,
BoundingBox* stairsBox, int direction) BoundingBox* stairsBox, int direction)
: StrongholdPiece(genDepth), : StrongholdPiece(genDepth),
entryDoor(randomSmallDoor(random)),
leftChild(random->nextInt(2) == 0), leftChild(random->nextInt(2) == 0),
rightChild(random->nextInt(2) == 0) { rightChild(random->nextInt(2) == 0) {
entryDoor = randomSmallDoor(random);
orientation = direction; orientation = direction;
boundingBox = stairsBox; boundingBox = stairsBox;
} }
void StrongholdPieces::Straight::addAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::addAdditonalSaveData(tag);
tag->putBoolean(L"Left", leftChild);
tag->putBoolean(L"Right", rightChild);
}
void StrongholdPieces::Straight::readAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::readAdditonalSaveData(tag);
leftChild = tag->getBoolean(L"Left");
rightChild = tag->getBoolean(L"Right");
}
void StrongholdPieces::Straight::addChildren(StructurePiece* startPiece, void StrongholdPieces::Straight::addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, std::list<StructurePiece*>* pieces,
Random* random) { Random* random) {
@ -719,16 +812,38 @@ WeighedTreasure*
new WeighedTreasure(Item::helmet_iron_Id, 0, 1, 1, 5), new WeighedTreasure(Item::helmet_iron_Id, 0, 1, 1, 5),
new WeighedTreasure(Item::leggings_iron_Id, 0, 1, 1, 5), new WeighedTreasure(Item::leggings_iron_Id, 0, 1, 1, 5),
new WeighedTreasure(Item::boots_iron_Id, 0, 1, 1, 5), new WeighedTreasure(Item::boots_iron_Id, 0, 1, 1, 5),
new WeighedTreasure(Item::apple_gold_Id, 0, 1, 1, 1)}; new WeighedTreasure(Item::apple_gold_Id, 0, 1, 1, 1),
// very rare for strongholds ...
new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 1),
new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1),
new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 1),
new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1),
// ...
};
StrongholdPieces::ChestCorridor::ChestCorridor() {
// for reflection
}
StrongholdPieces::ChestCorridor::ChestCorridor(int genDepth, Random* random, StrongholdPieces::ChestCorridor::ChestCorridor(int genDepth, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
int direction) int direction)
: StrongholdPiece(genDepth), entryDoor(randomSmallDoor(random)) { : StrongholdPiece(genDepth) {
entryDoor = randomSmallDoor(random);
orientation = direction; orientation = direction;
boundingBox = stairsBox; boundingBox = stairsBox;
} }
void StrongholdPieces::ChestCorridor::addAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::addAdditonalSaveData(tag);
tag->putBoolean(L"Chest", hasPlacedChest);
}
void StrongholdPieces::ChestCorridor::readAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::readAdditonalSaveData(tag);
hasPlacedChest = tag->getBoolean(L"Chest");
}
void StrongholdPieces::ChestCorridor::addChildren( void StrongholdPieces::ChestCorridor::addChildren(
StructurePiece* startPiece, std::list<StructurePiece*>* pieces, StructurePiece* startPiece, std::list<StructurePiece*>* pieces,
Random* random) { Random* random) {
@ -771,8 +886,8 @@ bool StrongholdPieces::ChestCorridor::postProcess(Level* level, Random* random,
generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1);
// chest placement // chest placement
generateBox(level, chunkBB, 3, 1, 2, 3, 1, 4, Tile::stoneBrickSmooth_Id, generateBox(level, chunkBB, 3, 1, 2, 3, 1, 4, Tile::stoneBrick_Id,
Tile::stoneBrickSmooth_Id, false); Tile::stoneBrick_Id, false);
placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB,
3, 1, 1, chunkBB); 3, 1, 1, chunkBB);
placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB,
@ -803,11 +918,16 @@ bool StrongholdPieces::ChestCorridor::postProcess(Level* level, Random* random,
return true; return true;
} }
StrongholdPieces::StraightStairsDown::StraightStairsDown() {
// for reflection
}
StrongholdPieces::StraightStairsDown::StraightStairsDown(int genDepth, StrongholdPieces::StraightStairsDown::StraightStairsDown(int genDepth,
Random* random, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
int direction) int direction)
: StrongholdPiece(genDepth), entryDoor(randomSmallDoor(random)) { : StrongholdPiece(genDepth) {
entryDoor = randomSmallDoor(random);
orientation = direction; orientation = direction;
boundingBox = stairsBox; boundingBox = stairsBox;
} }
@ -866,21 +986,26 @@ bool StrongholdPieces::StraightStairsDown::postProcess(Level* level,
placeBlock(level, Tile::stairs_stone_Id, orientationData, 3, placeBlock(level, Tile::stairs_stone_Id, orientationData, 3,
height - 5 - i, 1 + i, chunkBB); height - 5 - i, 1 + i, chunkBB);
if (i < 5) { if (i < 5) {
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, height - 6 - i, placeBlock(level, Tile::stoneBrick_Id, 0, 1, height - 6 - i, 1 + i,
1 + i, chunkBB); chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, height - 6 - i, placeBlock(level, Tile::stoneBrick_Id, 0, 2, height - 6 - i, 1 + i,
1 + i, chunkBB); chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, height - 6 - i, placeBlock(level, Tile::stoneBrick_Id, 0, 3, height - 6 - i, 1 + i,
1 + i, chunkBB); chunkBB);
} }
} }
return true; return true;
} }
StrongholdPieces::LeftTurn::LeftTurn() {
// for reflection
}
StrongholdPieces::LeftTurn::LeftTurn(int genDepth, Random* random, StrongholdPieces::LeftTurn::LeftTurn(int genDepth, Random* random,
BoundingBox* stairsBox, int direction) BoundingBox* stairsBox, int direction)
: StrongholdPiece(genDepth), entryDoor(randomSmallDoor(random)) { : StrongholdPiece(genDepth) {
entryDoor = randomSmallDoor(random);
orientation = direction; orientation = direction;
boundingBox = stairsBox; boundingBox = stairsBox;
} }
@ -938,6 +1063,10 @@ bool StrongholdPieces::LeftTurn::postProcess(Level* level, Random* random,
return true; return true;
} }
StrongholdPieces::RightTurn::RightTurn() {
// for reflection
}
StrongholdPieces::RightTurn::RightTurn(int genDepth, Random* random, StrongholdPieces::RightTurn::RightTurn(int genDepth, Random* random,
BoundingBox* stairsBox, int direction) BoundingBox* stairsBox, int direction)
: LeftTurn(genDepth, random, stairsBox, direction) {} : LeftTurn(genDepth, random, stairsBox, direction) {}
@ -976,16 +1105,29 @@ bool StrongholdPieces::RightTurn::postProcess(Level* level, Random* random,
return true; return true;
} }
StrongholdPieces::RoomCrossing::RoomCrossing() {
// for reflection
}
StrongholdPieces::RoomCrossing::RoomCrossing(int genDepth, Random* random, StrongholdPieces::RoomCrossing::RoomCrossing(int genDepth, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
int direction) int direction)
: StrongholdPiece(genDepth), : StrongholdPiece(genDepth), type(random->nextInt(5)) {
entryDoor(randomSmallDoor(random)), entryDoor = randomSmallDoor(random);
type(random->nextInt(5)) {
orientation = direction; orientation = direction;
boundingBox = stairsBox; boundingBox = stairsBox;
} }
void StrongholdPieces::RoomCrossing::addAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::addAdditonalSaveData(tag);
tag->putInt(L"Type", type);
}
void StrongholdPieces::RoomCrossing::readAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::readAdditonalSaveData(tag);
type = tag->getInt(L"Type");
}
void StrongholdPieces::RoomCrossing::addChildren( void StrongholdPieces::RoomCrossing::addChildren(
StructurePiece* startPiece, std::list<StructurePiece*>* pieces, StructurePiece* startPiece, std::list<StructurePiece*>* pieces,
Random* random) { Random* random) {
@ -1046,9 +1188,9 @@ bool StrongholdPieces::RoomCrossing::postProcess(Level* level, Random* random,
break; break;
case 0: case 0:
// middle torch pillar // middle torch pillar
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 1, 5, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 5, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 2, 5, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 5, 2, 5, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 3, 5, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 5, chunkBB);
placeBlock(level, Tile::torch_Id, 0, 4, 3, 5, chunkBB); placeBlock(level, Tile::torch_Id, 0, 4, 3, 5, chunkBB);
placeBlock(level, Tile::torch_Id, 0, 6, 3, 5, chunkBB); placeBlock(level, Tile::torch_Id, 0, 6, 3, 5, chunkBB);
placeBlock(level, Tile::torch_Id, 0, 5, 3, 4, chunkBB); placeBlock(level, Tile::torch_Id, 0, 5, 3, 4, chunkBB);
@ -1064,42 +1206,38 @@ bool StrongholdPieces::RoomCrossing::postProcess(Level* level, Random* random,
break; break;
case 1: { case 1: {
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 1, 3 + i, placeBlock(level, Tile::stoneBrick_Id, 0, 3, 1, 3 + i, chunkBB);
chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 7, 1, 3 + i, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 7, 1, 3 + i, placeBlock(level, Tile::stoneBrick_Id, 0, 3 + i, 1, 3, chunkBB);
chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 3 + i, 1, 7, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3 + i, 1, 3,
chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3 + i, 1, 7,
chunkBB);
} }
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 1, 5, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 5, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 2, 5, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 5, 2, 5, chunkBB);
placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 3, 5, chunkBB); placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 5, chunkBB);
placeBlock(level, Tile::water_Id, 0, 5, 4, 5, chunkBB); placeBlock(level, Tile::water_Id, 0, 5, 4, 5, chunkBB);
} break; } break;
case 2: { case 2: {
for (int z = 1; z <= 9; z++) { for (int z = 1; z <= 9; z++) {
placeBlock(level, Tile::stoneBrick_Id, 0, 1, 3, z, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 1, 3, z, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 9, 3, z, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 9, 3, z, chunkBB);
} }
for (int x = 1; x <= 9; x++) { for (int x = 1; x <= 9; x++) {
placeBlock(level, Tile::stoneBrick_Id, 0, x, 3, 1, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, x, 3, 1, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, x, 3, 9, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, x, 3, 9, chunkBB);
} }
placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 4, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 5, 1, 4, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 6, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 5, 1, 6, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 4, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 5, 3, 4, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 6, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 5, 3, 6, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 4, 1, 5, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 4, 1, 5, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 6, 1, 5, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 6, 1, 5, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 4, 3, 5, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 4, 3, 5, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 6, 3, 5, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 6, 3, 5, chunkBB);
for (int y = 1; y <= 3; y++) { for (int y = 1; y <= 3; y++) {
placeBlock(level, Tile::stoneBrick_Id, 0, 4, y, 4, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 4, y, 4, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 6, y, 4, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 6, y, 4, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 4, y, 6, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 4, y, 6, chunkBB);
placeBlock(level, Tile::stoneBrick_Id, 0, 6, y, 6, chunkBB); placeBlock(level, Tile::cobblestone_Id, 0, 6, y, 6, chunkBB);
} }
placeBlock(level, Tile::torch_Id, 0, 5, 3, 5, chunkBB); placeBlock(level, Tile::torch_Id, 0, 5, 3, 5, chunkBB);
for (int z = 2; z <= 8; z++) { for (int z = 2; z <= 8; z++) {
@ -1138,9 +1276,14 @@ bool StrongholdPieces::RoomCrossing::postProcess(Level* level, Random* random,
return true; return true;
} }
StrongholdPieces::PrisonHall::PrisonHall() {
// for reflection
}
StrongholdPieces::PrisonHall::PrisonHall(int genDepth, Random* random, StrongholdPieces::PrisonHall::PrisonHall(int genDepth, Random* random,
BoundingBox* stairsBox, int direction) BoundingBox* stairsBox, int direction)
: StrongholdPiece(genDepth), entryDoor(randomSmallDoor(random)) { : StrongholdPiece(genDepth) {
entryDoor = randomSmallDoor(random);
orientation = direction; orientation = direction;
boundingBox = stairsBox; boundingBox = stairsBox;
} }
@ -1218,15 +1361,29 @@ bool StrongholdPieces::PrisonHall::postProcess(Level* level, Random* random,
return true; return true;
} }
StrongholdPieces::Library::Library() {
isTall = false;
// for reflection
}
StrongholdPieces::Library::Library(int genDepth, Random* random, StrongholdPieces::Library::Library(int genDepth, Random* random,
BoundingBox* roomBox, int direction) BoundingBox* roomBox, int direction)
: StrongholdPiece(genDepth), : StrongholdPiece(genDepth), isTall(roomBox->getYSpan() > height) {
entryDoor(randomSmallDoor(random)), entryDoor = randomSmallDoor(random);
isTall(roomBox->getYSpan() > height) {
orientation = direction; orientation = direction;
boundingBox = roomBox; boundingBox = roomBox;
} }
void StrongholdPieces::Library::addAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::addAdditonalSaveData(tag);
tag->putBoolean(L"Tall", isTall);
}
void StrongholdPieces::Library::readAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::readAdditonalSaveData(tag);
isTall = tag->getBoolean(L"Tall");
}
StrongholdPieces::Library* StrongholdPieces::Library::createPiece( StrongholdPieces::Library* StrongholdPieces::Library::createPiece(
std::list<StructurePiece*>* pieces, Random* random, int footX, int footY, std::list<StructurePiece*>* pieces, Random* random, int footX, int footY,
int footZ, int direction, int genDepth) { int footZ, int direction, int genDepth) {
@ -1426,10 +1583,16 @@ bool StrongholdPieces::Library::postProcess(Level* level, Random* random,
return true; return true;
} }
StrongholdPieces::FiveCrossing::FiveCrossing() {
leftLow = leftHigh = rightLow = rightHigh = false;
// for reflection
}
StrongholdPieces::FiveCrossing::FiveCrossing(int genDepth, Random* random, StrongholdPieces::FiveCrossing::FiveCrossing(int genDepth, Random* random,
BoundingBox* stairsBox, BoundingBox* stairsBox,
int direction) int direction)
: StrongholdPiece(genDepth), entryDoor(randomSmallDoor(random)) { : StrongholdPiece(genDepth) {
entryDoor = randomSmallDoor(random);
orientation = direction; orientation = direction;
boundingBox = stairsBox; boundingBox = stairsBox;
@ -1439,6 +1602,22 @@ StrongholdPieces::FiveCrossing::FiveCrossing(int genDepth, Random* random,
rightHigh = random->nextInt(3) > 0; rightHigh = random->nextInt(3) > 0;
} }
void StrongholdPieces::FiveCrossing::addAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::addAdditonalSaveData(tag);
tag->putBoolean(L"leftLow", leftLow);
tag->putBoolean(L"leftHigh", leftHigh);
tag->putBoolean(L"rightLow", rightLow);
tag->putBoolean(L"rightHigh", rightHigh);
}
void StrongholdPieces::FiveCrossing::readAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::readAdditonalSaveData(tag);
leftLow = tag->getBoolean(L"leftLow");
leftHigh = tag->getBoolean(L"leftHigh");
rightLow = tag->getBoolean(L"rightLow");
rightHigh = tag->getBoolean(L"rightHigh");
}
void StrongholdPieces::FiveCrossing::addChildren( void StrongholdPieces::FiveCrossing::addChildren(
StructurePiece* startPiece, std::list<StructurePiece*>* pieces, StructurePiece* startPiece, std::list<StructurePiece*>* pieces,
Random* random) { Random* random) {
@ -1544,6 +1723,10 @@ bool StrongholdPieces::FiveCrossing::postProcess(Level* level, Random* random,
return true; return true;
} }
StrongholdPieces::PortalRoom::PortalRoom() {
// for reflection
}
StrongholdPieces::PortalRoom::PortalRoom(int genDepth, Random* random, StrongholdPieces::PortalRoom::PortalRoom(int genDepth, Random* random,
BoundingBox* box, int direction) BoundingBox* box, int direction)
: StrongholdPiece(genDepth) { : StrongholdPiece(genDepth) {
@ -1552,6 +1735,16 @@ StrongholdPieces::PortalRoom::PortalRoom(int genDepth, Random* random,
boundingBox = box; boundingBox = box;
} }
void StrongholdPieces::PortalRoom::addAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::addAdditonalSaveData(tag);
tag->putBoolean(L"Mob", hasPlacedMobSpawner);
}
void StrongholdPieces::PortalRoom::readAdditonalSaveData(CompoundTag* tag) {
StrongholdPiece::readAdditonalSaveData(tag);
hasPlacedMobSpawner = tag->getBoolean(L"Mob");
}
void StrongholdPieces::PortalRoom::addChildren( void StrongholdPieces::PortalRoom::addChildren(
StructurePiece* startPiece, std::list<StructurePiece*>* pieces, StructurePiece* startPiece, std::list<StructurePiece*>* pieces,
Random* random) { Random* random) {
@ -1629,8 +1822,7 @@ bool StrongholdPieces::PortalRoom::postProcess(Level* level, Random* random,
} }
// stair // stair
int orientationData = int orientationData = getOrientationData(Tile::stairs_stoneBrick_Id, 3);
getOrientationData(Tile::stairs_stoneBrickSmooth_Id, 3);
generateBox(level, chunkBB, 4, 1, 5, 6, 1, 7, false, random, generateBox(level, chunkBB, 4, 1, 5, 6, 1, 7, false, random,
(BlockSelector*)smoothStoneSelector); (BlockSelector*)smoothStoneSelector);
generateBox(level, chunkBB, 4, 2, 6, 6, 2, 7, false, random, generateBox(level, chunkBB, 4, 2, 6, 6, 2, 7, false, random,
@ -1638,12 +1830,12 @@ bool StrongholdPieces::PortalRoom::postProcess(Level* level, Random* random,
generateBox(level, chunkBB, 4, 3, 7, 6, 3, 7, false, random, generateBox(level, chunkBB, 4, 3, 7, 6, 3, 7, false, random,
(BlockSelector*)smoothStoneSelector); (BlockSelector*)smoothStoneSelector);
for (int x = 4; x <= 6; x++) { for (int x = 4; x <= 6; x++) {
placeBlock(level, Tile::stairs_stoneBrickSmooth_Id, orientationData, x, placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 1, 4,
1, 4, chunkBB); chunkBB);
placeBlock(level, Tile::stairs_stoneBrickSmooth_Id, orientationData, x, placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 2, 5,
2, 5, chunkBB); chunkBB);
placeBlock(level, Tile::stairs_stoneBrickSmooth_Id, orientationData, x, placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 3, 6,
3, 6, chunkBB); chunkBB);
} }
int north = Direction::NORTH; int north = Direction::NORTH;
@ -1749,11 +1941,13 @@ bool StrongholdPieces::PortalRoom::postProcess(Level* level, Random* random,
level->getLevelData()->setHasStrongholdEndPortal(); level->getLevelData()->setHasStrongholdEndPortal();
hasPlacedMobSpawner = true; hasPlacedMobSpawner = true;
level->setTile(x, y, z, Tile::mobSpawner_Id); level->setTileAndData(x, y, z, Tile::mobSpawner_Id, 0,
Tile::UPDATE_CLIENTS);
std::shared_ptr<MobSpawnerTileEntity> entity = std::shared_ptr<MobSpawnerTileEntity> entity =
std::dynamic_pointer_cast<MobSpawnerTileEntity>( std::dynamic_pointer_cast<MobSpawnerTileEntity>(
level->getTileEntity(x, y, z)); level->getTileEntity(x, y, z));
if (entity != NULL) entity->setEntityId(L"Silverfish"); if (entity != NULL)
entity->getSpawner()->setEntityId(L"Silverfish");
} }
} }
@ -1764,7 +1958,7 @@ void StrongholdPieces::SmoothStoneSelector::next(Random* random, int worldX,
int worldY, int worldZ, int worldY, int worldZ,
bool isEdge) { bool isEdge) {
if (isEdge) { if (isEdge) {
nextId = Tile::stoneBrickSmooth_Id; nextId = Tile::stoneBrick_Id;
float selection = random->nextFloat(); float selection = random->nextFloat();
if (selection < 0.2f) { if (selection < 0.2f) {

View file

@ -28,6 +28,10 @@ private:
EPieceClass_PortalRoom EPieceClass_PortalRoom
}; };
public:
static void loadStatic();
private:
class PieceWeight { class PieceWeight {
public: public:
EPieceClass pieceClass; // 4J - was Class<? extends StrongholdPiece> EPieceClass pieceClass; // 4J - was Class<? extends StrongholdPiece>
@ -36,7 +40,6 @@ private:
int maxPlaceCount; int maxPlaceCount;
PieceWeight(EPieceClass pieceClass, int weight, int maxPlaceCount); PieceWeight(EPieceClass pieceClass, int weight, int maxPlaceCount);
virtual ~PieceWeight() {}
virtual bool doPlace(int depth); virtual bool doPlace(int depth);
bool isValid(); bool isValid();
}; };
@ -94,8 +97,6 @@ private:
private: private:
class StrongholdPiece : public StructurePiece { class StrongholdPiece : public StructurePiece {
protected: protected:
StrongholdPiece(int genDepth);
enum SmallDoorType { enum SmallDoorType {
OPENING, OPENING,
WOOD_DOOR, WOOD_DOOR,
@ -103,6 +104,17 @@ private:
IRON_DOOR, IRON_DOOR,
}; };
SmallDoorType entryDoor;
public:
StrongholdPiece();
protected:
StrongholdPiece(int genDepth);
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
void generateSmallDoor(Level* level, Random* random, void generateSmallDoor(Level* level, Random* random,
BoundingBox* chunkBB, SmallDoorType doorType, BoundingBox* chunkBB, SmallDoorType doorType,
int footX, int footY, int footZ); int footX, int footY, int footZ);
@ -127,13 +139,25 @@ private:
*/ */
public: public:
class FillerCorridor : public StrongholdPiece { class FillerCorridor : public StrongholdPiece {
public:
static StructurePiece* Create() { return new FillerCorridor(); }
virtual EStructurePiece GetType() {
return eStructurePiece_FillerCorridor;
}
private: private:
const int steps; int steps;
public: public:
FillerCorridor();
FillerCorridor(int genDepth, Random* random, BoundingBox* corridorBox, FillerCorridor(int genDepth, Random* random, BoundingBox* corridorBox,
int direction); int direction);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
public:
static BoundingBox* findPieceBox(std::list<StructurePiece*>* pieces, static BoundingBox* findPieceBox(std::list<StructurePiece*>* pieces,
Random* random, int footX, int footY, Random* random, int footX, int footY,
int footZ, int direction); int footZ, int direction);
@ -147,19 +171,28 @@ public:
*/ */
public: public:
class StairsDown : public StrongholdPiece { class StairsDown : public StrongholdPiece {
public:
static StructurePiece* Create() { return new StairsDown(); }
virtual EStructurePiece GetType() { return eStructurePiece_StairsDown; }
private: private:
static const int width = 5; static const int width = 5;
static const int height = 11; static const int height = 11;
static const int depth = 5; static const int depth = 5;
const bool isSource; bool isSource;
const SmallDoorType entryDoor;
public: public:
StairsDown();
StairsDown(int genDepth, Random* random, int west, int north); StairsDown(int genDepth, Random* random, int west, int north);
StairsDown(int genDepth, Random* random, BoundingBox* stairsBox, StairsDown(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
public:
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, std::list<StructurePiece*>* pieces,
Random* random); Random* random);
@ -174,6 +207,11 @@ public:
class PortalRoom; class PortalRoom;
class StartPiece : public StairsDown { class StartPiece : public StairsDown {
public:
virtual EStructurePiece GetType() {
return eStructurePiece_StrongholdStartPiece;
}
public: public:
bool isLibraryAdded; bool isLibraryAdded;
PieceWeight* previousPiece; PieceWeight* previousPiece;
@ -184,6 +222,7 @@ public:
// called in a random order // called in a random order
std::vector<StructurePiece*> pendingChildren; std::vector<StructurePiece*> pendingChildren;
StartPiece();
StartPiece(int genDepth, Random* random, int west, int north, StartPiece(int genDepth, Random* random, int west, int north,
Level* level); // 4J Added level param Level* level); // 4J Added level param
virtual TilePos* getLocatorPosition(); virtual TilePos* getLocatorPosition();
@ -195,18 +234,28 @@ public:
*/ */
public: public:
class Straight : public StrongholdPiece { class Straight : public StrongholdPiece {
public:
static StructurePiece* Create() { return new Straight(); }
virtual EStructurePiece GetType() { return eStructurePiece_Straight; }
private: private:
static const int width = 5; static const int width = 5;
static const int height = 5; static const int height = 5;
static const int depth = 7; static const int depth = 7;
const SmallDoorType entryDoor; bool leftChild;
const bool leftChild; bool rightChild;
const bool rightChild;
public: public:
Straight();
Straight(int genDepth, Random* random, BoundingBox* stairsBox, Straight(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
public:
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, std::list<StructurePiece*>* pieces,
Random* random); Random* random);
@ -223,19 +272,31 @@ public:
*/ */
class ChestCorridor : public StrongholdPiece { class ChestCorridor : public StrongholdPiece {
public:
static StructurePiece* Create() { return new ChestCorridor(); }
virtual EStructurePiece GetType() {
return eStructurePiece_ChestCorridor;
}
private: private:
static const int width = 5; static const int width = 5;
static const int height = 5; static const int height = 5;
static const int depth = 7; static const int depth = 7;
static const int TREASURE_ITEMS_COUNT = 14; static const int TREASURE_ITEMS_COUNT = 18;
static WeighedTreasure* treasureItems[TREASURE_ITEMS_COUNT]; static WeighedTreasure* treasureItems[TREASURE_ITEMS_COUNT];
const SmallDoorType entryDoor; bool hasPlacedChest;
boolean hasPlacedChest;
public: public:
ChestCorridor();
ChestCorridor(int genDepth, Random* random, BoundingBox* stairsBox, ChestCorridor(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
public:
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, std::list<StructurePiece*>* pieces,
Random* random); Random* random);
@ -253,14 +314,19 @@ public:
*/ */
public: public:
class StraightStairsDown : public StrongholdPiece { class StraightStairsDown : public StrongholdPiece {
public:
static StructurePiece* Create() { return new StraightStairsDown(); }
virtual EStructurePiece GetType() {
return eStructurePiece_StraightStairsDown;
}
private: private:
static const int width = 5; static const int width = 5;
static const int height = 11; static const int height = 11;
static const int depth = 8; static const int depth = 8;
const SmallDoorType entryDoor;
public: public:
StraightStairsDown();
StraightStairsDown(int genDepth, Random* random, BoundingBox* stairsBox, StraightStairsDown(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -279,14 +345,17 @@ public:
*/ */
public: public:
class LeftTurn : public StrongholdPiece { class LeftTurn : public StrongholdPiece {
public:
static StructurePiece* Create() { return new LeftTurn(); }
virtual EStructurePiece GetType() { return eStructurePiece_LeftTurn; }
protected: protected:
static const int width = 5; static const int width = 5;
static const int height = 5; static const int height = 5;
static const int depth = 5; static const int depth = 5;
const SmallDoorType entryDoor;
public: public:
LeftTurn();
LeftTurn(int genDepth, Random* random, BoundingBox* stairsBox, LeftTurn(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -306,6 +375,11 @@ public:
public: public:
class RightTurn : public LeftTurn { class RightTurn : public LeftTurn {
public: public:
static StructurePiece* Create() { return new RightTurn(); }
virtual EStructurePiece GetType() { return eStructurePiece_RightTurn; }
public:
RightTurn();
RightTurn(int genDepth, Random* random, BoundingBox* stairsBox, RightTurn(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -321,6 +395,12 @@ public:
*/ */
public: public:
class RoomCrossing : public StrongholdPiece { class RoomCrossing : public StrongholdPiece {
public:
static StructurePiece* Create() { return new RoomCrossing(); }
virtual EStructurePiece GetType() {
return eStructurePiece_StrongholdRoomCrossing;
}
private: private:
static const int SMALL_TREASURE_ITEMS_COUNT = 7; // 4J added static const int SMALL_TREASURE_ITEMS_COUNT = 7; // 4J added
static WeighedTreasure* smallTreasureItems[SMALL_TREASURE_ITEMS_COUNT]; static WeighedTreasure* smallTreasureItems[SMALL_TREASURE_ITEMS_COUNT];
@ -331,12 +411,18 @@ public:
static const int depth = 11; static const int depth = 11;
protected: protected:
const SmallDoorType entryDoor; int type;
const int type;
public: public:
RoomCrossing();
RoomCrossing(int genDepth, Random* random, BoundingBox* stairsBox, RoomCrossing(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
public:
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, std::list<StructurePiece*>* pieces,
Random* random); Random* random);
@ -354,14 +440,17 @@ public:
*/ */
public: public:
class PrisonHall : public StrongholdPiece { class PrisonHall : public StrongholdPiece {
public:
static StructurePiece* Create() { return new PrisonHall(); }
virtual EStructurePiece GetType() { return eStructurePiece_PrisonHall; }
protected: protected:
static const int width = 9; static const int width = 9;
static const int height = 5; static const int height = 5;
static const int depth = 11; static const int depth = 11;
const SmallDoorType entryDoor;
public: public:
PrisonHall();
PrisonHall(int genDepth, Random* random, BoundingBox* stairsBox, PrisonHall(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
@ -380,6 +469,10 @@ public:
*/ */
public: public:
class Library : public StrongholdPiece { class Library : public StrongholdPiece {
public:
static StructurePiece* Create() { return new Library(); }
virtual EStructurePiece GetType() { return eStructurePiece_Library; }
private: private:
static const int LIBRARY_TREASURE_ITEMS_COUNT = 4; // 4J added static const int LIBRARY_TREASURE_ITEMS_COUNT = 4; // 4J added
static WeighedTreasure* static WeighedTreasure*
@ -391,14 +484,19 @@ public:
static const int tallHeight = 11; static const int tallHeight = 11;
static const int depth = 15; static const int depth = 15;
const SmallDoorType entryDoor;
private: private:
const bool isTall; bool isTall;
public: public:
Library();
Library(int genDepth, Random* random, BoundingBox* roomBox, Library(int genDepth, Random* random, BoundingBox* roomBox,
int direction); int direction);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
public:
static Library* createPiece(std::list<StructurePiece*>* pieces, static Library* createPiece(std::list<StructurePiece*>* pieces,
Random* random, int footX, int footY, Random* random, int footX, int footY,
int footZ, int direction, int genDepth); int footZ, int direction, int genDepth);
@ -412,19 +510,30 @@ public:
*/ */
public: public:
class FiveCrossing : public StrongholdPiece { class FiveCrossing : public StrongholdPiece {
public:
static StructurePiece* Create() { return new FiveCrossing(); }
virtual EStructurePiece GetType() {
return eStructurePiece_FiveCrossing;
}
protected: protected:
static const int width = 10; static const int width = 10;
static const int height = 9; static const int height = 9;
static const int depth = 11; static const int depth = 11;
const SmallDoorType entryDoor;
private: private:
bool leftLow, leftHigh, rightLow, rightHigh; bool leftLow, leftHigh, rightLow, rightHigh;
public: public:
FiveCrossing();
FiveCrossing(int genDepth, Random* random, BoundingBox* stairsBox, FiveCrossing(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
public:
virtual void addChildren(StructurePiece* startPiece, virtual void addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, std::list<StructurePiece*>* pieces,
Random* random); Random* random);
@ -442,6 +551,10 @@ public:
*/ */
class PortalRoom : public StrongholdPiece { class PortalRoom : public StrongholdPiece {
public:
static StructurePiece* Create() { return new PortalRoom(); }
virtual EStructurePiece GetType() { return eStructurePiece_PortalRoom; }
protected: protected:
static const int width = 11; static const int width = 11;
static const int height = 8; static const int height = 8;
@ -451,8 +564,15 @@ public:
bool hasPlacedMobSpawner; bool hasPlacedMobSpawner;
public: public:
PortalRoom();
PortalRoom(int genDepth, Random* random, BoundingBox* stairsBox, PortalRoom(int genDepth, Random* random, BoundingBox* stairsBox,
int direction); int direction);
protected:
virtual void addAdditonalSaveData(CompoundTag* tag);
virtual void readAdditonalSaveData(CompoundTag* tag);
public:
void addChildren(StructurePiece* startPiece, void addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, Random* random); std::list<StructurePiece*>* pieces, Random* random);
static PortalRoom* createPiece(std::list<StructurePiece*>* pieces, static PortalRoom* createPiece(std::list<StructurePiece*>* pieces,

View file

@ -1,4 +1,5 @@
#include "../../Platform/stdafx.h" #include "../../Platform/stdafx.h"
#include "../../Headers/net.minecraft.world.level.levelgen.structure.h"
#include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.h"
#include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.h"
#include "../../Headers/net.minecraft.world.level.material.h" #include "../../Headers/net.minecraft.world.level.material.h"
@ -41,6 +42,13 @@
* chunks, leading to infinite loops and other errors. * chunks, leading to infinite loops and other errors.
*/ */
StructurePiece::StructurePiece() {
boundingBox = NULL;
orientation = 0;
genDepth = 0;
// for reflection
}
StructurePiece::StructurePiece(int genDepth) { StructurePiece::StructurePiece(int genDepth) {
boundingBox = NULL; boundingBox = NULL;
this->genDepth = genDepth; this->genDepth = genDepth;
@ -51,6 +59,29 @@ StructurePiece::~StructurePiece() {
if (boundingBox != NULL) delete boundingBox; if (boundingBox != NULL) delete boundingBox;
} }
CompoundTag* StructurePiece::createTag() {
CompoundTag* tag = new CompoundTag();
tag->putString(L"id", StructureFeatureIO::getEncodeId(this));
tag->put(L"BB", boundingBox->createTag(L"BB"));
tag->putInt(L"O", orientation);
tag->putInt(L"GD", genDepth);
addAdditonalSaveData(tag);
return tag;
}
void StructurePiece::load(Level* level, CompoundTag* tag) {
if (tag->contains(L"BB")) {
boundingBox = new BoundingBox(tag->getIntArray(L"BB"));
}
orientation = tag->getInt(L"O");
genDepth = tag->getInt(L"GD");
readAdditonalSaveData(tag);
}
void StructurePiece::addChildren(StructurePiece* startPiece, void StructurePiece::addChildren(StructurePiece* startPiece,
std::list<StructurePiece*>* pieces, std::list<StructurePiece*>* pieces,
Random* random) {} Random* random) {}
@ -172,10 +203,10 @@ int StructurePiece::getWorldZ(int x, int z) {
int StructurePiece::getOrientationData(int tile, int data) { int StructurePiece::getOrientationData(int tile, int data) {
if (tile == Tile::rail->id) { if (tile == Tile::rail->id) {
if (orientation == Direction::WEST || orientation == Direction::EAST) { if (orientation == Direction::WEST || orientation == Direction::EAST) {
if (data == RailTile::DIR_FLAT_X) { if (data == BaseRailTile::DIR_FLAT_X) {
return RailTile::DIR_FLAT_Z; return BaseRailTile::DIR_FLAT_Z;
} else { } else {
return RailTile::DIR_FLAT_X; return BaseRailTile::DIR_FLAT_X;
} }
} }
} else if (tile == Tile::door_wood_Id || tile == Tile::door_iron_Id) { } else if (tile == Tile::door_wood_Id || tile == Tile::door_iron_Id) {
@ -201,7 +232,7 @@ int StructurePiece::getOrientationData(int tile, int data) {
} }
} else if (tile == Tile::stairs_stone_Id || tile == Tile::stairs_wood_Id || } else if (tile == Tile::stairs_stone_Id || tile == Tile::stairs_wood_Id ||
tile == Tile::stairs_netherBricks_Id || tile == Tile::stairs_netherBricks_Id ||
tile == Tile::stairs_stoneBrickSmooth_Id || tile == Tile::stairs_stoneBrick_Id ||
tile == Tile::stairs_sandstone_Id) { tile == Tile::stairs_sandstone_Id) {
if (orientation == Direction::SOUTH) { if (orientation == Direction::SOUTH) {
if (data == 2) { if (data == 2) {
@ -394,7 +425,8 @@ void StructurePiece::placeBlock(Level* level, int block, int data, int x, int y,
// SuperFlat) // SuperFlat)
if (worldY == 0) return; if (worldY == 0) return;
level->setTileAndDataNoUpdate(worldX, worldY, worldZ, block, data); level->setTileAndData(worldX, worldY, worldZ, block, data,
Tile::UPDATE_CLIENTS);
} }
/** /**
@ -590,7 +622,8 @@ void StructurePiece::generateAirColumnUp(Level* level, int x, int startY, int z,
while (!level->isEmptyTile(worldX, worldY, worldZ) && while (!level->isEmptyTile(worldX, worldY, worldZ) &&
worldY < Level::maxBuildHeight - 1) { worldY < Level::maxBuildHeight - 1) {
level->setTileAndDataNoUpdate(worldX, worldY, worldZ, 0, 0); level->setTileAndData(worldX, worldY, worldZ, 0, 0,
Tile::UPDATE_CLIENTS);
worldY++; worldY++;
} }
} }
@ -608,7 +641,8 @@ void StructurePiece::fillColumnDown(Level* level, int tile, int tileData, int x,
while ((level->isEmptyTile(worldX, worldY, worldZ) || while ((level->isEmptyTile(worldX, worldY, worldZ) ||
level->getMaterial(worldX, worldY, worldZ)->isLiquid()) && level->getMaterial(worldX, worldY, worldZ)->isLiquid()) &&
worldY > 1) { worldY > 1) {
level->setTileAndDataNoUpdate(worldX, worldY, worldZ, tile, tileData); level->setTileAndData(worldX, worldY, worldZ, tile, tileData,
Tile::UPDATE_CLIENTS);
worldY--; worldY--;
} }
} }
@ -622,7 +656,8 @@ bool StructurePiece::createChest(Level* level, BoundingBox* chunkBB,
if (chunkBB->isInside(worldX, worldY, worldZ)) { if (chunkBB->isInside(worldX, worldY, worldZ)) {
if (level->getTile(worldX, worldY, worldZ) != Tile::chest->id) { if (level->getTile(worldX, worldY, worldZ) != Tile::chest->id) {
level->setTile(worldX, worldY, worldZ, Tile::chest->id); level->setTileAndData(worldX, worldY, worldZ, Tile::chest->id, 0,
Tile::UPDATE_CLIENTS);
std::shared_ptr<ChestTileEntity> chest = std::shared_ptr<ChestTileEntity> chest =
std::dynamic_pointer_cast<ChestTileEntity>( std::dynamic_pointer_cast<ChestTileEntity>(
level->getTileEntity(worldX, worldY, worldZ)); level->getTileEntity(worldX, worldY, worldZ));
@ -647,7 +682,8 @@ bool StructurePiece::createDispenser(Level* level, BoundingBox* chunkBB,
if (level->getTile(worldX, worldY, worldZ) != Tile::dispenser_Id) { if (level->getTile(worldX, worldY, worldZ) != Tile::dispenser_Id) {
level->setTileAndData( level->setTileAndData(
worldX, worldY, worldZ, Tile::dispenser_Id, worldX, worldY, worldZ, Tile::dispenser_Id,
getOrientationData(Tile::dispenser_Id, facing)); getOrientationData(Tile::dispenser_Id, facing),
Tile::UPDATE_CLIENTS);
std::shared_ptr<DispenserTileEntity> dispenser = std::shared_ptr<DispenserTileEntity> dispenser =
std::dynamic_pointer_cast<DispenserTileEntity>( std::dynamic_pointer_cast<DispenserTileEntity>(
level->getTileEntity(worldX, worldY, worldZ)); level->getTileEntity(worldX, worldY, worldZ));

Some files were not shown because too many files have changed in this diff Show more