diff --git a/Minecraft.World/WorldGen/Biomes/BeachBiome.cpp b/Minecraft.World/WorldGen/Biomes/BeachBiome.cpp index dc245389a..cfa68b6b4 100644 --- a/Minecraft.World/WorldGen/Biomes/BeachBiome.cpp +++ b/Minecraft.World/WorldGen/Biomes/BeachBiome.cpp @@ -7,8 +7,8 @@ BeachBiome::BeachBiome(int id) : Biome(id) { // remove default mob spawn settings friendlies.clear(); friendlies_chicken.clear(); // 4J added - this->topMaterial = (uint8_t)Tile::sand_Id; - this->material = (uint8_t)Tile::sand_Id; + topMaterial = (uint8_t)Tile::sand_Id; + material = (uint8_t)Tile::sand_Id; decorator->treeCount = -999; decorator->deadBushCount = 0; diff --git a/Minecraft.World/WorldGen/Biomes/Biome.cpp b/Minecraft.World/WorldGen/Biomes/Biome.cpp index dbb53de36..ebcb1ce16 100644 --- a/Minecraft.World/WorldGen/Biomes/Biome.cpp +++ b/Minecraft.World/WorldGen/Biomes/Biome.cpp @@ -309,9 +309,10 @@ Biome::Biome(int id) : id(id) { m_waterColor = eMinecraftColour_NOT_SET; /* 4J - removing these so that we can consistently return newly created -trees via getTreeFeature, and let the calling function be resposible for -deleting the returned tree normalTree = new TreeFeature(); fancyTree = new -BasicTree(); birchTree = new BirchFeature(); swampTree = new SwampTreeFeature(); + trees via getTreeFeature, and let the calling function be resposible for + deleting the returned tree normalTree = new TreeFeature(); fancyTree = new + BasicTree(); birchTree = new BirchFeature(); swampTree = new + SwampTreeFeature(); */ biomes[id] = this; @@ -333,6 +334,8 @@ BasicTree(); birchTree = new BirchFeature(); swampTree = new SwampTreeFeature(); // wolves are added to forests and taigas waterFriendlies.push_back(new MobSpawnerData(eTYPE_SQUID, 10, 4, 4)); + + ambientFriendlies.push_back(new MobSpawnerData(eTYPE_BAT, 10, 8, 8)); } Biome::~Biome() { @@ -354,7 +357,7 @@ Biome* Biome::setLeafFoliageWaterSkyColor(eMinecraftColour grassColor, } Biome* Biome::setTemperatureAndDownfall(float temp, float downfall) { - this->temperature = temp; + temperature = temp; this->downfall = downfall; return this; } @@ -388,7 +391,7 @@ Feature* Biome::getGrassFeature(Random* random) { } Biome* Biome::setSnowCovered() { - this->snowCovered = true; + snowCovered = true; return this; } @@ -426,6 +429,7 @@ std::vector* Biome::getMobs(MobCategory* category) { if (category == MobCategory::creature_wolf) return &friendlies_wolf; if (category == MobCategory::creature_mushroomcow) return &friendlies_mushroomcow; + if (category == MobCategory::ambient) return &ambientFriendlies; return NULL; } diff --git a/Minecraft.World/WorldGen/Biomes/Biome.h b/Minecraft.World/WorldGen/Biomes/Biome.h index 1fc9a8c72..dd9ecd3e3 100644 --- a/Minecraft.World/WorldGen/Biomes/Biome.h +++ b/Minecraft.World/WorldGen/Biomes/Biome.h @@ -86,6 +86,7 @@ protected: std::vector friendlies_chicken; std::vector friendlies_wolf; std::vector friendlies_mushroomcow; + std::vector ambientFriendlies; Biome(int id); ~Biome(); @@ -109,9 +110,9 @@ private: protected: /* removing these so that we can consistently return newly created trees via -getTreeFeature, and let the calling function be resposible for deleting the -returned tree TreeFeature *normalTree; BasicTree *fancyTree; BirchFeature -*birchTree; SwampTreeFeature *swampTree; + getTreeFeature, and let the calling function be resposible for deleting the + returned tree TreeFeature *normalTree; BasicTree *fancyTree; BirchFeature + *birchTree; SwampTreeFeature *swampTree; */ public: diff --git a/Minecraft.World/WorldGen/Biomes/BiomeCache.cpp b/Minecraft.World/WorldGen/Biomes/BiomeCache.cpp index d647ffa1f..bc4f1109c 100644 --- a/Minecraft.World/WorldGen/Biomes/BiomeCache.cpp +++ b/Minecraft.World/WorldGen/Biomes/BiomeCache.cpp @@ -7,8 +7,10 @@ BiomeCache::Block::Block(int x, int z, BiomeCache* parent) { // temps = floatArray(ZONE_SIZE * ZONE_SIZE, false); // MGH - - // added "no clear" flag to arrayWithLength downfall = floatArray(ZONE_SIZE - // * ZONE_SIZE, false); biomes = BiomeArray(ZONE_SIZE * ZONE_SIZE, false); + // added "no clear" flag to arrayWithLength downfall = + // floatArray(ZONE_SIZE + // * ZONE_SIZE, false); biomes = BiomeArray(ZONE_SIZE * ZONE_SIZE, + // false); biomeIndices = byteArray(ZONE_SIZE * ZONE_SIZE, false); lastUse = 0; @@ -35,7 +37,7 @@ BiomeCache::Block::~Block() { Biome* BiomeCache::Block::getBiome(int x, int z) { // return biomes[(x & ZONE_SIZE_MASK) | ((z & ZONE_SIZE_MASK) << - //ZONE_SIZE_BITS)]; + // ZONE_SIZE_BITS)]; int biomeIndex = biomeIndices[(x & ZONE_SIZE_MASK) | ((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) { // return temps[(x & ZONE_SIZE_MASK) | ((z & ZONE_SIZE_MASK) << - //ZONE_SIZE_BITS)]; + // ZONE_SIZE_BITS)]; int biomeIndex = biomeIndices[(x & ZONE_SIZE_MASK) | ((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) { return getBlockAt(x, z)->biomeIndices; -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Biomes/BiomeCache.h b/Minecraft.World/WorldGen/Biomes/BiomeCache.h index 9c7601800..0d541baf7 100644 --- a/Minecraft.World/WorldGen/Biomes/BiomeCache.h +++ b/Minecraft.World/WorldGen/Biomes/BiomeCache.h @@ -1,5 +1,5 @@ #pragma once -#include "../../Util/JavaIntHash.h" +#include "../Minecraft.World/JavaIntHash.h" class BiomeCache { private: @@ -49,4 +49,4 @@ public: private: CRITICAL_SECTION m_CS; -}; +}; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Biomes/BiomeDecorator.cpp b/Minecraft.World/WorldGen/Biomes/BiomeDecorator.cpp index ca5f25ed1..696ec40af 100644 --- a/Minecraft.World/WorldGen/Biomes/BiomeDecorator.cpp +++ b/Minecraft.World/WorldGen/Biomes/BiomeDecorator.cpp @@ -49,8 +49,8 @@ void BiomeDecorator::_init() { lapisOreFeature = new OreFeature(Tile::lapisOre_Id, 6); yellowFlowerFeature = new FlowerFeature(Tile::flower_Id); roseFlowerFeature = new FlowerFeature(Tile::rose_Id); - brownMushroomFeature = new FlowerFeature(Tile::mushroom1_Id); - redMushroomFeature = new FlowerFeature(Tile::mushroom2_Id); + brownMushroomFeature = new FlowerFeature(Tile::mushroom_brown_Id); + redMushroomFeature = new FlowerFeature(Tile::mushroom_red_Id); hugeMushroomFeature = new HugeMushroomFeature(); reedsFeature = new ReedsFeature(); cactusFeature = new CactusFeature(); diff --git a/Minecraft.World/WorldGen/Biomes/BiomeSource.cpp b/Minecraft.World/WorldGen/Biomes/BiomeSource.cpp index d1f981a62..0cffcecec 100644 --- a/Minecraft.World/WorldGen/Biomes/BiomeSource.cpp +++ b/Minecraft.World/WorldGen/Biomes/BiomeSource.cpp @@ -239,6 +239,7 @@ void BiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, */ bool BiomeSource::containsOnly(int x, int z, int r, std::vector allowed) { + IntCache::releaseAll(); int x0 = ((x - r) >> 2); int z0 = ((z - 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 */ bool BiomeSource::containsOnly(int x, int z, int r, Biome* allowed) { + IntCache::releaseAll(); int x0 = ((x - r) >> 2); int z0 = ((z - 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, Random* random) { + IntCache::releaseAll(); int x0 = ((x - r) >> 2); int z0 = ((z - 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, std::vector allowed, Random* random) { + IntCache::releaseAll(); int x0 = ((x - r) >> 2); int z0 = ((z - 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); TilePos* res = NULL; int found = 0; - int biomesCount = w * h; - for (unsigned int i = 0; i < biomesCount; i++) { + for (unsigned int i = 0; i < w * h; i++) { int xx = (x0 + i % w) << 2; int zz = (z0 + i / w) << 2; Biome* b = Biome::biomes[biomes[i]]; @@ -376,7 +379,7 @@ int64_t BiomeSource::findSeed(LevelType* generator) #ifndef _CONTENT_PACKAGE if (app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) & - (1L << eDebugSetting_EnableHeightWaterBiomeOverride)) { + (1L << eDebugSetting_EnableBiomeOverride)) { // Do nothing } else #endif @@ -590,4 +593,4 @@ bool BiomeSource::getIsMatch(float* frac) { // or more - currently there's 8 critical so this just forces at least 1 // more others return (typeCount >= 9); -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Biomes/DesertBiome.cpp b/Minecraft.World/WorldGen/Biomes/DesertBiome.cpp index ebf590dc4..e01145c8d 100644 --- a/Minecraft.World/WorldGen/Biomes/DesertBiome.cpp +++ b/Minecraft.World/WorldGen/Biomes/DesertBiome.cpp @@ -27,4 +27,4 @@ void DesertBiome::decorate(Level* level, Random* random, int xo, int zo) { Feature* well = new DesertWellFeature(); well->place(level, random, x, level->getHeightmap(x, z) + 1, z); } -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Biomes/ExtremeHillsBiome.cpp b/Minecraft.World/WorldGen/Biomes/ExtremeHillsBiome.cpp index 73bd164bc..5ce0fb2db 100644 --- a/Minecraft.World/WorldGen/Biomes/ExtremeHillsBiome.cpp +++ b/Minecraft.World/WorldGen/Biomes/ExtremeHillsBiome.cpp @@ -1,9 +1,15 @@ #include "../../Platform/stdafx.h" #include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.tile.h" +#include "../../Headers/net.minecraft.world.level.levelgen.feature.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) { 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 z = zo + random->nextInt(16); int tile = level->getTile(x, y, z); - if (tile == Tile::rock_Id) { - level->setTileNoUpdate(x, y, z, Tile::emeraldOre_Id); + if (tile == Tile::stone_Id) { + level->setTileAndData(x, y, z, Tile::emeraldOre_Id, 0, + Tile::UPDATE_CLIENTS); } } } + + for (int i = 0; i < 7; i++) { + int x = xo + random->nextInt(16); + int y = random->nextInt(Level::genDepth / 2); + int z = zo + random->nextInt(16); + silverfishFeature->place(level, random, x, y, z); + } } diff --git a/Minecraft.World/WorldGen/Biomes/ExtremeHillsBiome.h b/Minecraft.World/WorldGen/Biomes/ExtremeHillsBiome.h index 29bae0098..39e11e6ce 100644 --- a/Minecraft.World/WorldGen/Biomes/ExtremeHillsBiome.h +++ b/Minecraft.World/WorldGen/Biomes/ExtremeHillsBiome.h @@ -7,9 +7,11 @@ class ExtremeHillsBiome : public Biome { private: static const bool GENERATE_EMERALD_ORE = true; + Feature* silverfishFeature; protected: ExtremeHillsBiome(int id); + ~ExtremeHillsBiome(); public: void decorate(Level* level, Random* random, int xo, int zo); diff --git a/Minecraft.World/WorldGen/Biomes/FixedBiomeSource.cpp b/Minecraft.World/WorldGen/Biomes/FixedBiomeSource.cpp index a9ccbe062..473fb1d1d 100644 --- a/Minecraft.World/WorldGen/Biomes/FixedBiomeSource.cpp +++ b/Minecraft.World/WorldGen/Biomes/FixedBiomeSource.cpp @@ -2,77 +2,29 @@ #include "../../Util/Arrays.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, float downfall) { - this->biome = fixed; + biome = fixed; this->temperature = temperature; 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; } -/** - * @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; } -/** - * @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; } -/** - * @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, int z, int w, int h) const { - if (!temperatures.data || temperatures.length < w * h) { - if (temperatures.data) delete[] temperatures.data; + if (temperatures.data == NULL || temperatures.length < w * h) { + if (temperatures.data != NULL) delete[] temperatures.data; temperatures = floatArray(w * h); } + 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, int h) const { floatArray temps(w * h); @@ -80,24 +32,15 @@ floatArray FixedBiomeSource::getTemperatureBlock(int x, int z, int w, return temps; } -/** - * @brief Fills a double array with temperature values. - * - * @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 - */ +// 4J - note that caller is responsible for deleting returned array. +// temperatures array is for output only. void FixedBiomeSource::getTemperatureBlock(doubleArray& temperatures, int x, int z, int w, int h) const { temperatures = doubleArray(w * h); - Arrays::fill(temperatures, 0, w * h, static_cast(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, int w, int h) const { 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); } -/** - * @brief Returns a floatArray filled with downfall values. - */ + floatArray FixedBiomeSource::getDownfallBlock(int x, int z, int w, int h) const { floatArray downfalls(w * h); @@ -116,37 +57,30 @@ floatArray FixedBiomeSource::getDownfallBlock(int x, int z, int w, return downfalls; } -/** - * @brief Returns the fixed downfall value at given coordinates. - */ float FixedBiomeSource::getDownfall(int x, int z) const { return downfall; } -/** - * @brief Fills a double array with downfall values. - */ -void FixedBiomeSource::getDownfallBlock(doubleArray& downfalls, int x, int z, +void FixedBiomeSource::getDownfallBlock(doubleArray downfalls, int x, int z, int w, int h) { - if (!downfalls.data || downfalls.length < w * h) { - if (downfalls.data) delete[] downfalls.data; + if (downfalls.data == NULL || downfalls.length < w * h) { + if (downfalls.data != NULL) delete[] downfalls.data; downfalls = doubleArray(w * h); } - Arrays::fill(downfalls, 0, w * h, static_cast(downfall)); + Arrays::fill(downfalls, 0, w * h, (double)downfall); } -/** - * @brief Fills a BiomeArray with the fixed biome for a region. - */ +// 4J - caller is responsible for deleting biomes array, plus any optional +// arrays output if pointers are passed in (_temperatures, _downfalls) void FixedBiomeSource::getBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h, bool useCache) const { MemSect(36); biomes = BiomeArray(w * h); MemSect(0); + Arrays::fill(biomes, 0, w * h, biome); } -/** - * @brief Fills a byteArray with the biome index for a region. - */ +// 4J - caller is responsible for deleting biomes array, plus any optional +// arrays output if pointers are passed in (_temperatures, _downfalls) void FixedBiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, int w, int h, bool useCache) const { MemSect(36); @@ -156,27 +90,21 @@ void FixedBiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, Arrays::fill(biomeIndices, 0, w * h, biomeIndex); } -/** - * @brief Fills a BiomeArray with the fixed biome for a region (raw version). - * @note 4J-PB Added in beyond 1.8.2 - * @note 4J - Caller is responsible for deleting biomes array, plus any optional - * arrays output if pointers are passed in (_temperatures, _downfalls) - */ +// 4J-PB added in from beyond 1.8.2 +// 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, int h) const { MemSect(36); biomes = BiomeArray(w * h); MemSect(0); + Arrays::fill(biomes, 0, w * h, biome); } -/** - * @brief Returns a raw BiomeArray. - * @note 4J-PB Added in beyond 1.8.2 - * @note 4J - caller is responsible for deleting biomes array, plus any - * optional arrays output if pointers are passed in (_temperatures, - * _downfalls) - */ +// 4J-PB added in from beyond 1.8.2 +// 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, int h) const { BiomeArray biomes; @@ -184,9 +112,6 @@ BiomeArray FixedBiomeSource::getRawBiomeBlock(int x, int z, int w, return biomes; } -/** - * @brief Finds a biome within a radius randomly. - */ TilePos* FixedBiomeSource::findBiome(int x, int z, int r, Biome* toFind, Random* random) { if (toFind == biome) { @@ -196,30 +121,22 @@ TilePos* FixedBiomeSource::findBiome(int x, int z, int r, Biome* toFind, return nullptr; } -/** - * @brief Finds a biome from a list of allowed biomes randomly. - */ TilePos* FixedBiomeSource::findBiome(int x, int z, int r, - const std::vector allowed, + std::vector allowed, Random* random) { if (find(allowed.begin(), allowed.end(), biome) != allowed.end()) { return new TilePos(x - r + random->nextInt(r * 2 + 1), 0, 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) { return allowed == biome; } -/** - * @brief Checks if the fixed biome is in the allowed list. - */ bool FixedBiomeSource::containsOnly(int x, int z, int r, - const std::vector allowed) { + std::vector allowed) { return find(allowed.begin(), allowed.end(), biome) != allowed.end(); -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Biomes/FixedBiomeSource.h b/Minecraft.World/WorldGen/Biomes/FixedBiomeSource.h index 1836d4292..4148e3b2e 100644 --- a/Minecraft.World/WorldGen/Biomes/FixedBiomeSource.h +++ b/Minecraft.World/WorldGen/Biomes/FixedBiomeSource.h @@ -1,16 +1,16 @@ #pragma once -#include - #include "BiomeSource.h" class FixedBiomeSource : public BiomeSource { - private: +private: Biome* biome; float temperature, downfall; - public: +public: using BiomeSource::getTemperature; + FixedBiomeSource(Biome* fixed, float temperature, float downfall); + virtual Biome* getBiome(ChunkPos* cp); virtual Biome* getBiome(int x, int z); virtual float getTemperature(int x, int z); @@ -23,23 +23,23 @@ class FixedBiomeSource : public BiomeSource { int h) const; virtual floatArray getDownfallBlock(int x, int z, int w, int h) 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); virtual void getBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h, bool useCache) const; virtual void getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, int w, int h, bool useCache) const; + // 4J-PB added in from beyond 1.8.2 virtual BiomeArray getRawBiomeBlock(int x, int z, int w, int h) const; virtual void getRawBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h) const; + + //////////////////////////////////// virtual TilePos* findBiome(int x, int z, int r, Biome* toFind, Random* random); - virtual TilePos* findBiome(int x, int z, int r, - const std::vector allowed, + virtual TilePos* findBiome(int x, int z, int r, std::vector allowed, Random* random); virtual bool containsOnly(int x, int z, int r, Biome* allowed); - virtual bool containsOnly( - int x, int z, int r, - const std::vector allowed); + virtual bool containsOnly(int x, int z, int r, std::vector allowed); }; diff --git a/Minecraft.World/WorldGen/Biomes/HellBiome.cpp b/Minecraft.World/WorldGen/Biomes/HellBiome.cpp index c508d89b8..273371764 100644 --- a/Minecraft.World/WorldGen/Biomes/HellBiome.cpp +++ b/Minecraft.World/WorldGen/Biomes/HellBiome.cpp @@ -8,6 +8,7 @@ HellBiome::HellBiome(int id) : Biome(id) { friendlies_chicken.clear(); // 4J added friendlies_wolf.clear(); // 4J added waterFriendlies.clear(); + ambientFriendlies.clear(); enemies.push_back(new MobSpawnerData(eTYPE_GHAST, 50, 4, 4)); enemies.push_back(new MobSpawnerData(eTYPE_PIGZOMBIE, 100, 4, 4)); diff --git a/Minecraft.World/WorldGen/Biomes/JungleBiome.cpp b/Minecraft.World/WorldGen/Biomes/JungleBiome.cpp index ef3aaba69..820b2a4b5 100644 --- a/Minecraft.World/WorldGen/Biomes/JungleBiome.cpp +++ b/Minecraft.World/WorldGen/Biomes/JungleBiome.cpp @@ -11,7 +11,7 @@ JungleBiome::JungleBiome(int id) : Biome(id) { decorator->grassCount = 25; 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 friendlies.push_back(new MobSpawnerData(eTYPE_CHICKEN, 10, 4, 4)); diff --git a/Minecraft.World/WorldGen/Biomes/PlainsBiome.cpp b/Minecraft.World/WorldGen/Biomes/PlainsBiome.cpp index feac79930..c86f58566 100644 --- a/Minecraft.World/WorldGen/Biomes/PlainsBiome.cpp +++ b/Minecraft.World/WorldGen/Biomes/PlainsBiome.cpp @@ -2,6 +2,8 @@ #include "../../Headers/net.minecraft.world.level.biome.h" PlainsBiome::PlainsBiome(int id) : Biome(id) { + friendlies.push_back(new MobSpawnerData(eTYPE_HORSE, 5, 2, 6)); + decorator->treeCount = -999; decorator->flowerCount = 4; decorator->grassCount = 10; diff --git a/Minecraft.World/WorldGen/Biomes/SwampBiome.cpp b/Minecraft.World/WorldGen/Biomes/SwampBiome.cpp index 7325f654f..9c50c03cc 100644 --- a/Minecraft.World/WorldGen/Biomes/SwampBiome.cpp +++ b/Minecraft.World/WorldGen/Biomes/SwampBiome.cpp @@ -13,6 +13,8 @@ SwampBiome::SwampBiome(int id) : Biome(id) { decorator->waterlilyCount = 4; // waterColor = 0xe0ffae; + + enemies.push_back(new MobSpawnerData(eTYPE_SLIME, 1, 1, 1)); } Feature* SwampBiome::getTreeFeature(Random* random) { diff --git a/Minecraft.World/WorldGen/Biomes/TheEndBiome.cpp b/Minecraft.World/WorldGen/Biomes/TheEndBiome.cpp index b67d7a0b1..77dce0233 100644 --- a/Minecraft.World/WorldGen/Biomes/TheEndBiome.cpp +++ b/Minecraft.World/WorldGen/Biomes/TheEndBiome.cpp @@ -10,10 +10,11 @@ TheEndBiome::TheEndBiome(int id) : Biome(id) { friendlies_chicken.clear(); // 4J added friendlies_wolf.clear(); // 4J added waterFriendlies.clear(); + ambientFriendlies.clear(); enemies.push_back(new MobSpawnerData(eTYPE_ENDERMAN, 10, 4, 4)); topMaterial = (uint8_t)Tile::dirt_Id; - this->material = (uint8_t)Tile::dirt_Id; + material = (uint8_t)Tile::dirt_Id; decorator = new TheEndBiomeDecorator(this); } diff --git a/Minecraft.World/WorldGen/Features/BirchFeature.cpp b/Minecraft.World/WorldGen/Features/BirchFeature.cpp index 2d2f34ce1..3c3b9174c 100644 --- a/Minecraft.World/WorldGen/Features/BirchFeature.cpp +++ b/Minecraft.World/WorldGen/Features/BirchFeature.cpp @@ -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++) { 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 && (random->nextInt(2) == 0 || yo == 0)) 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, LeafTile::BIRCH_LEAF); } diff --git a/Minecraft.World/WorldGen/Features/BonusChestFeature.cpp b/Minecraft.World/WorldGen/Features/BonusChestFeature.cpp index 5a698dfc9..56bd1b709 100644 --- a/Minecraft.World/WorldGen/Features/BonusChestFeature.cpp +++ b/Minecraft.World/WorldGen/Features/BonusChestFeature.cpp @@ -44,14 +44,13 @@ bool BonusChestFeature::place(Level* level, Random* random, int x, int y, int z, if (force) { x2 = x; - y2 = - y - 1; // 4J - the position passed in is actually two above the - // top solid block, as the calling function adds 1 to - // getTopSolidBlock, and that actually returns the block - // above anyway. this would explain why there is a while - // loop above here (not used in force mode) to move the - // y back down again, shouldn't really be needed if 1 - // wasn't added to the getTopSolidBlock return value. + y2 = y - 1; // 4J - the position passed in is actually two above + // the top solid block, as the calling function adds 1 + // to getTopSolidBlock, and that actually returns the + // block above anyway. + // this would explain why there is a while loop above here (not used + // in force mode) to move the y back down again, shouldn't really be + // needed if 1 wasn't added to the getTopSolidBlock return value. z2 = z; } else { 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) && 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 chest = std::dynamic_pointer_cast( 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) && 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) && 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) && 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) && 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; } diff --git a/Minecraft.World/WorldGen/Features/CactusFeature.cpp b/Minecraft.World/WorldGen/Features/CactusFeature.cpp index 609f1061b..62a97d1d5 100644 --- a/Minecraft.World/WorldGen/Features/CactusFeature.cpp +++ b/Minecraft.World/WorldGen/Features/CactusFeature.cpp @@ -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); for (int yy = 0; yy < h; yy++) { 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); } } } diff --git a/Minecraft.World/WorldGen/Features/CanyonFeature.cpp b/Minecraft.World/WorldGen/Features/CanyonFeature.cpp index 7eba68bf2..cd502aafb 100644 --- a/Minecraft.World/WorldGen/Features/CanyonFeature.cpp +++ b/Minecraft.World/WorldGen/Features/CanyonFeature.cpp @@ -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) { int block = blocks[p]; if (block == Tile::grass_Id) hasGrass = true; - if (block == Tile::rock_Id || + if (block == Tile::stone_Id || block == Tile::dirt_Id || block == Tile::grass_Id) { if (yy < 10) { diff --git a/Minecraft.World/WorldGen/Features/CaveFeature.cpp b/Minecraft.World/WorldGen/Features/CaveFeature.cpp index 4e17f8b95..ecdce794c 100644 --- a/Minecraft.World/WorldGen/Features/CaveFeature.cpp +++ b/Minecraft.World/WorldGen/Features/CaveFeature.cpp @@ -77,7 +77,7 @@ bool CaveFeature::place(Level* level, Random* random, int x, int y, int z) { AUTO_VAR(itEnd, toRemove.end()); for (AUTO_VAR(it, toRemove.begin()); it != itEnd; it++) { 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(); @@ -85,7 +85,8 @@ bool CaveFeature::place(Level* level, Random* random, int x, int y, int z) { TilePos* p = *it; // toRemove[i]; if (level->getTile(p->x, p->y - 1, p->z) == Tile::dirt_Id && 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; } diff --git a/Minecraft.World/WorldGen/Features/ClayFeature.cpp b/Minecraft.World/WorldGen/Features/ClayFeature.cpp index 29db4ed4e..06f643b30 100644 --- a/Minecraft.World/WorldGen/Features/ClayFeature.cpp +++ b/Minecraft.World/WorldGen/Features/ClayFeature.cpp @@ -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++) { int t = level->getTile(xx, yy, zz); 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); } } } diff --git a/Minecraft.World/WorldGen/Features/DeadBushFeature.cpp b/Minecraft.World/WorldGen/Features/DeadBushFeature.cpp index c3bf084ec..4fbf97f56 100644 --- a/Minecraft.World/WorldGen/Features/DeadBushFeature.cpp +++ b/Minecraft.World/WorldGen/Features/DeadBushFeature.cpp @@ -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); if (level->isEmptyTile(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); } } } diff --git a/Minecraft.World/WorldGen/Features/DesertWellFeature.cpp b/Minecraft.World/WorldGen/Features/DesertWellFeature.cpp index 0633d8017..16821ae19 100644 --- a/Minecraft.World/WorldGen/Features/DesertWellFeature.cpp +++ b/Minecraft.World/WorldGen/Features/DesertWellFeature.cpp @@ -26,57 +26,62 @@ bool DesertWellFeature::place(Level* level, Random* random, int x, int y, for (int oy = -1; oy <= 0; oy++) { for (int ox = -2; ox <= 2; ox++) { for (int oz = -2; oz <= 2; oz++) { - level->setTileNoUpdate(x + ox, y + oy, z + oz, - Tile::sandStone_Id); + level->setTileAndData(x + ox, y + oy, z + oz, + Tile::sandStone_Id, 0, + Tile::UPDATE_CLIENTS); } } } // place water cross - level->setTileNoUpdate(x, y, z, Tile::water_Id); - level->setTileNoUpdate(x - 1, y, z, Tile::water_Id); - level->setTileNoUpdate(x + 1, y, z, Tile::water_Id); - level->setTileNoUpdate(x, y, z - 1, Tile::water_Id); - level->setTileNoUpdate(x, y, z + 1, Tile::water_Id); + level->setTileAndData(x, y, z, Tile::water_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x - 1, y, z, Tile::water_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + 1, y, z, Tile::water_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z - 1, Tile::water_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y, z + 1, Tile::water_Id, 0, Tile::UPDATE_CLIENTS); // place "fence" for (int ox = -2; ox <= 2; ox++) { for (int oz = -2; oz <= 2; oz++) { if (ox == -2 || ox == 2 || oz == -2 || oz == 2) { - level->setTileNoUpdate(x + ox, y + 1, z + oz, - Tile::sandStone_Id); + level->setTileAndData(x + ox, y + 1, z + oz, Tile::sandStone_Id, + 0, Tile::UPDATE_CLIENTS); } } } - level->setTileAndDataNoUpdate(x + 2, y + 1, z, Tile::stoneSlabHalf_Id, - StoneSlabTile::SAND_SLAB); - level->setTileAndDataNoUpdate(x - 2, y + 1, z, Tile::stoneSlabHalf_Id, - StoneSlabTile::SAND_SLAB); - level->setTileAndDataNoUpdate(x, y + 1, z + 2, Tile::stoneSlabHalf_Id, - StoneSlabTile::SAND_SLAB); - level->setTileAndDataNoUpdate(x, y + 1, z - 2, Tile::stoneSlabHalf_Id, - StoneSlabTile::SAND_SLAB); + level->setTileAndData(x + 2, y + 1, z, Tile::stoneSlabHalf_Id, + StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); + level->setTileAndData(x - 2, y + 1, z, Tile::stoneSlabHalf_Id, + StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y + 1, z + 2, Tile::stoneSlabHalf_Id, + StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y + 1, z - 2, Tile::stoneSlabHalf_Id, + StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); // place roof for (int ox = -1; ox <= 1; ox++) { for (int oz = -1; oz <= 1; oz++) { if (ox == 0 && oz == 0) { - level->setTileNoUpdate(x + ox, y + 4, z + oz, - Tile::sandStone_Id); + level->setTileAndData(x + ox, y + 4, z + oz, Tile::sandStone_Id, + 0, Tile::UPDATE_CLIENTS); } else { - level->setTileAndDataNoUpdate(x + ox, y + 4, z + oz, - Tile::stoneSlabHalf_Id, - StoneSlabTile::SAND_SLAB); + level->setTileAndData( + x + ox, y + 4, z + oz, Tile::stoneSlabHalf_Id, + StoneSlabTile::SAND_SLAB, Tile::UPDATE_CLIENTS); } } } // place pillars for (int oy = 1; oy <= 3; oy++) { - level->setTileNoUpdate(x - 1, y + oy, z - 1, Tile::sandStone_Id); - level->setTileNoUpdate(x - 1, y + oy, z + 1, Tile::sandStone_Id); - level->setTileNoUpdate(x + 1, y + oy, z - 1, Tile::sandStone_Id); - level->setTileNoUpdate(x + 1, y + oy, z + 1, Tile::sandStone_Id); + 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); + 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; diff --git a/Minecraft.World/WorldGen/Features/DungeonFeature.cpp b/Minecraft.World/WorldGen/Features/DungeonFeature.cpp index 472db063c..e7f88585d 100644 --- a/Minecraft.World/WorldGen/Features/DungeonFeature.cpp +++ b/Minecraft.World/WorldGen/Features/DungeonFeature.cpp @@ -132,7 +132,7 @@ void DungeonFeature::addTunnel(int xOffs, int zOffs, byteArray blocks, if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) { int block = blocks[p]; 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) { if (yy < 10) { blocks[p] = (uint8_t)Tile::lava_Id; diff --git a/Minecraft.World/WorldGen/Features/EndPodiumFeature.cpp b/Minecraft.World/WorldGen/Features/EndPodiumFeature.cpp index 6215aa4a8..3c9a4bf34 100644 --- a/Minecraft.World/WorldGen/Features/EndPodiumFeature.cpp +++ b/Minecraft.World/WorldGen/Features/EndPodiumFeature.cpp @@ -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 zz = z - (r - 1); zz <= z + (r - 1); 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); } } } diff --git a/Minecraft.World/WorldGen/Features/Feature.cpp b/Minecraft.World/WorldGen/Features/Feature.cpp index 93f535ecf..a6edfbe66 100644 --- a/Minecraft.World/WorldGen/Features/Feature.cpp +++ b/Minecraft.World/WorldGen/Features/Feature.cpp @@ -1,11 +1,15 @@ #include "../../Platform/stdafx.h" #include "../../Headers/net.minecraft.world.level.h" +#include "../../Headers/net.minecraft.world.level.tile.h" #include "Feature.h" Feature::Feature() { this->doUpdate = false; } 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) { 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, int data) { if (doUpdate) { - level->setTileAndData(x, y, z, tile, data); + level->setTileAndData(x, y, z, tile, data, Tile::UPDATE_ALL); } else { - level->setTileAndDataNoUpdate(x, y, z, tile, data); + level->setTileAndData(x, y, z, tile, data, Tile::UPDATE_CLIENTS); } -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Features/Feature.h b/Minecraft.World/WorldGen/Features/Feature.h index f554df50a..94e3b4c31 100644 --- a/Minecraft.World/WorldGen/Features/Feature.h +++ b/Minecraft.World/WorldGen/Features/Feature.h @@ -17,6 +17,8 @@ public: return false; } virtual void init(double V1, double V2, double V3) {}; + virtual void applyFeature(Level* level, Random* random, int xChunk, + int zChunk); protected: virtual void placeBlock(Level* level, int x, int y, int z, int tile); diff --git a/Minecraft.World/WorldGen/Features/FlowerFeature.cpp b/Minecraft.World/WorldGen/Features/FlowerFeature.cpp index 1cbe6d457..1ba254ecc 100644 --- a/Minecraft.World/WorldGen/Features/FlowerFeature.cpp +++ b/Minecraft.World/WorldGen/Features/FlowerFeature.cpp @@ -1,5 +1,6 @@ #include "../../Platform/stdafx.h" #include "../../Headers/net.minecraft.world.level.h" +#include "../../Headers/net.minecraft.world.level.dimension.h" #include "FlowerFeature.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 y2 = y + random->nextInt(4) - random->nextInt(4); 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)) { - level->setTileNoUpdate(x2, y2, z2, tile); + level->setTileAndData(x2, y2, z2, tile, 0, + Tile::UPDATE_CLIENTS); } } } diff --git a/Minecraft.World/WorldGen/Features/GroundBushFeature.cpp b/Minecraft.World/WorldGen/Features/GroundBushFeature.cpp index f9668e191..912fdb414 100644 --- a/Minecraft.World/WorldGen/Features/GroundBushFeature.cpp +++ b/Minecraft.World/WorldGen/Features/GroundBushFeature.cpp @@ -4,8 +4,8 @@ #include "GroundBushFeature.h" GroundBushFeature::GroundBushFeature(int trunkType, int leafType) { - this->trunkTileType = trunkType; - this->leafTileType = leafType; + trunkTileType = trunkType; + leafTileType = leafType; } bool GroundBushFeature::place(Level* level, Random* random, int x, int y, diff --git a/Minecraft.World/WorldGen/Features/HellFireFeature.cpp b/Minecraft.World/WorldGen/Features/HellFireFeature.cpp index 11c9e1e17..4af1e30e8 100644 --- a/Minecraft.World/WorldGen/Features/HellFireFeature.cpp +++ b/Minecraft.World/WorldGen/Features/HellFireFeature.cpp @@ -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 z2 = z + random->nextInt(8) - random->nextInt(8); if (!level->isEmptyTile(x2, y2, z2)) continue; - if (level->getTile(x2, y2 - 1, z2) != Tile::hellRock_Id) continue; - level->setTile(x2, y2, z2, Tile::fire_Id); + if (level->getTile(x2, y2 - 1, z2) != Tile::netherRack_Id) continue; + level->setTileAndData(x2, y2, z2, Tile::fire_Id, 0, + Tile::UPDATE_CLIENTS); } return true; diff --git a/Minecraft.World/WorldGen/Features/HellPortalFeature.cpp b/Minecraft.World/WorldGen/Features/HellPortalFeature.cpp index 8b9b69747..9238b4f8d 100644 --- a/Minecraft.World/WorldGen/Features/HellPortalFeature.cpp +++ b/Minecraft.World/WorldGen/Features/HellPortalFeature.cpp @@ -6,8 +6,8 @@ bool HellPortalFeature::place(Level* level, Random* random, int x, int y, int z) { if (!level->isEmptyTile(x, y, z)) return false; - if (level->getTile(x, y + 1, z) != Tile::hellRock_Id) return false; - level->setTile(x, y, z, Tile::lightGem_Id); + if (level->getTile(x, y + 1, z) != Tile::netherRack_Id) return false; + level->setTileAndData(x, y, z, Tile::glowstone_Id, 0, Tile::UPDATE_CLIENTS); for (int i = 0; i < 1500; i++) { 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 == 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; diff --git a/Minecraft.World/WorldGen/Features/HellSpringFeature.cpp b/Minecraft.World/WorldGen/Features/HellSpringFeature.cpp index 87c452bae..2bae1dd4c 100644 --- a/Minecraft.World/WorldGen/Features/HellSpringFeature.cpp +++ b/Minecraft.World/WorldGen/Features/HellSpringFeature.cpp @@ -3,23 +3,26 @@ #include "HellSpringFeature.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, int z) { - if (level->getTile(x, y + 1, z) != Tile::hellRock_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 - 1, z) != Tile::netherRack_Id) return false; 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; int rockCount = 0; - if (level->getTile(x - 1, y, z) == Tile::hellRock_Id) rockCount++; - if (level->getTile(x + 1, y, z) == Tile::hellRock_Id) rockCount++; - if (level->getTile(x, y, z - 1) == Tile::hellRock_Id) rockCount++; - if (level->getTile(x, y, z + 1) == Tile::hellRock_Id) rockCount++; - if (level->getTile(x, y - 1, z) == Tile::hellRock_Id) rockCount++; + if (level->getTile(x - 1, y, z) == Tile::netherRack_Id) rockCount++; + if (level->getTile(x + 1, y, z) == Tile::netherRack_Id) rockCount++; + if (level->getTile(x, y, z - 1) == Tile::netherRack_Id) rockCount++; + if (level->getTile(x, y, z + 1) == Tile::netherRack_Id) rockCount++; + if (level->getTile(x, y - 1, z) == Tile::netherRack_Id) rockCount++; int holeCount = 0; 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 - 1, z)) holeCount++; - if (rockCount == 4 && holeCount == 1) { - level->setTile(x, y, z, tile); + if ((!insideRock && rockCount == 4 && holeCount == 1) || rockCount == 5) { + level->setTileAndData(x, y, z, tile, 0, Tile::UPDATE_CLIENTS); level->setInstaTick(true); Tile::tiles[tile]->tick(level, x, y, z, random); level->setInstaTick(false); diff --git a/Minecraft.World/WorldGen/Features/HellSpringFeature.h b/Minecraft.World/WorldGen/Features/HellSpringFeature.h index d97d5bf22..c0d9d9218 100644 --- a/Minecraft.World/WorldGen/Features/HellSpringFeature.h +++ b/Minecraft.World/WorldGen/Features/HellSpringFeature.h @@ -4,9 +4,10 @@ class HellSpringFeature : public Feature { private: int tile; + bool insideRock; public: - HellSpringFeature(int tile); + HellSpringFeature(int tile, bool insideRock); virtual bool place(Level* level, Random* random, int x, int y, int z); }; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Features/HouseFeature.cpp b/Minecraft.World/WorldGen/Features/HouseFeature.cpp index eba1785f5..48e71c7fd 100644 --- a/Minecraft.World/WorldGen/Features/HouseFeature.cpp +++ b/Minecraft.World/WorldGen/Features/HouseFeature.cpp @@ -6,9 +6,8 @@ #include "../../Headers/net.minecraft.world.item.h" bool HouseFeature::place(Level* level, Random* random, int x, int y, int z) { - while (y > 0 && !level->getMaterial(x, y - 1, z)->blocksMotion()) { - y--; - } + while (y > 0 && !level->getMaterial(x, y - 1, z)->blocksMotion()) y--; + int w = random->nextInt(7) + 7; int h = 4 + random->nextInt(3) / 2; 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 (t != 0) return false; } else { - if (t == Tile::stoneBrick_Id || t == Tile::mossStone_Id) + if (t == Tile::cobblestone_Id || t == Tile::mossyCobblestone_Id) 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 || zz == zz0 || xx == xx1 || zz == zz1) { if (yy <= y0 + random->nextInt(3)) - material = Tile::mossStone_Id; + material = Tile::mossyCobblestone_Id; else - material = Tile::stoneBrick_Id; + material = Tile::cobblestone_Id; } } if (material >= 0) { - level->setTileNoUpdate(xx, yy, zz, material); + level->setTileAndData(xx, yy, zz, material, 0, + Tile::UPDATE_CLIENTS); } } 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 == 2) zz = z0; if (doorSide == 3) zz = z0 + d - 1; - level->setTileNoUpdate(xx, y0, zz, 0); - level->setTileNoUpdate(xx, y0 + 1, zz, 0); + level->setTileAndData(xx, y0, zz, 0, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(xx, y0 + 1, zz, 0, 0, Tile::UPDATE_CLIENTS); int 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)) count++; 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 (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); return true; -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Features/HugeMushroomFeature.cpp b/Minecraft.World/WorldGen/Features/HugeMushroomFeature.cpp index e6944a6ad..fc7321ff4 100644 --- a/Minecraft.World/WorldGen/Features/HugeMushroomFeature.cpp +++ b/Minecraft.World/WorldGen/Features/HugeMushroomFeature.cpp @@ -46,10 +46,6 @@ bool HugeMushroomFeature::place(Level* level, Random* random, int x, int y, 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; if (type == 1) { 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 (!Tile::solid[level->getTile(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++) { int t = level->getTile(x, y + hh, z); 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; } diff --git a/Minecraft.World/WorldGen/Features/LakeFeature.cpp b/Minecraft.World/WorldGen/Features/LakeFeature.cpp index 513047a5d..28dd11011 100644 --- a/Minecraft.World/WorldGen/Features/LakeFeature.cpp +++ b/Minecraft.World/WorldGen/Features/LakeFeature.cpp @@ -9,9 +9,7 @@ LakeFeature::LakeFeature(int tile) { this->tile = tile; } bool LakeFeature::place(Level* level, Random* random, int x, int y, int z) { x -= 8; z -= 8; - while (y > 5 && level->isEmptyTile(x, y, z)) { - y--; - } + while (y > 5 && level->isEmptyTile(x, y, z)) y--; if (y <= 4) { 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++) { bool check = !grid[((xx) * 16 + (zz)) * 8 + (yy)] && - ((xx < 15 && grid[((xx + 1) * 16 + (zz)) * 8 + (yy)]) || - (xx > 0 && 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)]) || (zz < 15 && 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)]) || @@ -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 yy = 0; yy < 8; yy++) { if (grid[((xx) * 16 + (zz)) * 8 + (yy)]) { - level->setTileNoUpdate(x + xx, y + yy, z + zz, - yy >= 4 ? 0 : tile); + level->setTileAndData(x + xx, y + yy, z + zz, + 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) { Biome* b = level->getBiome(x + xx, z + zz); if (b->topMaterial == Tile::mycel_Id) - level->setTileNoUpdate(x + xx, y + yy - 1, z + zz, - Tile::mycel_Id); + level->setTileAndData(x + xx, y + yy - 1, z + zz, + Tile::mycel_Id, 0, + Tile::UPDATE_CLIENTS); else - level->setTileNoUpdate(x + xx, y + yy - 1, z + zz, - Tile::grass_Id); + level->setTileAndData(x + xx, y + yy - 1, z + zz, + 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) && level->getMaterial(x + xx, y + yy, z + zz) ->isSolid()) { - level->setTileNoUpdate(x + xx, y + yy, z + zz, - Tile::rock_Id); + level->setTileAndData(x + xx, y + yy, z + zz, + 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++) { int yy = 4; if (level->shouldFreezeIgnoreNeighbors(x + xx, y + yy, z + zz)) - level->setTileNoUpdate(x + xx, y + yy, z + zz, - Tile::ice_Id); + level->setTileAndData(x + xx, y + yy, z + zz, Tile::ice_Id, + 0, Tile::UPDATE_CLIENTS); } } } return true; -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Features/LargeCaveFeature.cpp b/Minecraft.World/WorldGen/Features/LargeCaveFeature.cpp index c64f16943..8fccdf9d5 100644 --- a/Minecraft.World/WorldGen/Features/LargeCaveFeature.cpp +++ b/Minecraft.World/WorldGen/Features/LargeCaveFeature.cpp @@ -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) { int block = blocks[p]; if (block == Tile::grass_Id) hasGrass = true; - if (block == Tile::rock_Id || + if (block == Tile::stone_Id || block == Tile::dirt_Id || block == Tile::grass_Id) { if (yy < 10) { diff --git a/Minecraft.World/WorldGen/Features/LargeFeature.cpp b/Minecraft.World/WorldGen/Features/LargeFeature.cpp index 8233f12fa..2a129e31d 100644 --- a/Minecraft.World/WorldGen/Features/LargeFeature.cpp +++ b/Minecraft.World/WorldGen/Features/LargeFeature.cpp @@ -28,4 +28,4 @@ void LargeFeature::apply(ChunkSource* ChunkSource, Level* level, int xOffs, addFeature(level, x, z, xOffs, zOffs, blocks); } } -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Features/LargeFeature.h b/Minecraft.World/WorldGen/Features/LargeFeature.h index 075c28f88..f48b26b24 100644 --- a/Minecraft.World/WorldGen/Features/LargeFeature.h +++ b/Minecraft.World/WorldGen/Features/LargeFeature.h @@ -22,4 +22,4 @@ public: protected: virtual void addFeature(Level* level, int x, int z, int xOffs, int zOffs, byteArray blocks) {} -}; +}; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Features/LargeHellCaveFeature.cpp b/Minecraft.World/WorldGen/Features/LargeHellCaveFeature.cpp index 8778e6ca2..4078d9729 100644 --- a/Minecraft.World/WorldGen/Features/LargeHellCaveFeature.cpp +++ b/Minecraft.World/WorldGen/Features/LargeHellCaveFeature.cpp @@ -3,14 +3,16 @@ #include "LargeHellCaveFeature.h" #include "../../Headers/net.minecraft.world.level.tile.h" -void LargeHellCaveFeature::addRoom(int xOffs, int zOffs, byteArray blocks, - double xRoom, double yRoom, double zRoom) { - addTunnel(xOffs, zOffs, blocks, xRoom, yRoom, zRoom, +void LargeHellCaveFeature::addRoom(int64_t seed, int xOffs, int zOffs, + byteArray blocks, double xRoom, double yRoom, + double zRoom) { + addTunnel(seed, xOffs, zOffs, blocks, xRoom, yRoom, zRoom, 1 + random->nextFloat() * 6, 0, 0, -1, -1, 0.5); } -void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks, - double xCave, double yCave, double zCave, +void LargeHellCaveFeature::addTunnel(int64_t seed, int xOffs, int zOffs, + byteArray blocks, double xCave, + double yCave, double zCave, float thickness, float yRot, float xRot, int step, int dist, double yScale) { double xMid = xOffs * 16 + 8; @@ -18,11 +20,11 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks, float yRota = 0; float xRota = 0; - Random* random = new Random(this->random->nextLong()); + Random random(seed); if (dist <= 0) { int max = radius * 16 - 16; - dist = max - random->nextInt(max / 4); + dist = max - random.nextInt(max / 4); } bool singleStep = false; @@ -31,8 +33,8 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks, singleStep = true; } - int splitPoint = random->nextInt(dist / 2) + dist / 4; - bool steep = random->nextInt(6) == 0; + int splitPoint = random.nextInt(dist / 2) + dist / 4; + bool steep = random.nextInt(6) == 0; for (; step < dist; step++) { 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; yRota *= 0.75f; - xRota += (random->nextFloat() - random->nextFloat()) * - random->nextFloat() * 2; - yRota += (random->nextFloat() - random->nextFloat()) * - random->nextFloat() * 4; + xRota += + (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2; + yRota += + (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4; if (!singleStep && step == splitPoint && thickness > 1) { - addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, - random->nextFloat() * 0.5f + 0.5f, yRot - PI / 2, + addTunnel(random.nextLong(), xOffs, zOffs, blocks, xCave, yCave, + zCave, random.nextFloat() * 0.5f + 0.5f, yRot - PI / 2, xRot / 3, step, dist, 1.0); - addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, - random->nextFloat() * 0.5f + 0.5f, yRot + PI / 2, + addTunnel(random.nextLong(), xOffs, zOffs, blocks, xCave, yCave, + zCave, random.nextFloat() * 0.5f + 0.5f, yRot + PI / 2, xRot / 3, step, dist, 1.0); - delete random; return; } - if (!singleStep && random->nextInt(4) == 0) continue; + if (!singleStep && random.nextInt(4) == 0) continue; { double xd = xCave - xMid; @@ -77,7 +78,6 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks, double remaining = dist - step; double rr = (thickness + 2) + 16; if (xd * xd + zd * zd - (remaining * remaining) > rr * rr) { - delete random; return; } } @@ -132,7 +132,7 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks, double yd = (yy + 0.5 - yCave) / yRad; if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) { int block = blocks[p]; - if (block == Tile::hellRock_Id || + if (block == Tile::netherRack_Id || block == Tile::dirt_Id || block == Tile::grass_Id) { blocks[p] = (uint8_t)0; } @@ -143,7 +143,6 @@ void LargeHellCaveFeature::addTunnel(int xOffs, int zOffs, byteArray blocks, } if (singleStep) break; } - delete random; } 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; 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); } @@ -167,8 +167,8 @@ void LargeHellCaveFeature::addFeature(Level* level, int x, int z, int xOffs, float xRot = ((random->nextFloat() - 0.5f) * 2) / 8; float thickness = random->nextFloat() * 2 + random->nextFloat(); - addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, thickness * 2, - yRot, xRot, 0, 0, 0.5); + addTunnel(random->nextLong(), xOffs, zOffs, blocks, xCave, yCave, + zCave, thickness * 2, yRot, xRot, 0, 0, 0.5); } } } diff --git a/Minecraft.World/WorldGen/Features/LargeHellCaveFeature.h b/Minecraft.World/WorldGen/Features/LargeHellCaveFeature.h index b8b59f62c..1a55d6653 100644 --- a/Minecraft.World/WorldGen/Features/LargeHellCaveFeature.h +++ b/Minecraft.World/WorldGen/Features/LargeHellCaveFeature.h @@ -4,11 +4,11 @@ class LargeHellCaveFeature : public LargeFeature { protected: - void addRoom(int xOffs, int zOffs, byteArray blocks, double xRoom, - double yRoom, double zRoom); - void addTunnel(int xOffs, int zOffs, byteArray blocks, double xCave, - double yCave, double zCave, float thickness, float yRot, - float xRot, int step, int dist, double yScale); + void addRoom(int64_t seed, int xOffs, int zOffs, byteArray blocks, + double xRoom, double yRoom, double zRoom); + void addTunnel(int64_t seed, int xOffs, int zOffs, byteArray blocks, + double xCave, double yCave, double zCave, float thickness, + float yRot, float xRot, int step, int dist, double yScale); virtual void addFeature(Level* level, int x, int z, int xOffs, int zOffs, byteArray blocks); }; diff --git a/Minecraft.World/WorldGen/Features/LightGemFeature.cpp b/Minecraft.World/WorldGen/Features/LightGemFeature.cpp index bf8b31871..d8ee13904 100644 --- a/Minecraft.World/WorldGen/Features/LightGemFeature.cpp +++ b/Minecraft.World/WorldGen/Features/LightGemFeature.cpp @@ -5,8 +5,8 @@ bool LightGemFeature::place(Level* level, Random* random, int x, int y, int z) { if (!level->isEmptyTile(x, y, z)) return false; - if (level->getTile(x, y + 1, z) != Tile::hellRock_Id) return false; - level->setTile(x, y, z, Tile::lightGem_Id); + if (level->getTile(x, y + 1, z) != Tile::netherRack_Id) return false; + level->setTileAndData(x, y, z, Tile::glowstone_Id, 0, Tile::UPDATE_CLIENTS); for (int i = 0; i < 1500; i++) { 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 == 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; diff --git a/Minecraft.World/WorldGen/Features/MegaTreeFeature.cpp b/Minecraft.World/WorldGen/Features/MegaTreeFeature.cpp index f4270db73..71ef87df6 100644 --- a/Minecraft.World/WorldGen/Features/MegaTreeFeature.cpp +++ b/Minecraft.World/WorldGen/Features/MegaTreeFeature.cpp @@ -58,10 +58,13 @@ bool MegaTreeFeature::place(Level* level, Random* random, int x, int y, int z) { y >= Level::maxBuildHeight - treeHeight - 1) return false; - level->setTileNoUpdate(x, y - 1, z, Tile::dirt_Id); - level->setTileNoUpdate(x + 1, y - 1, z, Tile::dirt_Id); - level->setTileNoUpdate(x, y - 1, z + 1, Tile::dirt_Id); - level->setTileNoUpdate(x + 1, y - 1, z + 1, Tile::dirt_Id); + level->setTileAndData(x, y - 1, z, Tile::dirt_Id, 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(x + 1, y - 1, z, Tile::dirt_Id, 0, + Tile::UPDATE_CLIENTS); + 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, y + treeHeight); @@ -191,7 +194,7 @@ void MegaTreeFeature::placeLeaves(Level* level, int x, int z, int topPosition, PIXBeginNamedEvent(0, "Getting tile"); int t = level->getTile(xx, yy, zz); PIXEndNamedEvent(); - if (!Tile::solid[t]) { + if (t == 0 || t == Tile::leaves_Id) { PIXBeginNamedEvent(0, "Placing block"); placeBlock(level, xx, yy, zz, Tile::leaves_Id, leafType); PIXEndNamedEvent(); diff --git a/Minecraft.World/WorldGen/Features/MineShaftFeature.cpp b/Minecraft.World/WorldGen/Features/MineShaftFeature.cpp index 1dfd838ff..f8287e4e2 100644 --- a/Minecraft.World/WorldGen/Features/MineShaftFeature.cpp +++ b/Minecraft.World/WorldGen/Features/MineShaftFeature.cpp @@ -1,6 +1,24 @@ #include "../../Platform/stdafx.h" #include "../../Headers/net.minecraft.world.level.levelgen.structure.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 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 forcePlacement = false; @@ -10,7 +28,7 @@ bool MineShaftFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) { 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))); } diff --git a/Minecraft.World/WorldGen/Features/MineShaftFeature.h b/Minecraft.World/WorldGen/Features/MineShaftFeature.h index b42fed562..1172f1b5e 100644 --- a/Minecraft.World/WorldGen/Features/MineShaftFeature.h +++ b/Minecraft.World/WorldGen/Features/MineShaftFeature.h @@ -3,6 +3,19 @@ #include "StructureFeature.h" class MineShaftFeature : public StructureFeature { +public: + static const std::wstring OPTION_CHANCE; + +private: + double chance; + +public: + MineShaftFeature(); + + std::wstring getFeatureName(); + + MineShaftFeature(std::unordered_map options); + protected: virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false); virtual StructureStart* createStructureStart(int x, int z); diff --git a/Minecraft.World/WorldGen/Features/MonsterRoomFeature.cpp b/Minecraft.World/WorldGen/Features/MonsterRoomFeature.cpp index 8369c3093..6bb4fc08b 100644 --- a/Minecraft.World/WorldGen/Features/MonsterRoomFeature.cpp +++ b/Minecraft.World/WorldGen/Features/MonsterRoomFeature.cpp @@ -4,8 +4,28 @@ #include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.entity.h" #include "../../Headers/net.minecraft.world.item.h" +#include "../../Util/WeighedTreasure.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, int z) { 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) { if (yy >= 0 && !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()) { 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 { - level->setTile(xx, yy, zz, Tile::stoneBrick_Id); + level->setTileAndData(xx, yy, zz, + Tile::cobblestone_Id, 0, + Tile::UPDATE_CLIENTS); } } } 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; - 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 chest = std::dynamic_pointer_cast( level->getTileEntity(xc, yc, zc)); if (chest != NULL) { - for (int j = 0; j < 8; j++) { - std::shared_ptr item = randomItem(random); - if (item != NULL) - chest->setItem( - random->nextInt(chest->getContainerSize()), item); - } + WeighedTreasure::addChestItems(random, treasure, chest, 8); } break; } } - level->setTile(x, y, z, Tile::mobSpawner_Id); + level->setTileAndData(x, y, z, Tile::mobSpawner_Id, 0, + Tile::UPDATE_CLIENTS); std::shared_ptr entity = std::dynamic_pointer_cast( level->getTileEntity(x, y, z)); if (entity != NULL) { - entity->setEntityId(randomEntityId(random)); + entity->getSpawner()->setEntityId(randomEntityId(random)); } return true; } -std::shared_ptr MonsterRoomFeature::randomItem(Random* random) { - int type = random->nextInt(12); - if (type == 0) - return std::shared_ptr(new ItemInstance(Item::saddle)); - if (type == 1) - return std::shared_ptr( - new ItemInstance(Item::ironIngot, random->nextInt(4) + 1)); - if (type == 2) - return std::shared_ptr(new ItemInstance(Item::bread)); - if (type == 3) - return std::shared_ptr( - new ItemInstance(Item::wheat, random->nextInt(4) + 1)); - if (type == 4) - return std::shared_ptr( - new ItemInstance(Item::sulphur, random->nextInt(4) + 1)); - if (type == 5) - return std::shared_ptr( - new ItemInstance(Item::string, random->nextInt(4) + 1)); - if (type == 6) - return std::shared_ptr( - new ItemInstance(Item::bucket_empty)); - if (type == 7 && random->nextInt(100) == 0) - return std::shared_ptr( - new ItemInstance(Item::apple_gold)); - if (type == 8 && random->nextInt(2) == 0) - return std::shared_ptr( - new ItemInstance(Item::redStone, random->nextInt(4) + 1)); - if (type == 9 && random->nextInt(10) == 0) - return std::shared_ptr(new ItemInstance( - Item::items[Item::record_01->id + random->nextInt(2)])); - if (type == 10) - return std::shared_ptr( - new ItemInstance(Item::dye_powder, 1, DyePowderItem::BROWN)); - if (type == 11) return Item::enchantedBook->createForRandomLoot(random); - - return std::shared_ptr(); -} - std::wstring MonsterRoomFeature::randomEntityId(Random* random) { int id = random->nextInt(4); if (id == 0) return std::wstring(L"Skeleton"); diff --git a/Minecraft.World/WorldGen/Features/MonsterRoomFeature.h b/Minecraft.World/WorldGen/Features/MonsterRoomFeature.h index 16fd3c232..36488997c 100644 --- a/Minecraft.World/WorldGen/Features/MonsterRoomFeature.h +++ b/Minecraft.World/WorldGen/Features/MonsterRoomFeature.h @@ -2,14 +2,16 @@ #include "Feature.h" #include "../../Blocks/Material.h" +class WeighedTreasure; + class MonsterRoomFeature : public Feature { private: - // int tile; + static const int TREASURE_ITEMS_COUNT = 15; + static WeighedTreasure* monsterRoomTreasure[TREASURE_ITEMS_COUNT]; public: virtual bool place(Level* level, Random* random, int x, int y, int z); private: - std::shared_ptr randomItem(Random* random); std::wstring randomEntityId(Random* random); }; diff --git a/Minecraft.World/WorldGen/Features/NetherBridgeFeature.cpp b/Minecraft.World/WorldGen/Features/NetherBridgeFeature.cpp index 23f66ccec..468a96df9 100644 --- a/Minecraft.World/WorldGen/Features/NetherBridgeFeature.cpp +++ b/Minecraft.World/WorldGen/Features/NetherBridgeFeature.cpp @@ -10,7 +10,9 @@ NetherBridgeFeature::NetherBridgeFeature() : StructureFeature() { bridgeEnemies.push_back(new Biome::MobSpawnerData(eTYPE_BLAZE, 10, 2, 3)); 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( new Biome::MobSpawnerData(eTYPE_LAVASLIME, 3, 4, 4)); isSpotSelected = false; @@ -21,6 +23,8 @@ NetherBridgeFeature::~NetherBridgeFeature() { if (netherFortressPos != NULL) delete netherFortressPos; } +std::wstring NetherBridgeFeature::getFeatureName() { return L"Fortress"; } + std::vector* NetherBridgeFeature::getBridgeEnemies() { return &bridgeEnemies; } @@ -89,11 +93,15 @@ StructureStart* NetherBridgeFeature::createStructureStart(int x, int z) { void NetherBridgeFeature::clearCachedBuildings() { cachedStructures.clear(); } +NetherBridgeFeature::NetherBridgeStart::NetherBridgeStart() { + // for reflection +} + NetherBridgeFeature::NetherBridgeStart::NetherBridgeStart(Level* level, Random* random, int chunkX, int chunkZ) - : StructureStart() { + : StructureStart(chunkX, chunkZ) { NetherBridgePieces::StartPiece* start = new NetherBridgePieces::StartPiece( random, (chunkX << 4) + 2, (chunkZ << 4) + 2, level); pieces.push_back(start); diff --git a/Minecraft.World/WorldGen/Features/NetherBridgeFeature.h b/Minecraft.World/WorldGen/Features/NetherBridgeFeature.h index 62f43c480..560c74b19 100644 --- a/Minecraft.World/WorldGen/Features/NetherBridgeFeature.h +++ b/Minecraft.World/WorldGen/Features/NetherBridgeFeature.h @@ -13,6 +13,7 @@ private: public: NetherBridgeFeature(); ~NetherBridgeFeature(); + std::wstring getFeatureName(); std::vector* getBridgeEnemies(); protected: @@ -22,9 +23,15 @@ protected: public: void clearCachedBuildings(); -private: class NetherBridgeStart : public StructureStart { public: + static StructureStart* Create() { return new NetherBridgeStart(); } + virtual EStructureStart GetType() { + return eStructureStart_NetherBridgeStart; + } + + public: + NetherBridgeStart(); NetherBridgeStart(Level* level, Random* random, int chunkX, int chunkZ); }; }; diff --git a/Minecraft.World/WorldGen/Features/OreFeature.cpp b/Minecraft.World/WorldGen/Features/OreFeature.cpp index 2d5a08f64..6f3b776d9 100644 --- a/Minecraft.World/WorldGen/Features/OreFeature.cpp +++ b/Minecraft.World/WorldGen/Features/OreFeature.cpp @@ -10,7 +10,7 @@ void OreFeature::_init(int tile, int count, int targetTile) { } 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) { @@ -52,6 +52,11 @@ bool OreFeature::place(Level* level, Random* random, int x, int y, int z) { maxX, maxY, maxZ); } + bool doEarlyRejectTest = false; + if (y0 > level->getSeaLevel()) { + doEarlyRejectTest = true; + } + for (int d = 0; d <= count; d++) { double xx = x0 + (x1 - x0) * 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 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); - int yt0 = Mth::floor(yy - hr / 2); - int zt0 = Mth::floor(zz - r / 2); + double halfR = r / 2; + double halfHR = halfR; // hr/2; - int xt1 = Mth::floor(xx + r / 2); - int yt1 = Mth::floor(yy + hr / 2); - int zt1 = Mth::floor(zz + r / 2); + int xt0 = Mth::floor(xx - halfR); + int yt0 = Mth::floor(yy - halfHR); + 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 // 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 // above the height stored in the heightmap - bool earlyReject = true; - if (level->getHeightmap(xt0, zt0) >= yt0) - earlyReject = false; - else if (level->getHeightmap(xt1, zt0) >= yt0) - earlyReject = false; - else if (level->getHeightmap(xt0, zt1) >= yt0) - earlyReject = false; - else if (level->getHeightmap(xt1, zt1) >= yt0) - earlyReject = false; + if (doEarlyRejectTest) { + bool earlyReject = true; + if (level->getHeightmap(xt0, zt0) >= yt0) + earlyReject = false; + else if (level->getHeightmap(xt1, zt0) >= yt0) + earlyReject = false; + else if (level->getHeightmap(xt0, zt1) >= yt0) + 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 xd = ((x2 + 0.5) - xx) / (r / 2); - if (xd * xd < 1) { - for (int y2 = yt0; y2 <= yt1; y2++) { - double yd = ((y2 + 0.5) - yy) / (hr / 2); - if (xd * xd + yd * yd < 1) { - for (int z2 = zt0; z2 <= zt1; z2++) { - double zd = ((z2 + 0.5) - zz) / (r / 2); - if (xd * xd + yd * yd + zd * zd < 1) { + double xdxd, ydyd; + + double xd0 = ((xt0 + 0.5) - xx); + double yd0 = ((yt0 + 0.5) - yy); + double zd0 = ((zt0 + 0.5) - zz); + + double halfRSq = halfR * halfR; + + 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) { - level->setTileNoUpdateNoLightCheck( - x2, y2, z2, tile); // 4J changed from - // setTileNoUpdate + level->setTileAndData( + x2, y2, z2, tile, 0, + Tile::UPDATE_INVISIBLE_NO_LIGHT); } } } diff --git a/Minecraft.World/WorldGen/Features/PumpkinFeature.cpp b/Minecraft.World/WorldGen/Features/PumpkinFeature.cpp index 7278bfe4b..905f2ded8 100644 --- a/Minecraft.World/WorldGen/Features/PumpkinFeature.cpp +++ b/Minecraft.World/WorldGen/Features/PumpkinFeature.cpp @@ -11,8 +11,8 @@ bool PumpkinFeature::place(Level* level, Random* random, int x, int y, int z) { if (level->isEmptyTile(x2, y2, z2) && level->getTile(x2, y2 - 1, z2) == Tile::grass_Id) { if (Tile::pumpkin->mayPlace(level, x2, y2, z2)) { - level->setTileAndDataNoUpdate(x2, y2, z2, Tile::pumpkin_Id, - random->nextInt(4)); + level->setTileAndData(x2, y2, z2, Tile::pumpkin_Id, + random->nextInt(4), Tile::UPDATE_CLIENTS); } } } diff --git a/Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.cpp b/Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.cpp index d89001d88..afc1599fd 100644 --- a/Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.cpp +++ b/Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.cpp @@ -1,37 +1,58 @@ #include "../../Platform/stdafx.h" #include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.biome.h" +#include "../../Headers/net.minecraft.world.level.levelgen.structure.h" #include "../Structures/ScatteredFeaturePieces.h" #include "RandomScatteredLargeFeature.h" +const std::wstring RandomScatteredLargeFeature::OPTION_SPACING = L"distance"; std::vector RandomScatteredLargeFeature::allowedBiomes; void RandomScatteredLargeFeature::staticCtor() { allowedBiomes.push_back(Biome::desert); allowedBiomes.push_back(Biome::desertHills); 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 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 bIsSuperflat) { - int featureSpacing = 32; - int minFeatureSeparation = 8; - int xx = x; int zz = z; - if (x < 0) x -= featureSpacing - 1; - if (z < 0) z -= featureSpacing - 1; + if (x < 0) x -= spacing - 1; + if (z < 0) z -= spacing - 1; - int xCenterFeatureChunk = x / featureSpacing; - int zCenterFeatureChunk = z / featureSpacing; + int xCenterFeatureChunk = x / spacing; + int zCenterFeatureChunk = z / spacing; Random* r = level->getRandomFor(xCenterFeatureChunk, zCenterFeatureChunk, 14357617); - xCenterFeatureChunk *= featureSpacing; - zCenterFeatureChunk *= featureSpacing; - xCenterFeatureChunk += r->nextInt(featureSpacing - minFeatureSeparation); - zCenterFeatureChunk += r->nextInt(featureSpacing - minFeatureSeparation); + xCenterFeatureChunk *= spacing; + zCenterFeatureChunk *= spacing; + xCenterFeatureChunk += r->nextInt(spacing - minSeparation); + zCenterFeatureChunk += r->nextInt(spacing - minSeparation); x = xx; z = zz; @@ -44,12 +65,14 @@ bool RandomScatteredLargeFeature::isFeatureChunk(int x, int z, if (forcePlacement || (x == xCenterFeatureChunk && z == zCenterFeatureChunk)) { - bool biomeOk = level->getBiomeSource()->containsOnly( - x * 16 + 8, z * 16 + 8, 0, allowedBiomes); - if (biomeOk) { - // System.out.println("feature at " + (x * 16) + " " - // + (z * 16)); - return true; + Biome* biome = + level->getBiomeSource()->getBiome(x * 16 + 8, z * 16 + 8); + for (AUTO_VAR(it, allowedBiomes.begin()); it != allowedBiomes.end(); + ++it) { + Biome* a = *it; + if (biome == a) { + return true; + } } } @@ -58,27 +81,51 @@ bool RandomScatteredLargeFeature::isFeatureChunk(int x, int z, StructureStart* RandomScatteredLargeFeature::createStructureStart(int x, int z) { - // System.out.println("feature at " + (x * 16) + " " + (z * 16)); return new ScatteredFeatureStart(level, random, x, z); } +RandomScatteredLargeFeature::ScatteredFeatureStart::ScatteredFeatureStart() { + // for reflection +} + RandomScatteredLargeFeature::ScatteredFeatureStart::ScatteredFeatureStart( - Level* level, Random* random, int chunkX, int chunkZ) { - if (level->getBiome(chunkX * 16 + 8, chunkZ * 16 + 8) == Biome::jungle) { + Level* level, Random* random, int chunkX, int chunkZ) + : StructureStart(chunkX, chunkZ) { + Biome* biome = level->getBiome(chunkX * 16 + 8, chunkZ * 16 + 8); + if (biome == Biome::jungle || biome == Biome::jungleHills) { ScatteredFeaturePieces::JunglePyramidPiece* startRoom = new ScatteredFeaturePieces::JunglePyramidPiece(random, chunkX * 16, chunkZ * 16); pieces.push_back(startRoom); - // System.out.println("jungle feature at " + (chunkX * - // 16) + " " + (chunkZ * 16)); + } else if (biome == Biome::swampland) { + ScatteredFeaturePieces::SwamplandHut* startRoom = + new ScatteredFeaturePieces::SwamplandHut(random, chunkX * 16, + chunkZ * 16); + pieces.push_back(startRoom); } else { ScatteredFeaturePieces::DesertPyramidPiece* startRoom = new ScatteredFeaturePieces::DesertPyramidPiece(random, chunkX * 16, chunkZ * 16); pieces.push_back(startRoom); - // System.out.println("desert feature at " + (chunkX * - // 16) + " " + (chunkZ * 16)); } calculateBoundingBox(); +} + +bool RandomScatteredLargeFeature::isSwamphut(int cellX, int cellY, int cellZ) { + StructureStart* structureAt = getStructureAt(cellX, cellY, cellZ); + if (structureAt == NULL || + !(dynamic_cast(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(first) != NULL; +} + +std::vector* +RandomScatteredLargeFeature::getSwamphutEnemies() { + return &swamphutEnemies; } \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.h b/Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.h index 122f13c7e..565d9763d 100644 --- a/Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.h +++ b/Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.h @@ -5,17 +5,44 @@ class RandomScatteredLargeFeature : public StructureFeature { public: + static const std::wstring OPTION_SPACING; + static void staticCtor(); static std::vector allowedBiomes; + +private: + std::vector swamphutEnemies; + int spacing; + int minSeparation; + + void _init(); + +public: RandomScatteredLargeFeature(); + RandomScatteredLargeFeature( + std::unordered_map options); + + std::wstring getFeatureName(); protected: virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false); StructureStart* createStructureStart(int x, int z); +public: class ScatteredFeatureStart : public StructureStart { public: + static StructureStart* Create() { return new ScatteredFeatureStart(); } + virtual EStructureStart GetType() { + return eStructureStart_ScatteredFeatureStart; + } + + public: + ScatteredFeatureStart(); ScatteredFeatureStart(Level* level, Random* random, int chunkX, int chunkZ); }; + +public: + bool isSwamphut(int cellX, int cellY, int cellZ); + std::vector* getSwamphutEnemies(); }; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Features/ReedsFeature.cpp b/Minecraft.World/WorldGen/Features/ReedsFeature.cpp index 9f0e472f6..12f73394c 100644 --- a/Minecraft.World/WorldGen/Features/ReedsFeature.cpp +++ b/Minecraft.World/WorldGen/Features/ReedsFeature.cpp @@ -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); for (int yy = 0; yy < h; yy++) { 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); } } } diff --git a/Minecraft.World/WorldGen/Features/SandFeature.cpp b/Minecraft.World/WorldGen/Features/SandFeature.cpp index 8cd0e46aa..fe9f015eb 100644 --- a/Minecraft.World/WorldGen/Features/SandFeature.cpp +++ b/Minecraft.World/WorldGen/Features/SandFeature.cpp @@ -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++) { int t = level->getTile(xx, yy, zz); 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); } } } diff --git a/Minecraft.World/WorldGen/Features/SpikeFeature.cpp b/Minecraft.World/WorldGen/Features/SpikeFeature.cpp index 2a4a93e84..69925079f 100644 --- a/Minecraft.World/WorldGen/Features/SpikeFeature.cpp +++ b/Minecraft.World/WorldGen/Features/SpikeFeature.cpp @@ -34,7 +34,8 @@ bool SpikeFeature::place(Level* level, Random* random, int x, int y, int z) { int xd = xx - x; int zd = zz - z; 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 @@ -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, 0); 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; } @@ -70,11 +72,13 @@ bool SpikeFeature::placeWithIndex(Level* level, Random* random, int x, int y, level->getTile(xx, y - iTileBelow, zz) != tile) { if (level->isEmptyTile(xx, y - iTileBelow, zz)) { // empty tile - level->setTileNoUpdate(xx, y - iTileBelow, zz, - Tile::obsidian_Id); + level->setTileAndData(xx, y - iTileBelow, zz, + Tile::obsidian_Id, 0, + Tile::UPDATE_CLIENTS); } else { - level->setTile(xx, y - iTileBelow, zz, - Tile::obsidian_Id); + level->setTileAndData(xx, y - iTileBelow, zz, + Tile::obsidian_Id, 0, + Tile::UPDATE_CLIENTS); } iTileBelow++; } diff --git a/Minecraft.World/WorldGen/Features/SpringFeature.cpp b/Minecraft.World/WorldGen/Features/SpringFeature.cpp index ca3a08890..69b4f46af 100644 --- a/Minecraft.World/WorldGen/Features/SpringFeature.cpp +++ b/Minecraft.World/WorldGen/Features/SpringFeature.cpp @@ -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::rock_Id) return false; + if (level->getTile(x, y + 1, z) != Tile::stone_Id) return false; + if (level->getTile(x, y - 1, z) != Tile::stone_Id) return false; 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; int rockCount = 0; - if (level->getTile(x - 1, y, z) == Tile::rock_Id) rockCount++; - if (level->getTile(x + 1, y, z) == Tile::rock_Id) rockCount++; - if (level->getTile(x, y, z - 1) == Tile::rock_Id) rockCount++; - if (level->getTile(x, y, z + 1) == Tile::rock_Id) rockCount++; + if (level->getTile(x - 1, y, z) == Tile::stone_Id) rockCount++; + if (level->getTile(x + 1, y, z) == Tile::stone_Id) rockCount++; + if (level->getTile(x, y, z - 1) == Tile::stone_Id) rockCount++; + if (level->getTile(x, y, z + 1) == Tile::stone_Id) rockCount++; int holeCount = 0; 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 (rockCount == 3 && holeCount == 1) { - level->setTile(x, y, z, tile); + level->setTileAndData(x, y, z, tile, 0, Tile::UPDATE_CLIENTS); level->setInstaTick(true); Tile::tiles[tile]->tick(level, x, y, z, random); level->setInstaTick(false); diff --git a/Minecraft.World/WorldGen/Features/StrongholdFeature.cpp b/Minecraft.World/WorldGen/Features/StrongholdFeature.cpp index b9e49b387..60cbf19b5 100644 --- a/Minecraft.World/WorldGen/Features/StrongholdFeature.cpp +++ b/Minecraft.World/WorldGen/Features/StrongholdFeature.cpp @@ -4,9 +4,14 @@ #include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.biome.h" #include "../../Headers/net.minecraft.world.level.dimension.h" +#include "../../Util/Mth.h" #include "../../IO/Files/FileHeader.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 StrongholdFeature::allowedBiomes; void StrongholdFeature::staticCtor() { @@ -25,7 +30,10 @@ void StrongholdFeature::staticCtor() { allowedBiomes.push_back(Biome::jungleHills); }; -StrongholdFeature::StrongholdFeature() : StructureFeature() { +void StrongholdFeature::_init() { + distance = 32; + spread = 3; + // 4J added initialisers for (int i = 0; i < strongholdPos_length; i++) { strongholdPos[i] = NULL; @@ -33,18 +41,43 @@ StrongholdFeature::StrongholdFeature() : StructureFeature() { isSpotSelected = false; } +StrongholdFeature::StrongholdFeature() : StructureFeature() { _init(); } + +StrongholdFeature::StrongholdFeature( + std::unordered_map 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() { for (int i = 0; i < strongholdPos_length; i++) { delete strongholdPos[i]; } } +std::wstring StrongholdFeature::getFeatureName() { + return LargeFeature::STRONGHOLD; +} + bool StrongholdFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) { if (!isSpotSelected) { Random random; random.setSeed(level->getSeed()); double angle = random.nextDouble() * PI * 2.0; + int circle = 1; // 4J Stu - Changed so that we keep trying more until we have found // 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)); } else { // Original Java - dist = (1.25 + random.nextDouble()) * 32.0; + dist = (1.25 * circle + random.nextDouble()) * + (distance * circle); } #else // 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 hasFoundValidPos = true; delete position; - } else { - app.DebugPrintf( - "Placed stronghold in INVALID biome at (%d, %d)\n", - selectedX, selectedZ); } 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 #ifdef _LARGE_WORLDS - angle = random.nextDouble() * PI * 2.0; + angle = random.nextDouble() * PI * 2.0 * circle / (double)spread; #endif } while (!hasFoundValidPos && findAttempts < MAX_STRONGHOLD_ATTEMPTS); @@ -200,10 +230,14 @@ StructureStart* StrongholdFeature::createStructureStart(int x, int z) { // return new StrongholdStart(level, random, x, z); } +StrongholdFeature::StrongholdStart::StrongholdStart() { + // for reflection +} + StrongholdFeature::StrongholdStart::StrongholdStart(Level* level, Random* random, int chunkX, int chunkZ) - : StructureStart() { + : StructureStart(chunkX, chunkZ) { StrongholdPieces::resetPieces(); StrongholdPieces::StartPiece* startRoom = new StrongholdPieces::StartPiece( @@ -222,4 +256,4 @@ StrongholdFeature::StrongholdStart::StrongholdStart(Level* level, calculateBoundingBox(); moveBelowSeaLevel(level, random, 10); -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Features/StrongholdFeature.h b/Minecraft.World/WorldGen/Features/StrongholdFeature.h index de889c93e..7c2114572 100644 --- a/Minecraft.World/WorldGen/Features/StrongholdFeature.h +++ b/Minecraft.World/WorldGen/Features/StrongholdFeature.h @@ -16,6 +16,11 @@ class Biome; #endif class StrongholdFeature : public StructureFeature { +public: + static const std::wstring OPTION_DISTANCE; + static const std::wstring OPTION_COUNT; + static const std::wstring OPTION_SPREAD; + public: static void staticCtor(); @@ -27,19 +32,33 @@ private: 1; // Java game has 3, but xbox game only has 1 because of the world // size; // 4J added ChunkPos* strongholdPos[strongholdPos_length]; + double distance; + int spread; + + void _init(); public: StrongholdFeature(); + StrongholdFeature(std::unordered_map options); ~StrongholdFeature(); + std::wstring getFeatureName(); + protected: virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false); std::vector* getGuesstimatedFeaturePositions(); virtual StructureStart* createStructureStart(int x, int z); -private: +public: class StrongholdStart : public StructureStart { public: + static StructureStart* Create() { return new StrongholdStart(); } + virtual EStructureStart GetType() { + return eStructureStart_StrongholdStart; + } + + public: + StrongholdStart(); StrongholdStart(Level* level, Random* random, int chunkX, int chunkZ); }; }; diff --git a/Minecraft.World/WorldGen/Features/StructureFeature.cpp b/Minecraft.World/WorldGen/Features/StructureFeature.cpp index 358a7249f..5599c2705 100644 --- a/Minecraft.World/WorldGen/Features/StructureFeature.cpp +++ b/Minecraft.World/WorldGen/Features/StructureFeature.cpp @@ -7,6 +7,12 @@ #include "../../Headers/net.minecraft.world.level.h" #include "../../Level/LevelData.h" +StructureFeature::StructureFeature() { +#ifdef ENABLE_STRUCTURE_SAVING + savedData = nullptr; +#endif +} + StructureFeature::~StructureFeature() { for (AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); 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 // structures + restoreSavedData(level); + if (cachedStructures.find(ChunkPos::hashCode(x, z)) != cachedStructures.end()) { return; @@ -35,11 +43,14 @@ void StructureFeature::addFeature(Level* level, int x, int z, int xOffs, level->getLevelData()->getGenerator() == LevelType::lvl_flat)) { StructureStart* start = createStructureStart(x, z); cachedStructures[ChunkPos::hashCode(x, z)] = start; + saveFeature(x, z, start); } } bool StructureFeature::postProcess(Level* level, Random* random, int chunkX, int chunkZ) { + restoreSavedData(level); + // 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 // 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); delete bb; 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) { + restoreSavedData(level); + for (AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); it++) { StructureStart* structureStart = it->second; @@ -90,10 +108,13 @@ bool StructureFeature::isIntersection(int cellX, int cellZ) { return false; } -/////////////////////////////////////////// -// 4J-PB - Below functions added from 1.2.3 -/////////////////////////////////////////// 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 (AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); ++it) { @@ -104,10 +125,10 @@ bool StructureFeature::isInsideFeature(int cellX, int cellY, int cellZ) { cellX, cellZ)) { /* Iterator it = - structureStart.getPieces().iterator(); while (it.hasNext()) { - StructurePiece next = it.next(); - if (next.getBoundingBox().isInside(cellX, cellY, cellZ)) { - return true; + structureStart.getPieces().iterator(); while (it.hasNext()) + { StructurePiece next = it.next(); if + (next.getBoundingBox().isInside(cellX, cellY, cellZ)) { return + true; } */ std::list* pieces = @@ -118,12 +139,27 @@ bool StructureFeature::isInsideFeature(int cellX, int cellY, int cellZ) { StructurePiece* piece = *it2; if (piece->getBoundingBox()->isInside(cellX, cellY, 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; } @@ -133,6 +169,8 @@ TilePos* StructureFeature::getNearestGeneratedFeature(Level* level, int cellX, // even if the player hasn't generated new chunks yet this->level = level; + restoreSavedData(level); + random->setSeed(level->getSeed()); int64_t xScale = random->nextLong(); int64_t zScale = random->nextLong(); @@ -159,7 +197,7 @@ TilePos* StructureFeature::getNearestGeneratedFeature(Level* level, int cellX, int dx = locatorPosition->x - cellX; int dy = locatorPosition->y - cellY; int dz = locatorPosition->z - cellZ; - double dist = dx + dx * dy * dy + dz * dz; + double dist = dx * dx + dy * dy + dz * dz; if (dist < minDistance) { minDistance = dist; @@ -180,7 +218,7 @@ TilePos* StructureFeature::getNearestGeneratedFeature(Level* level, int cellX, int dx = (*it).x - cellX; int dy = (*it).y - cellY; int dz = (*it).z - cellZ; - double dist = dx + dx * dy * dy + dz * dz; + double dist = dx * dx + dy * dy + dz * dz; if (dist < minDistance) { minDistance = dist; @@ -199,3 +237,50 @@ TilePos* StructureFeature::getNearestGeneratedFeature(Level* level, int cellX, std::vector* StructureFeature::getGuesstimatedFeaturePositions() { return NULL; } + +void StructureFeature::restoreSavedData(Level* level) { +#ifdef ENABLE_STRUCTURE_SAVING + if (savedData == NULL) { + savedData = std::dynamic_pointer_cast( + level->getSavedData(typeid(StructureFeatureSavedData), + getFeatureName())); + + if (savedData == NULL) { + savedData = std::shared_ptr( + new StructureFeatureSavedData(getFeatureName())); + level->setSavedData(getFeatureName(), savedData); + } else { + CompoundTag* fullTag = savedData->getFullTag(); + + std::vector* 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 +} diff --git a/Minecraft.World/WorldGen/Features/StructureFeature.h b/Minecraft.World/WorldGen/Features/StructureFeature.h index a32b74733..c00efbd20 100644 --- a/Minecraft.World/WorldGen/Features/StructureFeature.h +++ b/Minecraft.World/WorldGen/Features/StructureFeature.h @@ -1,7 +1,11 @@ #pragma once #include "LargeFeature.h" +#include "../StructureFeatureSavedData.h" + class StructureStart; +// #define ENABLE_STRUCTURE_SAVING + class StructureFeature : public LargeFeature { public: // 4J added - Maps to values in the game rules xml @@ -13,12 +17,20 @@ public: eFeature_Village, }; +#ifdef ENABLE_STRUCTURE_SAVING +private: + std::shared_ptr savedData; +#endif + protected: std::unordered_map cachedStructures; public: + StructureFeature(); ~StructureFeature(); + virtual std::wstring getFeatureName() = 0; + virtual void addFeature(Level* level, int x, int z, int xOffs, int zOffs, byteArray blocks); @@ -26,12 +38,22 @@ public: bool isIntersection(int cellX, 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, int cellZ); protected: std::vector* 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 * source. diff --git a/Minecraft.World/WorldGen/Features/TallGrassFeature.cpp b/Minecraft.World/WorldGen/Features/TallGrassFeature.cpp index 53888823a..1d848d5a5 100644 --- a/Minecraft.World/WorldGen/Features/TallGrassFeature.cpp +++ b/Minecraft.World/WorldGen/Features/TallGrassFeature.cpp @@ -21,7 +21,8 @@ bool TallGrassFeature::place(Level* level, Random* random, int x, int y, int z2 = z + random->nextInt(8) - random->nextInt(8); if (level->isEmptyTile(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); } } } diff --git a/Minecraft.World/WorldGen/Features/TreeFeature.cpp b/Minecraft.World/WorldGen/Features/TreeFeature.cpp index 4b5f02bac..e9c4bd399 100644 --- a/Minecraft.World/WorldGen/Features/TreeFeature.cpp +++ b/Minecraft.World/WorldGen/Features/TreeFeature.cpp @@ -83,7 +83,8 @@ bool TreeFeature::place(Level* level, Random* random, int x, int y, int z) { if (abs(xo) == offs && abs(zo) == offs && (random->nextInt(2) == 0 || yo == 0)) 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); } } diff --git a/Minecraft.World/WorldGen/Features/TreeFeature.h b/Minecraft.World/WorldGen/Features/TreeFeature.h index e3c3d8838..3d99e0a0b 100644 --- a/Minecraft.World/WorldGen/Features/TreeFeature.h +++ b/Minecraft.World/WorldGen/Features/TreeFeature.h @@ -4,9 +4,9 @@ class TreeFeature : public Feature { private: const int baseHeight; + const bool addJungleFeatures; const int trunkType; const int leafType; - const bool addJungleFeatures; public: TreeFeature(bool doUpdate); diff --git a/Minecraft.World/WorldGen/Features/VillageFeature.cpp b/Minecraft.World/WorldGen/Features/VillageFeature.cpp index 95d62a5f7..7987c0216 100644 --- a/Minecraft.World/WorldGen/Features/VillageFeature.cpp +++ b/Minecraft.World/WorldGen/Features/VillageFeature.cpp @@ -5,6 +5,9 @@ #include "../../Headers/net.minecraft.world.level.biome.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 VillageFeature::allowedBiomes; void VillageFeature::staticCtor() { @@ -12,27 +15,44 @@ void VillageFeature::staticCtor() { allowedBiomes.push_back(Biome::desert); } -VillageFeature::VillageFeature(int villageSizeModifier, int iXZSize) - : StructureFeature(), villageSizeModifier(villageSizeModifier) { +void VillageFeature::_init(int iXZSize) { + villageSizeModifier = 0; + townSpacing = 32; + minTownSeparation = 8; + m_iXZSize = iXZSize; } -bool VillageFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) { - int townSpacing; +VillageFeature::VillageFeature(int iXZSize) { _init(iXZSize); } +VillageFeature::VillageFeature( + std::unordered_map 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 - if (level->dimension->getXZSize() > 128) { - townSpacing = 32; - } else + && level->dimension->getXZSize() < 128 #endif - if (bIsSuperflat) { - townSpacing = 32; - } else { + ) { townSpacing = 16; // 4J change 32; } - int minTownSeparation = 8; - int xx = x; int zz = z; if (x < 0) x -= townSpacing - 1; @@ -77,6 +97,12 @@ StructureStart* VillageFeature::createStructureStart(int x, int z) { m_iXZSize); } +VillageFeature::VillageStart::VillageStart() { + valid = false; // 4J added initialiser + m_iXZSize = 0; + // for reflection +} + VillageFeature::VillageStart::VillageStart(Level* level, Random* random, int chunkX, int chunkZ, int villageSizeModifier, @@ -136,3 +162,14 @@ bool VillageFeature::VillageStart::isValid() { } 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"); +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Features/VillageFeature.h b/Minecraft.World/WorldGen/Features/VillageFeature.h index eede4c592..97b21a781 100644 --- a/Minecraft.World/WorldGen/Features/VillageFeature.h +++ b/Minecraft.World/WorldGen/Features/VillageFeature.h @@ -4,28 +4,48 @@ class Biome; class VillageFeature : public StructureFeature { +public: + static const std::wstring OPTION_SIZE_MODIFIER; + static const std::wstring OPTION_SPACING; + private: - const int villageSizeModifier; + int villageSizeModifier; + int townSpacing; + int minTownSeparation; + + void _init(int iXZSize); public: static void staticCtor(); static std::vector allowedBiomes; - VillageFeature(int villageSizeModifier, int iXZSize); + VillageFeature(int iXZSize); + VillageFeature(std::unordered_map options, + int iXZSize); + std::wstring getFeatureName(); protected: virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false); virtual StructureStart* createStructureStart(int x, int z); -private: +public: class VillageStart : public StructureStart { + public: + static StructureStart* Create() { return new VillageStart(); } + virtual EStructureStart GetType() { + return eStructureStart_VillageStart; + } + private: bool valid; int m_iXZSize; public: + VillageStart(); VillageStart(Level* level, Random* random, int chunkX, int chunkZ, int villageSizeModifier, int iXZSize); bool isValid(); + void addAdditonalSaveData(CompoundTag* tag); + void readAdditonalSaveData(CompoundTag* tag); }; int m_iXZSize; diff --git a/Minecraft.World/WorldGen/Features/VinesFeature.cpp b/Minecraft.World/WorldGen/Features/VinesFeature.cpp index e6243cd02..074c9e3f2 100644 --- a/Minecraft.World/WorldGen/Features/VinesFeature.cpp +++ b/Minecraft.World/WorldGen/Features/VinesFeature.cpp @@ -14,10 +14,11 @@ bool VinesFeature::place(Level* level, Random* random, int x, int y, int z) { if (level->isEmptyTile(x, y, z)) { for (int face = Facing::NORTH; face <= Facing::EAST; face++) { if (Tile::vine->mayPlace(level, x, y, z, face)) { - level->setTileAndDataNoUpdate( + level->setTileAndData( x, y, z, Tile::vine_Id, 1 << Direction::FACING_DIRECTION - [Facing::OPPOSITE_FACING[face]]); + [Facing::OPPOSITE_FACING[face]], + Tile::UPDATE_CLIENTS); break; } } diff --git a/Minecraft.World/WorldGen/Features/WaterlilyFeature.cpp b/Minecraft.World/WorldGen/Features/WaterlilyFeature.cpp index 2f2abb8b8..0271759ff 100644 --- a/Minecraft.World/WorldGen/Features/WaterlilyFeature.cpp +++ b/Minecraft.World/WorldGen/Features/WaterlilyFeature.cpp @@ -11,7 +11,8 @@ bool WaterlilyFeature::place(Level* level, Random* random, int x, int y, int z2 = z + random->nextInt(8) - random->nextInt(8); if (level->isEmptyTile(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); } } } diff --git a/Minecraft.World/WorldGen/Flat/FlatGeneratorInfo.cpp b/Minecraft.World/WorldGen/Flat/FlatGeneratorInfo.cpp new file mode 100644 index 000000000..c35669cf8 --- /dev/null +++ b/Minecraft.World/WorldGen/Flat/FlatGeneratorInfo.cpp @@ -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 >* +FlatGeneratorInfo::getStructures() { + return &structures; +} + +std::vector* 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> structure : structures.entrySet()) + { + if (structCount++ > 0) builder.append(","); + builder.append(structure.getKey().toLowerCase()); + + Map options = structure.getValue(); + if (!options.isEmpty()) + { + builder.append("("); + int optionCount = 0; + + for (Map.Entry 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 parts = stringSplit(input, L'x'); + + int height = 1; + int id; + int data = 0; + + if (parts.size() == 2) + { + height = _fromString(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(parts[0]); + if (parts.size() > 1) data = _from_String(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* FlatGeneratorInfo::getLayersFromString( + const std::wstring& input) { + if (input.empty()) return NULL; + + std::vector* result = new std::vector(); + std::vector 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 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 *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 structures = stringSplit(parts[index++], L','); + + for(AUTO_VAR(it, structures.begin()); it != structures.end(); ++it) + { + std::vector separated = stringSplit(parts[index++], L"\\("); + + std::unordered_map 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(); + } + + 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(); + + return result; +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Flat/FlatGeneratorInfo.h b/Minecraft.World/WorldGen/Flat/FlatGeneratorInfo.h new file mode 100644 index 000000000..be90b6ab4 --- /dev/null +++ b/Minecraft.World/WorldGen/Flat/FlatGeneratorInfo.h @@ -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 layers; + std::unordered_map > + structures; + int biome; + +public: + FlatGeneratorInfo(); + ~FlatGeneratorInfo(); + + int getBiome(); + void setBiome(int biome); + std::unordered_map >* + getStructures(); + std::vector* getLayers(); + void updateLayers(); + std::wstring toString(); + +private: + static FlatLayerInfo* getLayerFromString(const std::wstring& input, + int yOffset); + static std::vector* getLayersFromString( + const std::wstring& input); + +public: + static FlatGeneratorInfo* fromValue(const std::wstring& input); + static FlatGeneratorInfo* getDefault(); +}; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Flat/FlatLayerInfo.cpp b/Minecraft.World/WorldGen/Flat/FlatLayerInfo.cpp new file mode 100644 index 000000000..0cf9bda2e --- /dev/null +++ b/Minecraft.World/WorldGen/Flat/FlatLayerInfo.cpp @@ -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(id); + + if (height > 1) { + result = _toString(height) + L"x" + result; + } + if (data > 0) { + result += L":" + _toString(data); + } + + return result; +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Flat/FlatLayerInfo.h b/Minecraft.World/WorldGen/Flat/FlatLayerInfo.h new file mode 100644 index 000000000..01007cce5 --- /dev/null +++ b/Minecraft.World/WorldGen/Flat/FlatLayerInfo.h @@ -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(); +}; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp b/Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp index 3cf640b2d..8bbc2bf60 100644 --- a/Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp +++ b/Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp @@ -1,5 +1,4 @@ #include "../../Platform/stdafx.h" -#include "../../Util/PortableFileIO.h" #include "../../Headers/net.minecraft.world.level.biome.h" #include "../../Headers/net.minecraft.world.level.newbiome.layer.h" #include "../../Headers/net.minecraft.world.level.h" @@ -8,23 +7,44 @@ BiomeOverrideLayer::BiomeOverrideLayer(int seedMixup) : Layer(seedMixup) { m_biomeOverride = byteArray(width * height); -#ifdef _WINDOWS64 - const std::wstring path = L"GameRules\\biomemap.bin"; +#ifdef _UNICODE + 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 - 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 - const PortableFileIO::BinaryReadResult readResult = - PortableFileIO::ReadBinaryFile(path, m_biomeOverride.data, - m_biomeOverride.length); - if (readResult.status == PortableFileIO::BinaryReadStatus::not_found) { + HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); +#endif + if (file == INVALID_HANDLE_VALUE) { + DWORD error = GetLastError(); + // assert(false); app.DebugPrintf("Biome override not found, using plains as default\n"); + memset(m_biomeOverride.data, Biome::plains->id, m_biomeOverride.length); - } else if (readResult.status == - PortableFileIO::BinaryReadStatus::too_large) { - app.DebugPrintf("Biomemap binary is too large!!\n"); - __debugbreak(); - } else if (readResult.status != PortableFileIO::BinaryReadStatus::ok) { - app.FatalLoadError(); + } else { +#ifdef _DURANGO + __debugbreak(); // TODO + DWORD bytesRead, dwFileSize = 0; +#else + 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; -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Layers/Layer.cpp b/Minecraft.World/WorldGen/Layers/Layer.cpp index b23774313..8539f67f8 100644 --- a/Minecraft.World/WorldGen/Layers/Layer.cpp +++ b/Minecraft.World/WorldGen/Layers/Layer.cpp @@ -34,7 +34,7 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType) { islandLayer = std::shared_ptr(new ZoomLayer(2003, islandLayer)); islandLayer = std::shared_ptr(new AddIslandLayer(4, islandLayer)); // islandLayer = std::shared_ptr(new AddMushroomIslandLayer(5, - //islandLayer)); // 4J - old position of mushroom island layer + // islandLayer)); // 4J - old position of mushroom island layer int zoomLevel = 4; if (levelType == LevelType::lvl_largeBiomes) { @@ -105,7 +105,7 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType) { #ifdef _BIOME_OVERRIDE if (app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad()) & - (1L << eDebugSetting_EnableHeightWaterBiomeOverride)) { + (1L << eDebugSetting_EnableBiomeOverride)) { biomeLayer = std::shared_ptr(new BiomeOverrideLayer(1)); } diff --git a/Minecraft.World/WorldGen/Layers/Layer.h b/Minecraft.World/WorldGen/Layers/Layer.h index a4215e7ae..84b34fc9c 100644 --- a/Minecraft.World/WorldGen/Layers/Layer.h +++ b/Minecraft.World/WorldGen/Layers/Layer.h @@ -23,7 +23,6 @@ public: static LayerArray getDefaultLayers(int64_t seed, LevelType* levelType); Layer(int64_t seedMixup); - virtual ~Layer() {} virtual void init(int64_t seed); virtual void initRandom(int64_t x, int64_t y); @@ -33,4 +32,4 @@ protected: public: virtual intArray getArea(int xo, int yo, int w, int h) = 0; -}; +}; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Sources/FlatLevelSource.cpp b/Minecraft.World/WorldGen/Sources/FlatLevelSource.cpp index 837db83d6..9cbdc7f6d 100644 --- a/Minecraft.World/WorldGen/Sources/FlatLevelSource.cpp +++ b/Minecraft.World/WorldGen/Sources/FlatLevelSource.cpp @@ -21,7 +21,7 @@ FlatLevelSource::FlatLevelSource(Level* level, int64_t seed, seed); // 4J - added, so that we can have a separate random for doing // post-processing in parallel with creation - villageFeature = new VillageFeature(0, m_XZSize); + villageFeature = new VillageFeature(m_XZSize); } FlatLevelSource::~FlatLevelSource() { @@ -124,3 +124,7 @@ TilePos* FlatLevelSource::findNearestMapFeature(Level* level, int x, int y, int z) { return NULL; } + +void FlatLevelSource::recreateLogicStructuresForChunk(int chunkX, int chunkZ) { + // TODO +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Sources/FlatLevelSource.h b/Minecraft.World/WorldGen/Sources/FlatLevelSource.h index c37755ac8..8918767ff 100644 --- a/Minecraft.World/WorldGen/Sources/FlatLevelSource.h +++ b/Minecraft.World/WorldGen/Sources/FlatLevelSource.h @@ -43,4 +43,5 @@ public: virtual TilePos* findNearestMapFeature(Level* level, const std::wstring& featureName, int x, int y, int z); + virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ); }; diff --git a/Minecraft.World/WorldGen/Sources/HellFlatLevelSource.cpp b/Minecraft.World/WorldGen/Sources/HellFlatLevelSource.cpp index ad81657ec..e4b16fd1b 100644 --- a/Minecraft.World/WorldGen/Sources/HellFlatLevelSource.cpp +++ b/Minecraft.World/WorldGen/Sources/HellFlatLevelSource.cpp @@ -29,7 +29,7 @@ void HellFlatLevelSource::prepareHeights(int xOffs, int zOffs, for (int yc = 0; yc < height; yc++) { int block = 0; if ((yc <= 6) || (yc >= 121)) { - block = Tile::hellRock_Id; + block = Tile::netherRack_Id; } 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) { return NULL; } + +void HellFlatLevelSource::recreateLogicStructuresForChunk(int chunkX, + int chunkZ) {} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Sources/HellFlatLevelSource.h b/Minecraft.World/WorldGen/Sources/HellFlatLevelSource.h index b89d116d0..1e19ca85c 100644 --- a/Minecraft.World/WorldGen/Sources/HellFlatLevelSource.h +++ b/Minecraft.World/WorldGen/Sources/HellFlatLevelSource.h @@ -50,4 +50,5 @@ public: virtual TilePos* findNearestMapFeature(Level* level, const std::wstring& featureName, int x, int y, int z); + virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ); }; diff --git a/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp b/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp index 195a99d66..9a84d8277 100644 --- a/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp +++ b/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp @@ -115,7 +115,7 @@ void HellRandomLevelSource::prepareHeights(int xOffs, int zOffs, tileId = Tile::calmLava_Id; } if (val > 0) { - tileId = Tile::hellRock_Id; + tileId = Tile::netherRack_Id; } blocks[offs] = (uint8_t)tileId; @@ -167,8 +167,8 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, int run = -1; - uint8_t top = (uint8_t)Tile::hellRock_Id; - uint8_t material = (uint8_t)Tile::hellRock_Id; + uint8_t top = (uint8_t)Tile::netherRack_Id; + uint8_t material = (uint8_t)Tile::netherRack_Id; for (int y = Level::genDepthMinusOne; y >= 0; y--) { int offs = (z * 16 + x) * Level::genDepth + y; @@ -214,18 +214,18 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, if (old == 0) { run = -1; - } else if (old == Tile::hellRock_Id) { + } else if (old == Tile::netherRack_Id) { if (run == -1) { if (runDepth <= 0) { top = 0; - material = (uint8_t)Tile::hellRock_Id; + material = (uint8_t)Tile::netherRack_Id; } else if (y >= waterHeight - 4 && y <= waterHeight + 1) { - top = (uint8_t)Tile::hellRock_Id; - material = (uint8_t)Tile::hellRock_Id; + top = (uint8_t)Tile::netherRack_Id; + material = (uint8_t)Tile::netherRack_Id; if (gravel) top = (uint8_t)Tile::gravel_Id; if (gravel) - material = (uint8_t)Tile::hellRock_Id; + material = (uint8_t)Tile::netherRack_Id; if (sand) { // 4J Stu - Make some nether wart spawn // outside of the nether fortresses @@ -251,10 +251,10 @@ void HellRandomLevelSource::buildSurfaces(int xOffs, int zOffs, offs = (z * 16 + x) * Level::genDepth + y; } 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) @@ -451,10 +451,7 @@ void HellRandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) { pprandom->setSeed(level->getSeed()); int64_t xScale = pprandom->nextLong() / 2 * 2 + 1; int64_t zScale = pprandom->nextLong() / 2 * 2 + 1; - // 4jcraft added casts to a higher int and unsigned - pprandom->setSeed((((uint64_t)xt * (uint64_t)xScale) + - ((uint64_t)zt * (uint64_t)zScale)) ^ - level->getSeed()); + pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed()); 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 y = pprandom->nextInt(Level::genDepth - 8) + 4; 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; @@ -493,17 +490,17 @@ void HellRandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) { int x = xo + pprandom->nextInt(16) + 8; int y = pprandom->nextInt(Level::genDepth); 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) { int x = xo + pprandom->nextInt(16) + 8; int y = pprandom->nextInt(Level::genDepth); 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++) { int x = xo + pprandom->nextInt(16); 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); } + 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; app.processSchematics(parent->getChunk(xt, zt)); @@ -532,9 +537,14 @@ std::wstring HellRandomLevelSource::gatherStats() { std::vector* HellRandomLevelSource::getMobsAt( MobCategory* mobCategory, int x, int y, int z) { // check if the coordinates is within a netherbridge - if (mobCategory == MobCategory::monster && - netherBridgeFeature->isInsideFeature(x, y, z)) { - return netherBridgeFeature->getBridgeEnemies(); + if (mobCategory == MobCategory::monster) { + if (netherBridgeFeature->isInsideFeature(x, y, z)) { + 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); @@ -548,3 +558,8 @@ TilePos* HellRandomLevelSource::findNearestMapFeature( Level* level, const std::wstring& featureName, int x, int y, int z) { return NULL; } + +void HellRandomLevelSource::recreateLogicStructuresForChunk(int chunkX, + int chunkZ) { + netherBridgeFeature->apply(this, level, chunkX, chunkZ, NULL); +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.h b/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.h index 6c952be12..a055ba0a0 100644 --- a/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.h +++ b/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.h @@ -72,4 +72,5 @@ public: virtual TilePos* findNearestMapFeature(Level* level, const std::wstring& featureName, int x, int y, int z); + virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ); }; diff --git a/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp b/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp index b82d67a27..47690fd44 100644 --- a/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp +++ b/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp @@ -101,7 +101,7 @@ void TheEndLevelRandomLevelSource::prepareHeights(int xOffs, int zOffs, for (int z = 0; z < CHUNK_WIDTH; z++) { int tileId = 0; if (val > 0) { - tileId = Tile::whiteStone_Id; + tileId = Tile::endStone_Id; } else { } @@ -132,8 +132,8 @@ void TheEndLevelRandomLevelSource::buildSurfaces(int xOffs, int zOffs, int runDepth = 1; int run = -1; - uint8_t top = (uint8_t)Tile::whiteStone_Id; - uint8_t material = (uint8_t)Tile::whiteStone_Id; + uint8_t top = (uint8_t)Tile::endStone_Id; + uint8_t material = (uint8_t)Tile::endStone_Id; for (int y = Level::genDepthMinusOne; y >= 0; y--) { int offs = (z * 16 + x) * Level::genDepth + y; @@ -142,11 +142,11 @@ void TheEndLevelRandomLevelSource::buildSurfaces(int xOffs, int zOffs, if (old == 0) { run = -1; - } else if (old == Tile::rock_Id) { + } else if (old == Tile::stone_Id) { if (run == -1) { if (runDepth <= 0) { top = 0; - material = (uint8_t)Tile::whiteStone_Id; + material = (uint8_t)Tile::endStone_Id; } run = runDepth; @@ -199,8 +199,8 @@ LevelChunk* TheEndLevelRandomLevelSource::getChunk(int xOffs, int zOffs) { levelChunk->recalcHeightmap(); // delete blocks.data; // Don't delete the blocks as the array data is - // actually owned by the chunk now 4jcraft changed to [] - delete[] biomes.data; + // actually owned by the chunk now + delete biomes.data; return levelChunk; } @@ -354,19 +354,21 @@ void TheEndLevelRandomLevelSource::calcWaterDepths(ChunkSource* parent, int xt, int od = level->getData(xp + x2, y, zp + z2); if (od < 7 && od < d) { - level->setData(xp + x2, y, zp + z2, - d); + level->setData( + xp + x2, y, zp + z2, d, + Tile::UPDATE_CLIENTS); } } } } } if (hadWater) { - level->setTileAndDataNoUpdate( - xp, y, zp, Tile::calmWater_Id, 7); + level->setTileAndData(xp, y, zp, Tile::calmWater_Id, + 7, Tile::UPDATE_CLIENTS); for (int y2 = 0; y2 < y; y2++) { - level->setTileAndDataNoUpdate( - xp, y2, zp, Tile::calmWater_Id, 8); + level->setTileAndData(xp, y2, zp, + Tile::calmWater_Id, 8, + Tile::UPDATE_CLIENTS); } } } @@ -391,9 +393,7 @@ void TheEndLevelRandomLevelSource::postProcess(ChunkSource* parent, int xt, pprandom->setSeed(level->getSeed()); int64_t xScale = pprandom->nextLong() / 2 * 2 + 1; int64_t zScale = pprandom->nextLong() / 2 * 2 + 1; - // 4jcraft added cast to higher int and unsigned - pprandom->setSeed((((uint64_t)xt * xScale) + ((uint64_t)zt * zScale)) ^ - level->getSeed()); + pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed()); Biome* biome = level->getBiome(xo + 16, zo + 16); biome->decorate( @@ -432,3 +432,7 @@ TilePos* TheEndLevelRandomLevelSource::findNearestMapFeature( Level* level, const std::wstring& featureName, int x, int y, int z) { return NULL; } + +void TheEndLevelRandomLevelSource::recreateLogicStructuresForChunk(int chunkX, + int chunkZ) { +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.h b/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.h index f57a606a7..617b30a68 100644 --- a/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.h +++ b/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.h @@ -65,4 +65,5 @@ public: virtual TilePos* findNearestMapFeature(Level* level, const std::wstring& featureName, int x, int y, int z); + virtual void recreateLogicStructuresForChunk(int chunkX, int chunkZ); }; diff --git a/Minecraft.World/WorldGen/StructureFeatureIO.cpp b/Minecraft.World/WorldGen/StructureFeatureIO.cpp new file mode 100644 index 000000000..9e91abe94 --- /dev/null +++ b/Minecraft.World/WorldGen/StructureFeatureIO.cpp @@ -0,0 +1,101 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.level.levelgen.structure.h" +#include "StructureFeatureIO.h" + +std::unordered_map + StructureFeatureIO::startIdClassMap; +std::unordered_map + StructureFeatureIO::startClassIdMap; + +std::unordered_map + StructureFeatureIO::pieceIdClassMap; +std::unordered_map + 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; +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/StructureFeatureIO.h b/Minecraft.World/WorldGen/StructureFeatureIO.h new file mode 100644 index 000000000..f4aba2c98 --- /dev/null +++ b/Minecraft.World/WorldGen/StructureFeatureIO.h @@ -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 + startIdClassMap; + static std::unordered_map startClassIdMap; + + static std::unordered_map + pieceIdClassMap; + static std::unordered_map 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); +}; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/StructureFeatureSavedData.cpp b/Minecraft.World/WorldGen/StructureFeatureSavedData.cpp new file mode 100644 index 000000000..32d3b10fd --- /dev/null +++ b/Minecraft.World/WorldGen/StructureFeatureSavedData.cpp @@ -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(chunkX) + L"," + _toString(chunkZ) + L"]"; +} + +CompoundTag* StructureFeatureSavedData::getFullTag() { return pieceTags; } \ No newline at end of file diff --git a/Minecraft.World/WorldGen/StructureFeatureSavedData.h b/Minecraft.World/WorldGen/StructureFeatureSavedData.h new file mode 100644 index 000000000..6dec5e561 --- /dev/null +++ b/Minecraft.World/WorldGen/StructureFeatureSavedData.h @@ -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(); +}; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Structures/MineShaftPieces.cpp b/Minecraft.World/WorldGen/Structures/MineShaftPieces.cpp index 8ec0bf937..53b5b6cdd 100644 --- a/Minecraft.World/WorldGen/Structures/MineShaftPieces.cpp +++ b/Minecraft.World/WorldGen/Structures/MineShaftPieces.cpp @@ -1,4 +1,5 @@ #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.h" #include "../../Headers/net.minecraft.world.level.tile.h" @@ -12,7 +13,7 @@ WeighedTreasureArray MineShaftPieces::smallTreasureItems; ; void MineShaftPieces::staticCtor() { - smallTreasureItems = WeighedTreasureArray(11); + smallTreasureItems = WeighedTreasureArray(13); smallTreasureItems[0] = new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10); 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[9] = new WeighedTreasure(Item::seeds_melon_Id, 0, 2, 4, 10); - // 4J-PB - Adding from 1.2.3 smallTreasureItems[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( @@ -85,6 +100,10 @@ StructurePiece* MineShaftPieces::generateAndAddPiece( return newPiece; } +MineShaftPieces::MineShaftRoom::MineShaftRoom() { + // for reflection +} + MineShaftPieces::MineShaftRoom::MineShaftRoom(int genDepth, Random* random, int west, int north) : StructurePiece(genDepth) { @@ -221,6 +240,44 @@ bool MineShaftPieces::MineShaftRoom::postProcess(Level* level, Random* random, return true; } +void MineShaftPieces::MineShaftRoom::addAdditonalSaveData(CompoundTag* tag) { + ListTag* entrances = new ListTag(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* entrances = + (ListTag*)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, Random* random, 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 chest = + std::shared_ptr(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, Random* random, BoundingBox* chunkBB) { @@ -490,11 +574,13 @@ bool MineShaftPieces::MineShaftCorridor::postProcess(Level* level, newZ = getWorldZ(x0 + 1, newZ); if (chunkBB->isInside(x, y, newZ)) { 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 entity = std::dynamic_pointer_cast( 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]) { maybeGenerateBlock( 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; } +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, Random* random, BoundingBox* crossingBox, @@ -716,6 +819,10 @@ bool MineShaftPieces::MineShaftCrossing::postProcess(Level* level, return true; } +MineShaftPieces::MineShaftStairs::MineShaftStairs() { + // for reflection +} + MineShaftPieces::MineShaftStairs::MineShaftStairs(int genDepth, Random* random, BoundingBox* stairsBox, int direction) @@ -724,6 +831,11 @@ MineShaftPieces::MineShaftStairs::MineShaftStairs(int genDepth, Random* random, boundingBox = stairsBox; } +void MineShaftPieces::MineShaftStairs::addAdditonalSaveData(CompoundTag* tag) {} + +void MineShaftPieces::MineShaftStairs::readAdditonalSaveData(CompoundTag* tag) { +} + BoundingBox* MineShaftPieces::MineShaftStairs::findStairs( std::list* pieces, Random* random, int footX, int footY, int footZ, int direction) { diff --git a/Minecraft.World/WorldGen/Structures/MineShaftPieces.h b/Minecraft.World/WorldGen/Structures/MineShaftPieces.h index 75322f48d..696094b86 100644 --- a/Minecraft.World/WorldGen/Structures/MineShaftPieces.h +++ b/Minecraft.World/WorldGen/Structures/MineShaftPieces.h @@ -10,6 +10,10 @@ private: static const int MAX_DEPTH = 8; // 1.2.3 change +public: + static void loadStatic(); + +private: static StructurePiece* createRandomShaftPiece( std::list* pieces, Random* random, int footX, int footY, int footZ, int direction, int genDepth); @@ -24,10 +28,17 @@ private: */ public: class MineShaftRoom : public StructurePiece { + public: + static StructurePiece* Create() { return new MineShaftRoom(); } + virtual EStructurePiece GetType() { + return eStructurePiece_MineShaftRoom; + } + private: std::list childEntranceBoxes; public: + MineShaftRoom(); MineShaftRoom(int genDepth, Random* random, int west, int north); ~MineShaftRoom(); @@ -36,6 +47,10 @@ public: Random* random); virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB); + + protected: + void addAdditonalSaveData(CompoundTag* tag); + void readAdditonalSaveData(CompoundTag* tag); }; /** @@ -43,12 +58,25 @@ public: * */ class MineShaftCorridor : public StructurePiece { + public: + static StructurePiece* Create() { return new MineShaftCorridor(); } + virtual EStructurePiece GetType() { + return eStructurePiece_MineShaftCorridor; + } + private: bool hasRails; // was final bool spiderCorridor; // was final bool hasPlacedSpider; int numSections; + public: + MineShaftCorridor(); + + protected: + void addAdditonalSaveData(CompoundTag* tag); + void readAdditonalSaveData(CompoundTag* tag); + public: MineShaftCorridor(int genDepth, Random* random, BoundingBox* corridorBox, int direction); @@ -60,6 +88,13 @@ public: virtual void addChildren(StructurePiece* startPiece, std::list* pieces, 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, BoundingBox* chunkBB); }; @@ -69,9 +104,22 @@ public: * */ class MineShaftCrossing : public StructurePiece { + public: + static StructurePiece* Create() { return new MineShaftCrossing(); } + virtual EStructurePiece GetType() { + return eStructurePiece_MineShaftCrossing; + } + private: - const int direction; - const bool isTwoFloored; + int direction; + bool isTwoFloored; + + public: + MineShaftCrossing(); + + protected: + void addAdditonalSaveData(CompoundTag* tag); + void readAdditonalSaveData(CompoundTag* tag); public: MineShaftCrossing(int genDepth, Random* random, @@ -93,9 +141,21 @@ public: */ class MineShaftStairs : public StructurePiece { public: + static StructurePiece* Create() { return new MineShaftStairs(); } + virtual EStructurePiece GetType() { + return eStructurePiece_MineShaftStairs; + } + + public: + MineShaftStairs(); MineShaftStairs(int genDepth, Random* random, BoundingBox* stairsBox, int direction); + protected: + void addAdditonalSaveData(CompoundTag* tag); + void readAdditonalSaveData(CompoundTag* tag); + + public: static BoundingBox* findStairs(std::list* pieces, Random* random, int footX, int footY, int footZ, int direction); diff --git a/Minecraft.World/WorldGen/Structures/MineShaftStart.cpp b/Minecraft.World/WorldGen/Structures/MineShaftStart.cpp index ecee80167..465a30804 100644 --- a/Minecraft.World/WorldGen/Structures/MineShaftStart.cpp +++ b/Minecraft.World/WorldGen/Structures/MineShaftStart.cpp @@ -1,16 +1,19 @@ #include "../../Platform/stdafx.h" #include "../../Headers/net.minecraft.world.level.levelgen.structure.h" +MineShaftStart::MineShaftStart() { + // for reflection +} + MineShaftStart::MineShaftStart(Level* level, Random* random, int chunkX, - int chunkZ) { - // 4jcraft added to unsigned + int chunkZ) + : StructureStart(chunkX, chunkZ) { MineShaftPieces::MineShaftRoom* mineShaftRoom = - new MineShaftPieces::MineShaftRoom(0, random, - ((unsigned)chunkX << 4) + 2, - ((unsigned)chunkZ << 4) + 2); + new MineShaftPieces::MineShaftRoom(0, random, (chunkX << 4) + 2, + (chunkZ << 4) + 2); pieces.push_back(mineShaftRoom); mineShaftRoom->addChildren(mineShaftRoom, &pieces, random); calculateBoundingBox(); moveBelowSeaLevel(level, random, 10); -} +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Structures/MineShaftStart.h b/Minecraft.World/WorldGen/Structures/MineShaftStart.h index 76f9e60fd..625b1b1d2 100644 --- a/Minecraft.World/WorldGen/Structures/MineShaftStart.h +++ b/Minecraft.World/WorldGen/Structures/MineShaftStart.h @@ -4,5 +4,10 @@ class MineShaftStart : public StructureStart { public: + static StructureStart* Create() { return new MineShaftStart(); } + virtual EStructureStart GetType() { return eStructureStart_MineShaftStart; } + +public: + MineShaftStart(); MineShaftStart(Level* level, Random* random, int chunkX, int chunkZ); }; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Structures/NetherBridgePieces.cpp b/Minecraft.World/WorldGen/Structures/NetherBridgePieces.cpp index 03fc90367..450100a37 100644 --- a/Minecraft.World/WorldGen/Structures/NetherBridgePieces.cpp +++ b/Minecraft.World/WorldGen/Structures/NetherBridgePieces.cpp @@ -1,12 +1,52 @@ #include "../../Platform/stdafx.h" +#include "../../Headers/net.minecraft.world.item.h" #include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.tile.h" #include "../../Headers/net.minecraft.world.level.tile.entity.h" #include "../../Headers/net.minecraft.world.level.levelgen.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 "../../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, int maxPlaceCount, bool allowInRow) : weight(weight) { @@ -113,9 +153,34 @@ NetherBridgePieces::findAndCreateBridgePieceFactory( 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) : StructurePiece(genDepth) {} +void NetherBridgePieces::NetherBridgePiece::readAdditonalSaveData( + CompoundTag* tag) {} + +void NetherBridgePieces::NetherBridgePiece::addAdditonalSaveData( + CompoundTag* tag) {} + int NetherBridgePieces::NetherBridgePiece::updatePieceWeight( std::list* currentPieces) { bool hasAnyPieces = false; @@ -323,17 +388,17 @@ void NetherBridgePieces::NetherBridgePiece::generateLightPost( level->isEmptyTile(worldX, worldY + 1, worldZ) && level->isEmptyTile(worldX, worldY + 2, worldZ) && level->isEmptyTile(worldX, worldY + 3, worldZ)) { - level->setTileAndDataNoUpdate(worldX, worldY, worldZ, - Tile::netherFence_Id, 0); - level->setTileAndDataNoUpdate(worldX, worldY + 1, worldZ, - Tile::netherFence_Id, 0); - level->setTileAndDataNoUpdate(worldX, worldY + 2, worldZ, - Tile::netherFence_Id, 0); - level->setTileAndDataNoUpdate(worldX, worldY + 3, worldZ, - Tile::netherFence_Id, 0); + level->setTileAndData(worldX, worldY, worldZ, Tile::netherFence_Id, 0, + Tile::UPDATE_CLIENTS); + level->setTileAndData(worldX, worldY + 1, worldZ, Tile::netherFence_Id, + 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(worldX, worldY + 2, worldZ, Tile::netherFence_Id, + 0, Tile::UPDATE_CLIENTS); + level->setTileAndData(worldX, worldY + 3, worldZ, Tile::netherFence_Id, + 0, Tile::UPDATE_CLIENTS); placeBlock(level, Tile::netherFence_Id, 0, x + xOff, y + 3, z + zOff, 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); } } @@ -358,6 +423,10 @@ void NetherBridgePieces::NetherBridgePiece::generateLightPostFacingDown( generateLightPost(level, random, chunkBB, x, y, z, 0, -1); } +NetherBridgePieces::BridgeStraight::BridgeStraight() { + // for reflection +} + NetherBridgePieces::BridgeStraight::BridgeStraight(int genDepth, Random* random, BoundingBox* stairsBox, int direction) @@ -445,6 +514,10 @@ bool NetherBridgePieces::BridgeStraight::postProcess(Level* level, return true; } +NetherBridgePieces::BridgeEndFiller::BridgeEndFiller() { + // for reflection +} + NetherBridgePieces::BridgeEndFiller::BridgeEndFiller(int genDepth, Random* random, BoundingBox* stairsBox, @@ -520,6 +593,24 @@ bool NetherBridgePieces::BridgeEndFiller::postProcess(Level* level, 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, BoundingBox* stairsBox, int direction) @@ -639,10 +730,14 @@ bool NetherBridgePieces::BridgeCrossing::postProcess(Level* level, return true; } +NetherBridgePieces::StartPiece::StartPiece() { + // for reflection + previousPiece = NULL; +} + NetherBridgePieces::StartPiece::StartPiece(Random* random, int west, int north, Level* level) : BridgeCrossing(random, west, north) { - isLibraryAdded = false; previousPiece = NULL; 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, BoundingBox* box, int direction) : NetherBridgePiece(genDepth) { @@ -747,6 +854,10 @@ bool NetherBridgePieces::RoomCrossing::postProcess(Level* level, Random* random, return true; } +NetherBridgePieces::StairsRoom::StairsRoom() { + // for reflection +} + NetherBridgePieces::StairsRoom::StairsRoom(int genDepth, Random* random, BoundingBox* box, int direction) : NetherBridgePiece(genDepth) { @@ -838,6 +949,10 @@ bool NetherBridgePieces::StairsRoom::postProcess(Level* level, Random* random, return true; } +NetherBridgePieces::MonsterThrone::MonsterThrone() { + // for reflection +} + NetherBridgePieces::MonsterThrone::MonsterThrone(int genDepth, Random* random, BoundingBox* box, int direction) @@ -867,6 +982,19 @@ NetherBridgePieces::MonsterThrone::createPiece( 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, Random* random, BoundingBox* chunkBB) { @@ -913,11 +1041,12 @@ bool NetherBridgePieces::MonsterThrone::postProcess(Level* level, int y = getWorldY(5), x = getWorldX(3, 5), z = getWorldZ(3, 5); if (chunkBB->isInside(x, y, z)) { 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 entity = std::dynamic_pointer_cast( 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; } +NetherBridgePieces::CastleEntrance::CastleEntrance() { + // for reflection +} + NetherBridgePieces::CastleEntrance::CastleEntrance(int genDepth, Random* random, BoundingBox* stairsBox, int direction) @@ -1080,6 +1213,10 @@ bool NetherBridgePieces::CastleEntrance::postProcess(Level* level, return true; } +NetherBridgePieces::CastleStalkRoom::CastleStalkRoom() { + // for reflection +} + NetherBridgePieces::CastleStalkRoom::CastleStalkRoom(int genDepth, Random* random, BoundingBox* stairsBox, @@ -1241,10 +1378,10 @@ bool NetherBridgePieces::CastleStalkRoom::postProcess(Level* level, chunkBB); // farmlands - generateBox(level, chunkBB, 3, 4, 4, 4, 4, 8, Tile::hellSand_Id, - Tile::hellSand_Id, false); - generateBox(level, chunkBB, 8, 4, 4, 9, 4, 8, Tile::hellSand_Id, - Tile::hellSand_Id, false); + generateBox(level, chunkBB, 3, 4, 4, 4, 4, 8, Tile::soulsand_Id, + Tile::soulsand_Id, false); + generateBox(level, chunkBB, 8, 4, 4, 9, 4, 8, Tile::soulsand_Id, + Tile::soulsand_Id, false); generateBox(level, chunkBB, 3, 5, 4, 4, 5, 8, Tile::netherStalk_Id, Tile::netherStalk_Id, false); generateBox(level, chunkBB, 8, 5, 4, 9, 5, 8, Tile::netherStalk_Id, @@ -1283,6 +1420,10 @@ bool NetherBridgePieces::CastleStalkRoom::postProcess(Level* level, return true; } +NetherBridgePieces::CastleSmallCorridorPiece::CastleSmallCorridorPiece() { + // for reflection +} + NetherBridgePieces::CastleSmallCorridorPiece::CastleSmallCorridorPiece( int genDepth, Random* random, BoundingBox* stairsBox, int direction) : NetherBridgePiece(genDepth) { @@ -1352,6 +1493,11 @@ bool NetherBridgePieces::CastleSmallCorridorPiece::postProcess( return true; } +NetherBridgePieces::CastleSmallCorridorCrossingPiece:: + CastleSmallCorridorCrossingPiece() { + // for reflection +} + NetherBridgePieces::CastleSmallCorridorCrossingPiece:: CastleSmallCorridorCrossingPiece(int genDepth, Random* random, BoundingBox* stairsBox, int direction) @@ -1421,12 +1567,33 @@ bool NetherBridgePieces::CastleSmallCorridorCrossingPiece::postProcess( return true; } +NetherBridgePieces::CastleSmallCorridorRightTurnPiece:: + CastleSmallCorridorRightTurnPiece() { + // for reflection + isNeedingChest = false; +} + NetherBridgePieces::CastleSmallCorridorRightTurnPiece:: CastleSmallCorridorRightTurnPiece(int genDepth, Random* random, BoundingBox* stairsBox, int direction) : NetherBridgePiece(genDepth) { orientation = direction; 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( @@ -1482,6 +1649,18 @@ bool NetherBridgePieces::CastleSmallCorridorRightTurnPiece::postProcess( generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, Tile::netherFence_Id, 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 generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); @@ -1496,12 +1675,33 @@ bool NetherBridgePieces::CastleSmallCorridorRightTurnPiece::postProcess( return true; } +NetherBridgePieces::CastleSmallCorridorLeftTurnPiece:: + CastleSmallCorridorLeftTurnPiece() { + isNeedingChest = false; + // for reflection +} + NetherBridgePieces::CastleSmallCorridorLeftTurnPiece:: CastleSmallCorridorLeftTurnPiece(int genDepth, Random* random, BoundingBox* stairsBox, int direction) : NetherBridgePiece(genDepth) { orientation = direction; 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( @@ -1557,6 +1757,18 @@ bool NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::postProcess( generateBox(level, chunkBB, 3, 3, 4, 3, 4, 4, Tile::netherFence_Id, 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 generateBox(level, chunkBB, 0, 6, 0, 4, 6, 4, Tile::netherBrick_Id, Tile::netherBrick_Id, false); @@ -1571,6 +1783,10 @@ bool NetherBridgePieces::CastleSmallCorridorLeftTurnPiece::postProcess( return true; } +NetherBridgePieces::CastleCorridorStairsPiece::CastleCorridorStairsPiece() { + // for reflection +} + NetherBridgePieces::CastleCorridorStairsPiece::CastleCorridorStairsPiece( int genDepth, Random* random, BoundingBox* stairsBox, int direction) : NetherBridgePiece(genDepth) { @@ -1651,6 +1867,10 @@ bool NetherBridgePieces::CastleCorridorStairsPiece::postProcess( return true; } +NetherBridgePieces::CastleCorridorTBalconyPiece::CastleCorridorTBalconyPiece() { + // for reflection +} + NetherBridgePieces::CastleCorridorTBalconyPiece::CastleCorridorTBalconyPiece( int genDepth, Random* random, BoundingBox* stairsBox, int direction) : NetherBridgePiece(genDepth) { diff --git a/Minecraft.World/WorldGen/Structures/NetherBridgePieces.h b/Minecraft.World/WorldGen/Structures/NetherBridgePieces.h index ac2ba4590..1dfd9b8bf 100644 --- a/Minecraft.World/WorldGen/Structures/NetherBridgePieces.h +++ b/Minecraft.World/WorldGen/Structures/NetherBridgePieces.h @@ -26,6 +26,10 @@ private: EPieceClass_CastleCorridorTBalconyPiece }; +public: + static void loadStatic(); + +private: class PieceWeight { public: EPieceClass pieceClass; @@ -64,9 +68,20 @@ public: private: class NetherBridgePiece : public StructurePiece { + protected: + static const int FORTRESS_TREASURE_ITEMS_COUNT = 11; + static WeighedTreasure* + fortressTreasureItems[FORTRESS_TREASURE_ITEMS_COUNT]; + + public: + NetherBridgePiece(); + protected: NetherBridgePiece(int genDepth); + virtual void readAdditonalSaveData(CompoundTag* tag); + virtual void addAdditonalSaveData(CompoundTag* tag); + private: int updatePieceWeight(std::list* currentPieces); @@ -120,12 +135,19 @@ private: * */ class BridgeStraight : public NetherBridgePiece { + public: + static StructurePiece* Create() { return new BridgeStraight(); } + virtual EStructurePiece GetType() { + return eStructurePiece_BridgeStraight; + } + private: static const int width = 5; static const int height = 10; static const int depth = 19; public: + BridgeStraight(); BridgeStraight(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -140,6 +162,12 @@ private: }; class BridgeEndFiller : public NetherBridgePiece { + public: + static StructurePiece* Create() { return new BridgeEndFiller(); } + virtual EStructurePiece GetType() { + return eStructurePiece_BridgeEndFiller; + } + private: static const int width = 5; static const int height = 10; @@ -148,23 +176,36 @@ private: int selfSeed; public: + BridgeEndFiller(); BridgeEndFiller(int genDepth, Random* random, BoundingBox* stairsBox, int direction); + static BridgeEndFiller* createPiece(std::list* pieces, Random* random, int footX, int footY, int footZ, int direction, int genDepth); virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB); + + protected: + void readAdditonalSaveData(CompoundTag* tag); + void addAdditonalSaveData(CompoundTag* tag); }; class BridgeCrossing : public NetherBridgePiece { + public: + static StructurePiece* Create() { return new BridgeCrossing(); } + virtual EStructurePiece GetType() { + return eStructurePiece_BridgeCrossing; + } + private: static const int width = 19; static const int height = 10; static const int depth = 19; public: + BridgeCrossing(); BridgeCrossing(int genDepth, Random* random, BoundingBox* stairsBox, int direction); @@ -186,7 +227,11 @@ private: public: class StartPiece : public BridgeCrossing { public: - bool isLibraryAdded; + virtual EStructurePiece GetType() { + return eStructurePiece_NetherBridgeStartPiece; + } + + public: PieceWeight* previousPiece; Level* m_level; @@ -197,18 +242,30 @@ public: // called in a random order std::vector pendingChildren; + StartPiece(); StartPiece(Random* random, int west, int north, Level* level); // 4J Added level param + + protected: + virtual void readAdditonalSaveData(CompoundTag* tag); + virtual void addAdditonalSaveData(CompoundTag* tag); }; private: class RoomCrossing : public NetherBridgePiece { + public: + static StructurePiece* Create() { return new RoomCrossing(); } + virtual EStructurePiece GetType() { + return eStructurePiece_RoomCrossing; + } + private: static const int width = 7; static const int height = 9; static const int depth = 7; public: + RoomCrossing(); RoomCrossing(int genDepth, Random* random, BoundingBox* box, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -223,12 +280,17 @@ private: }; class StairsRoom : public NetherBridgePiece { + public: + static StructurePiece* Create() { return new StairsRoom(); } + virtual EStructurePiece GetType() { return eStructurePiece_StairsRoom; } + private: static const int width = 7; static const int height = 11; static const int depth = 7; public: + StairsRoom(); StairsRoom(int genDepth, Random* random, BoundingBox* box, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -242,6 +304,12 @@ private: }; class MonsterThrone : public NetherBridgePiece { + public: + static StructurePiece* Create() { return new MonsterThrone(); } + virtual EStructurePiece GetType() { + return eStructurePiece_MonsterThrone; + } + private: static const int width = 7; static const int height = 8; @@ -250,8 +318,15 @@ private: bool hasPlacedMobSpawner; public: + MonsterThrone(); MonsterThrone(int genDepth, Random* random, BoundingBox* box, int direction); + + protected: + virtual void readAdditonalSaveData(CompoundTag* tag); + virtual void addAdditonalSaveData(CompoundTag* tag); + + public: static MonsterThrone* createPiece(std::list* pieces, Random* random, int footX, int footY, int footZ, int direction, @@ -265,12 +340,19 @@ private: * */ class CastleEntrance : public NetherBridgePiece { + public: + static StructurePiece* Create() { return new CastleEntrance(); } + virtual EStructurePiece GetType() { + return eStructurePiece_CastleEntrance; + } + private: static const int width = 13; static const int height = 14; static const int depth = 13; public: + CastleEntrance(); CastleEntrance(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -289,12 +371,19 @@ private: * */ class CastleStalkRoom : public NetherBridgePiece { + public: + static StructurePiece* Create() { return new CastleStalkRoom(); } + virtual EStructurePiece GetType() { + return eStructurePiece_CastleStalkRoom; + } + private: static const int width = 13; static const int height = 14; static const int depth = 13; public: + CastleStalkRoom(); CastleStalkRoom(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -313,12 +402,21 @@ private: * */ class CastleSmallCorridorPiece : public NetherBridgePiece { + public: + static StructurePiece* Create() { + return new CastleSmallCorridorPiece(); + } + virtual EStructurePiece GetType() { + return eStructurePiece_CastleSmallCorridorPiece; + } + private: static const int width = 5; static const int height = 7; static const int depth = 5; public: + CastleSmallCorridorPiece(); CastleSmallCorridorPiece(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -336,12 +434,21 @@ private: * */ class CastleSmallCorridorCrossingPiece : public NetherBridgePiece { + public: + static StructurePiece* Create() { + return new CastleSmallCorridorCrossingPiece(); + } + virtual EStructurePiece GetType() { + return eStructurePiece_CastleSmallCorridorCrossingPiece; + } + private: static const int width = 5; static const int height = 7; static const int depth = 5; public: + CastleSmallCorridorCrossingPiece(); CastleSmallCorridorCrossingPiece(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -359,15 +466,32 @@ private: * */ class CastleSmallCorridorRightTurnPiece : public NetherBridgePiece { + public: + static StructurePiece* Create() { + return new CastleSmallCorridorRightTurnPiece(); + } + virtual EStructurePiece GetType() { + return eStructurePiece_CastleSmallCorridorRightTurnPiece; + } + private: static const int width = 5; static const int height = 7; static const int depth = 5; + bool isNeedingChest; + public: + CastleSmallCorridorRightTurnPiece(); CastleSmallCorridorRightTurnPiece(int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + virtual void readAdditonalSaveData(CompoundTag* tag); + virtual void addAdditonalSaveData(CompoundTag* tag); + + public: virtual void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); @@ -383,14 +507,30 @@ private: * */ class CastleSmallCorridorLeftTurnPiece : public NetherBridgePiece { + public: + static StructurePiece* Create() { + return new CastleSmallCorridorLeftTurnPiece(); + } + virtual EStructurePiece GetType() { + return eStructurePiece_CastleSmallCorridorLeftTurnPiece; + } + private: static const int width = 5; static const int height = 7; static const int depth = 5; + bool isNeedingChest; public: + CastleSmallCorridorLeftTurnPiece(); CastleSmallCorridorLeftTurnPiece(int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + virtual void readAdditonalSaveData(CompoundTag* tag); + virtual void addAdditonalSaveData(CompoundTag* tag); + + public: virtual void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); @@ -406,12 +546,21 @@ private: * */ class CastleCorridorStairsPiece : public NetherBridgePiece { + public: + static StructurePiece* Create() { + return new CastleCorridorStairsPiece(); + } + virtual EStructurePiece GetType() { + return eStructurePiece_CastleCorridorStairsPiece; + } + private: static const int width = 5; static const int height = 14; static const int depth = 10; public: + CastleCorridorStairsPiece(); CastleCorridorStairsPiece(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -429,12 +578,21 @@ private: * */ class CastleCorridorTBalconyPiece : public NetherBridgePiece { + public: + static StructurePiece* Create() { + return new CastleCorridorTBalconyPiece(); + } + virtual EStructurePiece GetType() { + return eStructurePiece_CastleCorridorTBalconyPiece; + } + private: static const int width = 9; static const int height = 7; static const int depth = 9; public: + CastleCorridorTBalconyPiece(); CastleCorridorTBalconyPiece(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, diff --git a/Minecraft.World/WorldGen/Structures/ScatteredFeaturePieces.cpp b/Minecraft.World/WorldGen/Structures/ScatteredFeaturePieces.cpp index 1bf46204d..359c9aded 100644 --- a/Minecraft.World/WorldGen/Structures/ScatteredFeaturePieces.cpp +++ b/Minecraft.World/WorldGen/Structures/ScatteredFeaturePieces.cpp @@ -1,12 +1,31 @@ #include "../../Platform/stdafx.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.level.dimension.h" #include "../../Headers/net.minecraft.world.level.h" #include "../../Headers/net.minecraft.world.level.tile.h" +#include "../../Headers/net.minecraft.world.level.levelgen.structure.h" #include "../../Util/WeighedTreasure.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( Random* random, int west, int floor, int north, int width, int height, int depth) @@ -18,6 +37,16 @@ ScatteredFeaturePieces::ScatteredFeaturePiece::ScatteredFeaturePiece( 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) { case Direction::NORTH: 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( Level* level, BoundingBox* chunkBB, int offset) { if (heightPosition >= 0) { @@ -67,8 +112,22 @@ WeighedTreasure* ScatteredFeaturePieces::DesertPyramidPiece::treasureItems new WeighedTreasure(Item::emerald_Id, 0, 1, 3, 2), new WeighedTreasure(Item::bone_Id, 0, 4, 6, 20), 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, int west, int north) @@ -79,6 +138,24 @@ ScatteredFeaturePieces::DesertPyramidPiece::DesertPyramidPiece(Random* random, 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( Level* level, Random* random, BoundingBox* chunkBB) { // pyramid @@ -232,48 +309,48 @@ bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess( placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_HEIROGLYPHS, width - 5, 2, z, chunkBB); } - placeBlock(level, Tile::cloth_Id, baseDecoColor, 10, 0, 7, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 10, 0, 8, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 9, 0, 9, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 11, 0, 9, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 8, 0, 10, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 12, 0, 10, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 7, 0, 10, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 13, 0, 10, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 9, 0, 11, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 11, 0, 11, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 10, 0, 12, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 10, 0, 13, chunkBB); - placeBlock(level, Tile::cloth_Id, blue, 10, 0, 10, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 10, 0, 7, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 10, 0, 8, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 9, 0, 9, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 11, 0, 9, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 8, 0, 10, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 12, 0, 10, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 7, 0, 10, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 13, 0, 10, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 9, 0, 11, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 11, 0, 11, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 10, 0, 12, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 10, 0, 13, chunkBB); + placeBlock(level, Tile::wool_Id, blue, 10, 0, 10, chunkBB); // outdoor decoration for (int x = 0; x <= width - 1; x += width - 1) { placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 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, 2, 3, chunkBB); placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 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, 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, 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, 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, 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, x, 6, 2, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 6, 3, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 7, 1, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 7, 2, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, x, 7, 3, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, x, 6, 3, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, x, 7, 1, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, x, 7, 2, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, x, 7, 3, chunkBB); placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, 8, 1, chunkBB); 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) { placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 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, x + 1, 2, 0, chunkBB); placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, 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, 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, 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, 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, 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, x, 6, 0, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, x + 1, 6, 00, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, x - 1, 7, 0, chunkBB); - placeBlock(level, Tile::cloth_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, 6, 00, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, x - 1, 7, 0, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, x, 7, 0, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, x + 1, 7, 0, chunkBB); placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x - 1, 8, 0, chunkBB); placeBlock(level, Tile::sandStone_Id, SandStoneTile::TYPE_SMOOTHSIDE, x, @@ -320,10 +397,10 @@ bool ScatteredFeaturePieces::DesertPyramidPiece::postProcess( SandStoneTile::TYPE_SMOOTHSIDE, false); placeBlock(level, 0, 0, 8, 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, 5, 0, chunkBB); - placeBlock(level, Tile::cloth_Id, baseDecoColor, 11, 5, 0, chunkBB); + placeBlock(level, Tile::wool_Id, baseDecoColor, 11, 5, 0, chunkBB); // tombs 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::bone_Id, 0, 4, 6, 20), 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 @@ -398,6 +481,10 @@ WeighedTreasure* ScatteredFeaturePieces::JunglePyramidPiece::dispenserItems // new WeighedTreasure(Item.fireball.id, 0, 1, 1, 10), }; +ScatteredFeaturePieces::JunglePyramidPiece::JunglePyramidPiece() { + // for reflection +} + ScatteredFeaturePieces::JunglePyramidPiece::JunglePyramidPiece(Random* random, int west, int north) @@ -408,6 +495,24 @@ ScatteredFeaturePieces::JunglePyramidPiece::JunglePyramidPiece(Random* random, 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( Level* level, Random* random, BoundingBox* chunkBB) { 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, 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) { placedTrap1 = createDispenser( 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, 9, -3, 6, 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); if (!placedTrap2) { placedTrap2 = createDispenser( @@ -636,26 +741,26 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess( Item::enchantedBook->createForRandomTreasure(random)), 2 + random->nextInt(5)); } - placeBlock(level, Tile::mossStone_Id, 0, 9, -3, 2, chunkBB); - placeBlock(level, Tile::mossStone_Id, 0, 8, -3, 1, chunkBB); - placeBlock(level, Tile::mossStone_Id, 0, 4, -3, 5, chunkBB); - placeBlock(level, Tile::mossStone_Id, 0, 5, -2, 5, chunkBB); - placeBlock(level, Tile::mossStone_Id, 0, 5, -1, 5, chunkBB); - placeBlock(level, Tile::mossStone_Id, 0, 6, -3, 5, chunkBB); - placeBlock(level, Tile::mossStone_Id, 0, 7, -2, 5, chunkBB); - placeBlock(level, Tile::mossStone_Id, 0, 7, -1, 5, chunkBB); - placeBlock(level, Tile::mossStone_Id, 0, 8, -3, 5, chunkBB); + placeBlock(level, Tile::mossyCobblestone_Id, 0, 9, -3, 2, chunkBB); + placeBlock(level, Tile::mossyCobblestone_Id, 0, 8, -3, 1, chunkBB); + placeBlock(level, Tile::mossyCobblestone_Id, 0, 4, -3, 5, chunkBB); + placeBlock(level, Tile::mossyCobblestone_Id, 0, 5, -2, 5, chunkBB); + placeBlock(level, Tile::mossyCobblestone_Id, 0, 5, -1, 5, chunkBB); + placeBlock(level, Tile::mossyCobblestone_Id, 0, 6, -3, 5, chunkBB); + placeBlock(level, Tile::mossyCobblestone_Id, 0, 7, -2, 5, chunkBB); + placeBlock(level, Tile::mossyCobblestone_Id, 0, 7, -1, 5, chunkBB); + placeBlock(level, Tile::mossyCobblestone_Id, 0, 8, -3, 5, chunkBB); generateBox(level, chunkBB, 9, -1, 1, 9, -1, 5, false, random, &stoneSelector); // hidden room generateAirBox(level, chunkBB, 8, -3, 8, 10, -1, 10); - placeBlock(level, Tile::stoneBrickSmooth_Id, - SmoothStoneBrickTile::TYPE_DETAIL, 8, -2, 11, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, - SmoothStoneBrickTile::TYPE_DETAIL, 9, -2, 11, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, - SmoothStoneBrickTile::TYPE_DETAIL, 10, -2, 11, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, 8, + -2, 11, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, 9, + -2, 11, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, SmoothStoneBrickTile::TYPE_DETAIL, + 10, -2, 11, chunkBB); placeBlock(level, Tile::lever_Id, LeverTile::getLeverFacing( getOrientationData(Tile::lever_Id, Facing::NORTH)), @@ -672,7 +777,7 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess( &stoneSelector); generateBox(level, chunkBB, 10, -3, 8, 10, -3, 10, false, random, &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, 10, chunkBB); placeBlock(level, Tile::redStoneDust_Id, 0, 10, -1, 9, chunkBB); @@ -701,11 +806,136 @@ bool ScatteredFeaturePieces::JunglePyramidPiece::postProcess( void ScatteredFeaturePieces::JunglePyramidPiece::MossStoneSelector::next( Random* random, int worldX, int worldY, int worldZ, bool isEdge) { if (random->nextFloat() < .4f) { - nextId = Tile::stoneBrick_Id; + nextId = Tile::cobblestone_Id; } else { - nextId = Tile::mossStone_Id; + nextId = Tile::mossyCobblestone_Id; } } ScatteredFeaturePieces::JunglePyramidPiece::MossStoneSelector - ScatteredFeaturePieces::JunglePyramidPiece::stoneSelector; \ No newline at end of file + 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 = + std::shared_ptr(new Witch(level)); + witch->moveTo(wx + .5, wy, wz + .5, 0, 0); + witch->finalizeMobSpawn(NULL); + level->addEntity(witch); + } + } + + return true; +} \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Structures/ScatteredFeaturePieces.h b/Minecraft.World/WorldGen/Structures/ScatteredFeaturePieces.h index 802c92374..9828f5675 100644 --- a/Minecraft.World/WorldGen/Structures/ScatteredFeaturePieces.h +++ b/Minecraft.World/WorldGen/Structures/ScatteredFeaturePieces.h @@ -3,6 +3,9 @@ #include "StructurePiece.h" class ScatteredFeaturePieces { +public: + static void loadStatic(); + private: class ScatteredFeaturePiece : public StructurePiece { protected: @@ -12,9 +15,12 @@ private: int heightPosition; + ScatteredFeaturePiece(); ScatteredFeaturePiece(Random* random, int west, int floor, int north, int width, int height, int depth); + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); bool updateAverageGroundHeight(Level* level, BoundingBox* chunkBB, int offset); }; @@ -22,21 +28,38 @@ private: public: class DesertPyramidPiece : public ScatteredFeaturePiece { 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: bool hasPlacedChest[4]; static WeighedTreasure* treasureItems[TREASURE_ITEMS_COUNT]; public: + DesertPyramidPiece(); 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); }; class JunglePyramidPiece : public ScatteredFeaturePiece { 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; private: @@ -49,8 +72,14 @@ public: static WeighedTreasure* dispenserItems[DISPENSER_ITEMS_COUNT]; public: + JunglePyramidPiece(); 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); private: @@ -62,4 +91,26 @@ public: 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); + }; }; \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Structures/StrongholdPieces.cpp b/Minecraft.World/WorldGen/Structures/StrongholdPieces.cpp index 876743744..51af77a16 100644 --- a/Minecraft.World/WorldGen/Structures/StrongholdPieces.cpp +++ b/Minecraft.World/WorldGen/Structures/StrongholdPieces.cpp @@ -5,6 +5,7 @@ #include "../../Headers/net.minecraft.world.level.tile.entity.h" #include "../../Headers/net.minecraft.world.level.storage.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 "../../Util/WeighedTreasure.h" #include "../../IO/Files/FileHeader.h" @@ -15,6 +16,35 @@ std::list StrongholdPieces::currentPieces; StrongholdPieces::EPieceClass StrongholdPieces::imposedPiece; 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, int maxPlaceCount) : weight(weight) { @@ -223,8 +253,24 @@ StructurePiece* StrongholdPieces::generateAndAddPiece( return newPiece; } +StrongholdPieces::StrongholdPiece::StrongholdPiece() { + entryDoor = OPENING; + // for reflection +} + StrongholdPieces::StrongholdPiece::StrongholdPiece(int genDepth) - : StructurePiece(genDepth) {} + : StructurePiece(genDepth) { + entryDoor = OPENING; +} + +void StrongholdPieces::StrongholdPiece::addAdditonalSaveData(CompoundTag* tag) { + tag->putString(L"EntryDoor", _toString(entryDoor)); +} + +void StrongholdPieces::StrongholdPiece::readAdditonalSaveData( + CompoundTag* tag) { + entryDoor = (SmallDoorType)_fromString(tag->getString(L"EntryDoor")); +} void StrongholdPieces::StrongholdPiece::generateSmallDoor( Level* level, Random* random, BoundingBox* chunkBB, @@ -238,20 +284,20 @@ void StrongholdPieces::StrongholdPiece::generateSmallDoor( footY + SMALL_DOOR_HEIGHT - 1, footZ, 0, 0, false); break; case WOOD_DOOR: - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX, footY, footZ, + placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY, footZ, 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); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX, footY + 2, + placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX + 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, + placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 1, footZ, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY, footZ, + chunkBB); placeBlock(level, Tile::door_wood_Id, 0, footX + 1, footY, footZ, chunkBB); placeBlock(level, Tile::door_wood_Id, DoorTile::UPPER_BIT, @@ -276,20 +322,20 @@ void StrongholdPieces::StrongholdPiece::generateSmallDoor( chunkBB); break; case IRON_DOOR: - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX, footY, footZ, + placeBlock(level, Tile::stoneBrick_Id, 0, footX, footY, footZ, 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); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX, footY + 2, + placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 2, footZ, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, footX + 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, + placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY + 1, footZ, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, footX + 2, footY, footZ, + chunkBB); placeBlock(level, Tile::door_iron_Id, 0, footX + 1, footY, footZ, chunkBB); placeBlock(level, Tile::door_iron_Id, DoorTile::UPPER_BIT, @@ -431,6 +477,10 @@ bool StrongholdPieces::StrongholdPiece::isOkBox(BoundingBox* box, return bIsOk; } +StrongholdPieces::FillerCorridor::FillerCorridor() : steps(0) { + // for reflection +} + StrongholdPieces::FillerCorridor::FillerCorridor(int genDepth, Random* random, BoundingBox* corridorBox, int direction) @@ -442,6 +492,16 @@ StrongholdPieces::FillerCorridor::FillerCorridor(int genDepth, Random* random, 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( std::list* pieces, Random* random, int footX, int footY, int footZ, int direction) { @@ -469,8 +529,7 @@ BoundingBox* StrongholdPieces::FillerCorridor::findPieceBox( if (!collisionPiece->getBoundingBox()->intersects(box)) { delete box; // the corridor has shrunk enough to fit, but make it - // one step too big to build an entrance into the other - // block + // one step too big to build an entrance into the other block return BoundingBox::orientBox(footX, footY, footZ, -1, -1, 0, 5, 5, depth, direction); } @@ -490,34 +549,39 @@ bool StrongholdPieces::FillerCorridor::postProcess(Level* level, Random* random, // filler corridor for (int i = 0; i < steps; i++) { // row 0 - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 0, 0, i, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 0, i, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, 0, i, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 0, i, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 4, 0, i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 0, 0, i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 1, 0, i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 2, 0, i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 3, 0, i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 4, 0, i, chunkBB); // row 1-3 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, 2, 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 - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 0, 4, i, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 4, i, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, 4, i, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 4, i, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 4, 4, i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 0, 4, i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 1, 4, i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 2, 4, i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 3, 4, i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 4, 4, i, chunkBB); } return true; } +StrongholdPieces::StairsDown::StairsDown() { + // for reflection +} + StrongholdPieces::StairsDown::StairsDown(int genDepth, Random* random, int west, int north) - : StrongholdPiece(genDepth), isSource(true), entryDoor(OPENING) { + : StrongholdPiece(genDepth), isSource(true) { orientation = random->nextInt(4); + entryDoor = OPENING; switch (orientation) { case Direction::NORTH: @@ -534,13 +598,22 @@ StrongholdPieces::StairsDown::StairsDown(int genDepth, Random* random, int west, StrongholdPieces::StairsDown::StairsDown(int genDepth, Random* random, BoundingBox* stairsBox, int direction) - : StrongholdPiece(genDepth), - isSource(false), - entryDoor(randomSmallDoor(random)) { + : StrongholdPiece(genDepth), isSource(false) { + entryDoor = randomSmallDoor(random); orientation = direction; 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( StructurePiece* startPiece, std::list* pieces, Random* random) { @@ -587,33 +660,37 @@ bool StrongholdPieces::StairsDown::postProcess(Level* level, Random* random, generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); // stair steps - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, 6, 1, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 5, 1, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 2, 6, 1, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 1, 5, 1, chunkBB); placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 6, 1, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 5, 2, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 4, 3, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 1, 5, 2, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 1, 4, 3, chunkBB); placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 5, 3, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, 4, 3, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 3, 3, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 2, 4, 3, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 3, 3, 3, chunkBB); placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 3, 4, 3, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 3, 2, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 2, 1, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 3, 3, 2, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 3, 2, 1, chunkBB); placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 3, 3, 1, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, 2, 1, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, 1, 1, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 2, 2, 1, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 1, 1, 1, chunkBB); placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::STONE_SLAB, 1, 2, 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, 3, chunkBB); return true; } +StrongholdPieces::StartPiece::StartPiece() { + // for reflection +} + StrongholdPieces::StartPiece::StartPiece(int genDepth, Random* random, int west, int north, Level* level) : StairsDown(0, random, west, north) { @@ -632,16 +709,32 @@ TilePos* StrongholdPieces::StartPiece::getLocatorPosition() { return StairsDown::getLocatorPosition(); } +StrongholdPieces::Straight::Straight() { + // for reflection +} + StrongholdPieces::Straight::Straight(int genDepth, Random* random, BoundingBox* stairsBox, int direction) : StrongholdPiece(genDepth), - entryDoor(randomSmallDoor(random)), leftChild(random->nextInt(2) == 0), rightChild(random->nextInt(2) == 0) { + entryDoor = randomSmallDoor(random); orientation = direction; 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, std::list* pieces, Random* random) { @@ -719,16 +812,38 @@ WeighedTreasure* new WeighedTreasure(Item::helmet_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::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, BoundingBox* stairsBox, int direction) - : StrongholdPiece(genDepth), entryDoor(randomSmallDoor(random)) { + : StrongholdPiece(genDepth) { + entryDoor = randomSmallDoor(random); orientation = direction; 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( StructurePiece* startPiece, std::list* pieces, Random* random) { @@ -771,8 +886,8 @@ bool StrongholdPieces::ChestCorridor::postProcess(Level* level, Random* random, generateSmallDoor(level, random, chunkBB, OPENING, 1, 1, depth - 1); // chest placement - generateBox(level, chunkBB, 3, 1, 2, 3, 1, 4, Tile::stoneBrickSmooth_Id, - Tile::stoneBrickSmooth_Id, false); + generateBox(level, chunkBB, 3, 1, 2, 3, 1, 4, Tile::stoneBrick_Id, + Tile::stoneBrick_Id, false); placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, 3, 1, 1, chunkBB); placeBlock(level, Tile::stoneSlabHalf_Id, StoneSlabTile::SMOOTHBRICK_SLAB, @@ -803,11 +918,16 @@ bool StrongholdPieces::ChestCorridor::postProcess(Level* level, Random* random, return true; } +StrongholdPieces::StraightStairsDown::StraightStairsDown() { + // for reflection +} + StrongholdPieces::StraightStairsDown::StraightStairsDown(int genDepth, Random* random, BoundingBox* stairsBox, int direction) - : StrongholdPiece(genDepth), entryDoor(randomSmallDoor(random)) { + : StrongholdPiece(genDepth) { + entryDoor = randomSmallDoor(random); orientation = direction; boundingBox = stairsBox; } @@ -866,21 +986,26 @@ bool StrongholdPieces::StraightStairsDown::postProcess(Level* level, placeBlock(level, Tile::stairs_stone_Id, orientationData, 3, height - 5 - i, 1 + i, chunkBB); if (i < 5) { - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 1, height - 6 - i, - 1 + i, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 2, height - 6 - i, - 1 + i, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, height - 6 - i, - 1 + i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 1, height - 6 - i, 1 + i, + chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 2, height - 6 - i, 1 + i, + chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 3, height - 6 - i, 1 + i, + chunkBB); } } return true; } +StrongholdPieces::LeftTurn::LeftTurn() { + // for reflection +} + StrongholdPieces::LeftTurn::LeftTurn(int genDepth, Random* random, BoundingBox* stairsBox, int direction) - : StrongholdPiece(genDepth), entryDoor(randomSmallDoor(random)) { + : StrongholdPiece(genDepth) { + entryDoor = randomSmallDoor(random); orientation = direction; boundingBox = stairsBox; } @@ -938,6 +1063,10 @@ bool StrongholdPieces::LeftTurn::postProcess(Level* level, Random* random, return true; } +StrongholdPieces::RightTurn::RightTurn() { + // for reflection +} + StrongholdPieces::RightTurn::RightTurn(int genDepth, Random* random, BoundingBox* stairsBox, int direction) : LeftTurn(genDepth, random, stairsBox, direction) {} @@ -976,16 +1105,29 @@ bool StrongholdPieces::RightTurn::postProcess(Level* level, Random* random, return true; } +StrongholdPieces::RoomCrossing::RoomCrossing() { + // for reflection +} + StrongholdPieces::RoomCrossing::RoomCrossing(int genDepth, Random* random, BoundingBox* stairsBox, int direction) - : StrongholdPiece(genDepth), - entryDoor(randomSmallDoor(random)), - type(random->nextInt(5)) { + : StrongholdPiece(genDepth), type(random->nextInt(5)) { + entryDoor = randomSmallDoor(random); orientation = direction; 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( StructurePiece* startPiece, std::list* pieces, Random* random) { @@ -1046,9 +1188,9 @@ bool StrongholdPieces::RoomCrossing::postProcess(Level* level, Random* random, break; case 0: // middle torch pillar - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 1, 5, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 2, 5, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 3, 5, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 5, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 5, 2, 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, 6, 3, 5, chunkBB); placeBlock(level, Tile::torch_Id, 0, 5, 3, 4, chunkBB); @@ -1064,42 +1206,38 @@ bool StrongholdPieces::RoomCrossing::postProcess(Level* level, Random* random, break; case 1: { for (int i = 0; i < 5; i++) { - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 3, 1, 3 + i, - chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 7, 1, 3 + i, - 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::stoneBrick_Id, 0, 3, 1, 3 + i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 7, 1, 3 + i, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 3 + i, 1, 3, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 3 + i, 1, 7, chunkBB); } - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 1, 5, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 2, 5, chunkBB); - placeBlock(level, Tile::stoneBrickSmooth_Id, 0, 5, 3, 5, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 5, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 5, 2, 5, chunkBB); + placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 5, chunkBB); placeBlock(level, Tile::water_Id, 0, 5, 4, 5, chunkBB); } break; case 2: { for (int z = 1; z <= 9; z++) { - placeBlock(level, Tile::stoneBrick_Id, 0, 1, 3, z, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 9, 3, z, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 1, 3, z, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 9, 3, z, chunkBB); } for (int x = 1; x <= 9; x++) { - placeBlock(level, Tile::stoneBrick_Id, 0, x, 3, 1, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, x, 3, 9, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, x, 3, 1, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, x, 3, 9, chunkBB); } - placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 4, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 5, 1, 6, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 4, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 5, 3, 6, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 1, 5, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 6, 1, 5, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 3, 5, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 6, 3, 5, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 5, 1, 4, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 5, 1, 6, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 5, 3, 4, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 5, 3, 6, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, 1, 5, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 6, 1, 5, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, 3, 5, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 6, 3, 5, chunkBB); for (int y = 1; y <= 3; y++) { - placeBlock(level, Tile::stoneBrick_Id, 0, 4, y, 4, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 6, y, 4, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, y, 6, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 6, y, 6, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, y, 4, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 6, y, 4, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, y, 6, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 6, y, 6, chunkBB); } placeBlock(level, Tile::torch_Id, 0, 5, 3, 5, chunkBB); for (int z = 2; z <= 8; z++) { @@ -1138,9 +1276,14 @@ bool StrongholdPieces::RoomCrossing::postProcess(Level* level, Random* random, return true; } +StrongholdPieces::PrisonHall::PrisonHall() { + // for reflection +} + StrongholdPieces::PrisonHall::PrisonHall(int genDepth, Random* random, BoundingBox* stairsBox, int direction) - : StrongholdPiece(genDepth), entryDoor(randomSmallDoor(random)) { + : StrongholdPiece(genDepth) { + entryDoor = randomSmallDoor(random); orientation = direction; boundingBox = stairsBox; } @@ -1218,15 +1361,29 @@ bool StrongholdPieces::PrisonHall::postProcess(Level* level, Random* random, return true; } +StrongholdPieces::Library::Library() { + isTall = false; + // for reflection +} + StrongholdPieces::Library::Library(int genDepth, Random* random, BoundingBox* roomBox, int direction) - : StrongholdPiece(genDepth), - entryDoor(randomSmallDoor(random)), - isTall(roomBox->getYSpan() > height) { + : StrongholdPiece(genDepth), isTall(roomBox->getYSpan() > height) { + entryDoor = randomSmallDoor(random); orientation = direction; 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( std::list* pieces, Random* random, int footX, int footY, int footZ, int direction, int genDepth) { @@ -1426,10 +1583,16 @@ bool StrongholdPieces::Library::postProcess(Level* level, Random* random, return true; } +StrongholdPieces::FiveCrossing::FiveCrossing() { + leftLow = leftHigh = rightLow = rightHigh = false; + // for reflection +} + StrongholdPieces::FiveCrossing::FiveCrossing(int genDepth, Random* random, BoundingBox* stairsBox, int direction) - : StrongholdPiece(genDepth), entryDoor(randomSmallDoor(random)) { + : StrongholdPiece(genDepth) { + entryDoor = randomSmallDoor(random); orientation = direction; boundingBox = stairsBox; @@ -1439,6 +1602,22 @@ StrongholdPieces::FiveCrossing::FiveCrossing(int genDepth, Random* random, 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( StructurePiece* startPiece, std::list* pieces, Random* random) { @@ -1544,6 +1723,10 @@ bool StrongholdPieces::FiveCrossing::postProcess(Level* level, Random* random, return true; } +StrongholdPieces::PortalRoom::PortalRoom() { + // for reflection +} + StrongholdPieces::PortalRoom::PortalRoom(int genDepth, Random* random, BoundingBox* box, int direction) : StrongholdPiece(genDepth) { @@ -1552,6 +1735,16 @@ StrongholdPieces::PortalRoom::PortalRoom(int genDepth, Random* random, 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( StructurePiece* startPiece, std::list* pieces, Random* random) { @@ -1629,8 +1822,7 @@ bool StrongholdPieces::PortalRoom::postProcess(Level* level, Random* random, } // stair - int orientationData = - getOrientationData(Tile::stairs_stoneBrickSmooth_Id, 3); + int orientationData = getOrientationData(Tile::stairs_stoneBrick_Id, 3); generateBox(level, chunkBB, 4, 1, 5, 6, 1, 7, false, random, (BlockSelector*)smoothStoneSelector); 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, (BlockSelector*)smoothStoneSelector); for (int x = 4; x <= 6; x++) { - placeBlock(level, Tile::stairs_stoneBrickSmooth_Id, orientationData, x, - 1, 4, chunkBB); - placeBlock(level, Tile::stairs_stoneBrickSmooth_Id, orientationData, x, - 2, 5, chunkBB); - placeBlock(level, Tile::stairs_stoneBrickSmooth_Id, orientationData, x, - 3, 6, chunkBB); + placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 1, 4, + chunkBB); + placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 2, 5, + chunkBB); + placeBlock(level, Tile::stairs_stoneBrick_Id, orientationData, x, 3, 6, + chunkBB); } int north = Direction::NORTH; @@ -1749,11 +1941,13 @@ bool StrongholdPieces::PortalRoom::postProcess(Level* level, Random* random, level->getLevelData()->setHasStrongholdEndPortal(); 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 entity = std::dynamic_pointer_cast( 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, bool isEdge) { if (isEdge) { - nextId = Tile::stoneBrickSmooth_Id; + nextId = Tile::stoneBrick_Id; float selection = random->nextFloat(); if (selection < 0.2f) { diff --git a/Minecraft.World/WorldGen/Structures/StrongholdPieces.h b/Minecraft.World/WorldGen/Structures/StrongholdPieces.h index 93f32faa7..1718d2db6 100644 --- a/Minecraft.World/WorldGen/Structures/StrongholdPieces.h +++ b/Minecraft.World/WorldGen/Structures/StrongholdPieces.h @@ -28,6 +28,10 @@ private: EPieceClass_PortalRoom }; +public: + static void loadStatic(); + +private: class PieceWeight { public: EPieceClass pieceClass; // 4J - was Class @@ -36,7 +40,6 @@ private: int maxPlaceCount; PieceWeight(EPieceClass pieceClass, int weight, int maxPlaceCount); - virtual ~PieceWeight() {} virtual bool doPlace(int depth); bool isValid(); }; @@ -94,8 +97,6 @@ private: private: class StrongholdPiece : public StructurePiece { protected: - StrongholdPiece(int genDepth); - enum SmallDoorType { OPENING, WOOD_DOOR, @@ -103,6 +104,17 @@ private: 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, BoundingBox* chunkBB, SmallDoorType doorType, int footX, int footY, int footZ); @@ -127,13 +139,25 @@ private: */ public: class FillerCorridor : public StrongholdPiece { + public: + static StructurePiece* Create() { return new FillerCorridor(); } + virtual EStructurePiece GetType() { + return eStructurePiece_FillerCorridor; + } + private: - const int steps; + int steps; public: + FillerCorridor(); FillerCorridor(int genDepth, Random* random, BoundingBox* corridorBox, int direction); + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: static BoundingBox* findPieceBox(std::list* pieces, Random* random, int footX, int footY, int footZ, int direction); @@ -147,19 +171,28 @@ public: */ public: class StairsDown : public StrongholdPiece { + public: + static StructurePiece* Create() { return new StairsDown(); } + virtual EStructurePiece GetType() { return eStructurePiece_StairsDown; } + private: static const int width = 5; static const int height = 11; static const int depth = 5; - const bool isSource; - const SmallDoorType entryDoor; + bool isSource; public: + StairsDown(); StairsDown(int genDepth, Random* random, int west, int north); StairsDown(int genDepth, Random* random, BoundingBox* stairsBox, int direction); + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: virtual void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); @@ -174,6 +207,11 @@ public: class PortalRoom; class StartPiece : public StairsDown { + public: + virtual EStructurePiece GetType() { + return eStructurePiece_StrongholdStartPiece; + } + public: bool isLibraryAdded; PieceWeight* previousPiece; @@ -184,6 +222,7 @@ public: // called in a random order std::vector pendingChildren; + StartPiece(); StartPiece(int genDepth, Random* random, int west, int north, Level* level); // 4J Added level param virtual TilePos* getLocatorPosition(); @@ -195,18 +234,28 @@ public: */ public: class Straight : public StrongholdPiece { + public: + static StructurePiece* Create() { return new Straight(); } + virtual EStructurePiece GetType() { return eStructurePiece_Straight; } + private: static const int width = 5; static const int height = 5; static const int depth = 7; - const SmallDoorType entryDoor; - const bool leftChild; - const bool rightChild; + bool leftChild; + bool rightChild; public: + Straight(); Straight(int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: virtual void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); @@ -223,19 +272,31 @@ public: */ class ChestCorridor : public StrongholdPiece { + public: + static StructurePiece* Create() { return new ChestCorridor(); } + virtual EStructurePiece GetType() { + return eStructurePiece_ChestCorridor; + } + private: static const int width = 5; static const int height = 5; 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]; - const SmallDoorType entryDoor; - boolean hasPlacedChest; + bool hasPlacedChest; public: + ChestCorridor(); ChestCorridor(int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: virtual void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); @@ -253,14 +314,19 @@ public: */ public: class StraightStairsDown : public StrongholdPiece { + public: + static StructurePiece* Create() { return new StraightStairsDown(); } + virtual EStructurePiece GetType() { + return eStructurePiece_StraightStairsDown; + } + private: static const int width = 5; static const int height = 11; static const int depth = 8; - const SmallDoorType entryDoor; - public: + StraightStairsDown(); StraightStairsDown(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -279,14 +345,17 @@ public: */ public: class LeftTurn : public StrongholdPiece { + public: + static StructurePiece* Create() { return new LeftTurn(); } + virtual EStructurePiece GetType() { return eStructurePiece_LeftTurn; } + protected: static const int width = 5; static const int height = 5; static const int depth = 5; - const SmallDoorType entryDoor; - public: + LeftTurn(); LeftTurn(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -306,6 +375,11 @@ public: public: class RightTurn : public LeftTurn { public: + static StructurePiece* Create() { return new RightTurn(); } + virtual EStructurePiece GetType() { return eStructurePiece_RightTurn; } + + public: + RightTurn(); RightTurn(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -321,6 +395,12 @@ public: */ public: class RoomCrossing : public StrongholdPiece { + public: + static StructurePiece* Create() { return new RoomCrossing(); } + virtual EStructurePiece GetType() { + return eStructurePiece_StrongholdRoomCrossing; + } + private: static const int SMALL_TREASURE_ITEMS_COUNT = 7; // 4J added static WeighedTreasure* smallTreasureItems[SMALL_TREASURE_ITEMS_COUNT]; @@ -331,12 +411,18 @@ public: static const int depth = 11; protected: - const SmallDoorType entryDoor; - const int type; + int type; public: + RoomCrossing(); RoomCrossing(int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: virtual void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); @@ -354,14 +440,17 @@ public: */ public: class PrisonHall : public StrongholdPiece { + public: + static StructurePiece* Create() { return new PrisonHall(); } + virtual EStructurePiece GetType() { return eStructurePiece_PrisonHall; } + protected: static const int width = 9; static const int height = 5; static const int depth = 11; - const SmallDoorType entryDoor; - public: + PrisonHall(); PrisonHall(int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, @@ -380,6 +469,10 @@ public: */ public: class Library : public StrongholdPiece { + public: + static StructurePiece* Create() { return new Library(); } + virtual EStructurePiece GetType() { return eStructurePiece_Library; } + private: static const int LIBRARY_TREASURE_ITEMS_COUNT = 4; // 4J added static WeighedTreasure* @@ -391,14 +484,19 @@ public: static const int tallHeight = 11; static const int depth = 15; - const SmallDoorType entryDoor; - private: - const bool isTall; + bool isTall; public: + Library(); Library(int genDepth, Random* random, BoundingBox* roomBox, int direction); + + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: static Library* createPiece(std::list* pieces, Random* random, int footX, int footY, int footZ, int direction, int genDepth); @@ -412,19 +510,30 @@ public: */ public: class FiveCrossing : public StrongholdPiece { + public: + static StructurePiece* Create() { return new FiveCrossing(); } + virtual EStructurePiece GetType() { + return eStructurePiece_FiveCrossing; + } + protected: static const int width = 10; static const int height = 9; static const int depth = 11; - const SmallDoorType entryDoor; - private: bool leftLow, leftHigh, rightLow, rightHigh; public: + FiveCrossing(); FiveCrossing(int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: virtual void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); @@ -442,6 +551,10 @@ public: */ class PortalRoom : public StrongholdPiece { + public: + static StructurePiece* Create() { return new PortalRoom(); } + virtual EStructurePiece GetType() { return eStructurePiece_PortalRoom; } + protected: static const int width = 11; static const int height = 8; @@ -451,8 +564,15 @@ public: bool hasPlacedMobSpawner; public: + PortalRoom(); PortalRoom(int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); static PortalRoom* createPiece(std::list* pieces, diff --git a/Minecraft.World/WorldGen/Structures/StructurePiece.cpp b/Minecraft.World/WorldGen/Structures/StructurePiece.cpp index b1de56e2b..06ed98963 100644 --- a/Minecraft.World/WorldGen/Structures/StructurePiece.cpp +++ b/Minecraft.World/WorldGen/Structures/StructurePiece.cpp @@ -1,4 +1,5 @@ #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.tile.h" #include "../../Headers/net.minecraft.world.level.material.h" @@ -41,6 +42,13 @@ * chunks, leading to infinite loops and other errors. */ +StructurePiece::StructurePiece() { + boundingBox = NULL; + orientation = 0; + genDepth = 0; + // for reflection +} + StructurePiece::StructurePiece(int genDepth) { boundingBox = NULL; this->genDepth = genDepth; @@ -51,6 +59,29 @@ StructurePiece::~StructurePiece() { 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, std::list* pieces, Random* random) {} @@ -172,10 +203,10 @@ int StructurePiece::getWorldZ(int x, int z) { int StructurePiece::getOrientationData(int tile, int data) { if (tile == Tile::rail->id) { if (orientation == Direction::WEST || orientation == Direction::EAST) { - if (data == RailTile::DIR_FLAT_X) { - return RailTile::DIR_FLAT_Z; + if (data == BaseRailTile::DIR_FLAT_X) { + return BaseRailTile::DIR_FLAT_Z; } else { - return RailTile::DIR_FLAT_X; + return BaseRailTile::DIR_FLAT_X; } } } 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 || tile == Tile::stairs_netherBricks_Id || - tile == Tile::stairs_stoneBrickSmooth_Id || + tile == Tile::stairs_stoneBrick_Id || tile == Tile::stairs_sandstone_Id) { if (orientation == Direction::SOUTH) { if (data == 2) { @@ -394,7 +425,8 @@ void StructurePiece::placeBlock(Level* level, int block, int data, int x, int y, // SuperFlat) 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) && worldY < Level::maxBuildHeight - 1) { - level->setTileAndDataNoUpdate(worldX, worldY, worldZ, 0, 0); + level->setTileAndData(worldX, worldY, worldZ, 0, 0, + Tile::UPDATE_CLIENTS); worldY++; } } @@ -608,7 +641,8 @@ void StructurePiece::fillColumnDown(Level* level, int tile, int tileData, int x, while ((level->isEmptyTile(worldX, worldY, worldZ) || level->getMaterial(worldX, worldY, worldZ)->isLiquid()) && worldY > 1) { - level->setTileAndDataNoUpdate(worldX, worldY, worldZ, tile, tileData); + level->setTileAndData(worldX, worldY, worldZ, tile, tileData, + Tile::UPDATE_CLIENTS); worldY--; } } @@ -622,7 +656,8 @@ bool StructurePiece::createChest(Level* level, BoundingBox* chunkBB, if (chunkBB->isInside(worldX, worldY, worldZ)) { 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 chest = std::dynamic_pointer_cast( 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) { level->setTileAndData( worldX, worldY, worldZ, Tile::dispenser_Id, - getOrientationData(Tile::dispenser_Id, facing)); + getOrientationData(Tile::dispenser_Id, facing), + Tile::UPDATE_CLIENTS); std::shared_ptr dispenser = std::dynamic_pointer_cast( level->getTileEntity(worldX, worldY, worldZ)); diff --git a/Minecraft.World/WorldGen/Structures/StructurePiece.h b/Minecraft.World/WorldGen/Structures/StructurePiece.h index 780035b52..100919a17 100644 --- a/Minecraft.World/WorldGen/Structures/StructurePiece.h +++ b/Minecraft.World/WorldGen/Structures/StructurePiece.h @@ -1,6 +1,7 @@ #pragma once #include "../../Util/WeighedRandom.h" #include "../../Util/BoundingBox.h" +#include "../StructureFeatureIO.h" class Level; class Random; @@ -38,6 +39,9 @@ class TilePos; * chunks, leading to infinite loops and other errors. */ class StructurePiece { +public: + virtual EStructurePiece GetType() = 0; + public: class BlockSelector { protected: @@ -60,11 +64,27 @@ protected: int orientation; int genDepth; +public: + StructurePiece(); + +protected: StructurePiece(int genDepth); public: virtual ~StructurePiece(); + virtual CompoundTag* createTag(); + +protected: + virtual void addAdditonalSaveData(CompoundTag* tag) = 0; + +public: + virtual void load(Level* level, CompoundTag* tag); + +protected: + virtual void readAdditonalSaveData(CompoundTag* tag) = 0; + +public: virtual void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); diff --git a/Minecraft.World/WorldGen/Structures/StructureStart.cpp b/Minecraft.World/WorldGen/Structures/StructureStart.cpp index 07845cc58..9bcb12777 100644 --- a/Minecraft.World/WorldGen/Structures/StructureStart.cpp +++ b/Minecraft.World/WorldGen/Structures/StructureStart.cpp @@ -1,13 +1,21 @@ #include "../../Platform/stdafx.h" #include "../../Headers/net.minecraft.world.level.h" +#include "../../Headers/net.minecraft.world.level.levelgen.structure.h" #include "StructureStart.h" #include "StructurePiece.h" #include "../../Util/BoundingBox.h" StructureStart::StructureStart() { + chunkX = chunkZ = 0; boundingBox = NULL; // 4J added initialiser } +StructureStart::StructureStart(int x, int z) { + this->chunkX = x; + this->chunkZ = z; + boundingBox = NULL; +} + StructureStart::~StructureStart() { for (AUTO_VAR(it, pieces.begin()); it != pieces.end(); it++) { delete (*it); @@ -44,6 +52,47 @@ void StructureStart::calculateBoundingBox() { } } +CompoundTag* StructureStart::createTag(int chunkX, int chunkZ) { + CompoundTag* tag = new CompoundTag(); + + tag->putString(L"id", StructureFeatureIO::getEncodeId(this)); + tag->putInt(L"ChunkX", chunkX); + tag->putInt(L"ChunkZ", chunkZ); + tag->put(L"BB", boundingBox->createTag(L"BB")); + + ListTag* childrenTags = new ListTag(L"Children"); + for (AUTO_VAR(it, pieces.begin()); it != pieces.end(); ++it) { + StructurePiece* piece = *it; + childrenTags->add(piece->createTag()); + } + tag->put(L"Children", childrenTags); + + addAdditonalSaveData(tag); + + return tag; +} + +void StructureStart::addAdditonalSaveData(CompoundTag* tag) {} + +void StructureStart::load(Level* level, CompoundTag* tag) { + chunkX = tag->getInt(L"ChunkX"); + chunkZ = tag->getInt(L"ChunkZ"); + if (tag->contains(L"BB")) { + boundingBox = new BoundingBox(tag->getIntArray(L"BB")); + } + + ListTag* children = + (ListTag*)tag->getList(L"Children"); + for (int i = 0; i < children->size(); i++) { + pieces.push_back( + StructureFeatureIO::loadStaticPiece(children->get(i), level)); + } + + readAdditonalSaveData(tag); +} + +void StructureStart::readAdditonalSaveData(CompoundTag* tag) {} + void StructureStart::moveBelowSeaLevel(Level* level, Random* random, int offset) { const int MAX_Y = level->seaLevel - offset; @@ -85,4 +134,8 @@ void StructureStart::moveInsideHeights(Level* level, Random* random, } } -bool StructureStart::isValid() { return true; } \ No newline at end of file +bool StructureStart::isValid() { return true; } + +int StructureStart::getChunkX() { return chunkX; } + +int StructureStart::getChunkZ() { return chunkZ; } \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Structures/StructureStart.h b/Minecraft.World/WorldGen/Structures/StructureStart.h index f9afa5aba..b1f1cfbbb 100644 --- a/Minecraft.World/WorldGen/Structures/StructureStart.h +++ b/Minecraft.World/WorldGen/Structures/StructureStart.h @@ -2,14 +2,21 @@ class StructurePiece; class BoundingBox; +#include "../StructureFeatureIO.h" + class StructureStart { -protected: +public: std::list pieces; + +protected: BoundingBox* boundingBox; - StructureStart(); +private: + int chunkX, chunkZ; public: + StructureStart(); + StructureStart(int x, int z); ~StructureStart(); BoundingBox* getBoundingBox(); std::list* getPieces(); @@ -17,10 +24,22 @@ public: protected: void calculateBoundingBox(); + +public: + virtual CompoundTag* createTag(int chunkX, int chunkZ); + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void load(Level* level, CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + +protected: void moveBelowSeaLevel(Level* level, Random* random, int offset); void moveInsideHeights(Level* level, Random* random, int lowestAllowed, int highestAllowed); public: bool isValid(); + int getChunkX(); + int getChunkZ(); + + virtual EStructureStart GetType() = 0; }; diff --git a/Minecraft.World/WorldGen/Structures/TheEndBiomeDecorator.cpp b/Minecraft.World/WorldGen/Structures/TheEndBiomeDecorator.cpp index 376985870..c7baf035d 100644 --- a/Minecraft.World/WorldGen/Structures/TheEndBiomeDecorator.cpp +++ b/Minecraft.World/WorldGen/Structures/TheEndBiomeDecorator.cpp @@ -31,8 +31,8 @@ TheEndBiomeDecorator::SPIKE TheEndBiomeDecorator::SpikeValA[8] = { TheEndBiomeDecorator::TheEndBiomeDecorator(Biome* biome) : BiomeDecorator(biome) { - spikeFeature = new SpikeFeature(Tile::whiteStone_Id); - endPodiumFeature = new EndPodiumFeature(Tile::whiteStone_Id); + spikeFeature = new SpikeFeature(Tile::endStone_Id); + endPodiumFeature = new EndPodiumFeature(Tile::endStone_Id); } void TheEndBiomeDecorator::decorate() { @@ -56,6 +56,7 @@ void TheEndBiomeDecorator::decorate() { if (xo == 0 && zo == 0) { std::shared_ptr enderDragon = std::shared_ptr(new EnderDragon(level)); + enderDragon->AddParts(); // 4J added enderDragon->moveTo(0, 128, 0, random->nextFloat() * 360, 0); level->addEntity(enderDragon); } @@ -64,6 +65,6 @@ void TheEndBiomeDecorator::decorate() { // one since this guarantees that all chunks required for the podium are // loaded if (xo == -16 && zo == -16) { - endPodiumFeature->place(level, random, 0, Level::genDepth / 2, 0); + endPodiumFeature->place(level, random, 0, level->seaLevel, 0); } } \ No newline at end of file diff --git a/Minecraft.World/WorldGen/Structures/Village.cpp b/Minecraft.World/WorldGen/Structures/Village.cpp index 737a7b498..a5ef99fe9 100644 --- a/Minecraft.World/WorldGen/Structures/Village.cpp +++ b/Minecraft.World/WorldGen/Structures/Village.cpp @@ -8,7 +8,8 @@ #include "../../Util/BasicTypeContainers.h" #include "Village.h" -Village::Aggressor::Aggressor(std::shared_ptr mob, int timeStamp) { +Village::Aggressor::Aggressor(std::shared_ptr mob, + int timeStamp) { this->mob = mob; this->timeStamp = timeStamp; } @@ -217,7 +218,7 @@ void Village::addDoorInfo(std::shared_ptr di) { bool Village::canRemove() { return doorInfos.empty(); } -void Village::addAggressor(std::shared_ptr mob) { +void Village::addAggressor(std::shared_ptr mob) { // for (Aggressor a : aggressors) for (AUTO_VAR(it, aggressors.begin()); it != aggressors.end(); ++it) { Aggressor* a = *it; @@ -229,7 +230,8 @@ void Village::addAggressor(std::shared_ptr mob) { aggressors.push_back(new Aggressor(mob, _tick)); } -std::shared_ptr Village::getClosestAggressor(std::shared_ptr from) { +std::shared_ptr Village::getClosestAggressor( + std::shared_ptr from) { double closestSqr = Double::MAX_VALUE; Aggressor* closest = NULL; // for (int i = 0; i < aggressors.size(); ++i) @@ -244,9 +246,7 @@ std::shared_ptr Village::getClosestAggressor(std::shared_ptr from) { } std::shared_ptr Village::getClosestBadStandingPlayer( - std::shared_ptr - from) // 4J Stu - Should be LivingEntity when we add that -{ + std::shared_ptr from) { double closestSqr = Double::MAX_VALUE; std::shared_ptr closest = nullptr; diff --git a/Minecraft.World/WorldGen/Structures/Village.h b/Minecraft.World/WorldGen/Structures/Village.h index 697afaed4..fb35335f7 100644 --- a/Minecraft.World/WorldGen/Structures/Village.h +++ b/Minecraft.World/WorldGen/Structures/Village.h @@ -17,10 +17,10 @@ private: class Aggressor { public: - std::shared_ptr mob; + std::shared_ptr mob; int timeStamp; - Aggressor(std::shared_ptr mob, int timeStamp); + Aggressor(std::shared_ptr mob, int timeStamp); }; std::vector aggressors; @@ -55,11 +55,11 @@ public: std::shared_ptr getDoorInfo(int x, int y, int z); void addDoorInfo(std::shared_ptr di); bool canRemove(); - void addAggressor(std::shared_ptr mob); - std::shared_ptr getClosestAggressor(std::shared_ptr from); + void addAggressor(std::shared_ptr mob); + std::shared_ptr getClosestAggressor( + std::shared_ptr from); std::shared_ptr getClosestBadStandingPlayer( - std::shared_ptr - from); // 4J Stu - Should be LivingEntity when we add that + std::shared_ptr from); private: void updateAggressors(); diff --git a/Minecraft.World/WorldGen/Structures/VillagePieces.cpp b/Minecraft.World/WorldGen/Structures/VillagePieces.cpp index b6bbdf711..d1b4fefdf 100644 --- a/Minecraft.World/WorldGen/Structures/VillagePieces.cpp +++ b/Minecraft.World/WorldGen/Structures/VillagePieces.cpp @@ -4,6 +4,7 @@ #include "../../Headers/net.minecraft.world.level.storage.h" #include "../../Headers/net.minecraft.world.level.tile.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.level.dimension.h" #include "../../Headers/net.minecraft.world.entity.npc.h" @@ -16,6 +17,34 @@ WeighedTreasureArray VillagePieces::Smithy::treasureItems; +void VillagePieces::loadStatic() { + StructureFeatureIO::setPieceId(eStructurePiece_BookHouse, BookHouse::Create, + L"ViBH"); + StructureFeatureIO::setPieceId(eStructurePiece_DoubleFarmland, + DoubleFarmland::Create, L"ViDF"); + StructureFeatureIO::setPieceId(eStructurePiece_Farmland, Farmland::Create, + L"ViF"); + StructureFeatureIO::setPieceId(eStructurePiece_LightPost, LightPost::Create, + L"ViL"); + StructureFeatureIO::setPieceId(eStructurePiece_PigHouse, PigHouse::Create, + L"ViPH"); + StructureFeatureIO::setPieceId(eStructurePiece_SimpleHouse, + SimpleHouse::Create, L"ViSH"); + StructureFeatureIO::setPieceId(eStructurePiece_SmallHut, SmallHut::Create, + L"ViSmH"); + StructureFeatureIO::setPieceId(eStructurePiece_SmallTemple, + SmallTemple::Create, L"ViST"); + StructureFeatureIO::setPieceId(eStructurePiece_Smithy, Smithy::Create, + L"ViS"); + StructureFeatureIO::setPieceId(eStructurePiece_VillageStartPiece, + StartPiece::Create, L"ViStart"); + StructureFeatureIO::setPieceId(eStructurePiece_StraightRoad, + StraightRoad::Create, L"ViSR"); + StructureFeatureIO::setPieceId(eStructurePiece_TwoRoomHouse, + TwoRoomHouse::Create, L"ViTRH"); + StructureFeatureIO::setPieceId(eStructurePiece_Well, Well::Create, L"ViW"); +} + VillagePieces::PieceWeight::PieceWeight(VillagePieces::EPieceClass pieceClass, int weight, int maxPlaceCount) : weight(weight) { @@ -251,10 +280,35 @@ StructurePiece* VillagePieces::generateAndAddRoadPiece( return NULL; } +VillagePieces::VillagePiece::VillagePiece() { + heightPosition = -1; + spawnedVillagerCount = 0; + isDesertVillage = false; + startPiece = NULL; + // for reflection +} + VillagePieces::VillagePiece::VillagePiece(StartPiece* startPiece, int genDepth) : StructurePiece(genDepth) { + heightPosition = -1; + isDesertVillage = false; spawnedVillagerCount = 0; this->startPiece = startPiece; + if (startPiece != NULL) { + this->isDesertVillage = startPiece->isDesertVillage; + } +} + +void VillagePieces::VillagePiece::addAdditonalSaveData(CompoundTag* tag) { + tag->putInt(L"HPos", heightPosition); + tag->putInt(L"VCount", spawnedVillagerCount); + tag->putBoolean(L"Desert", isDesertVillage); +} + +void VillagePieces::VillagePiece::readAdditonalSaveData(CompoundTag* tag) { + heightPosition = tag->getInt(L"HPos"); + spawnedVillagerCount = tag->getInt(L"VCount"); + isDesertVillage = tag->getBoolean(L"Desert"); } StructurePiece* VillagePieces::VillagePiece::generateHouseNorthernLeft( @@ -384,10 +438,10 @@ int VillagePieces::VillagePiece::getVillagerProfession(int villagerNumber) { } int VillagePieces::VillagePiece::biomeBlock(int tile, int data) { - if (startPiece->isDesertVillage) { + if (isDesertVillage) { if (tile == Tile::treeTrunk_Id) { return Tile::sandStone_Id; - } else if (tile == Tile::stoneBrick_Id) { + } else if (tile == Tile::cobblestone_Id) { return Tile::sandStone_Id; } else if (tile == Tile::wood_Id) { return Tile::sandStone_Id; @@ -403,10 +457,10 @@ int VillagePieces::VillagePiece::biomeBlock(int tile, int data) { } int VillagePieces::VillagePiece::biomeData(int tile, int data) { - if (startPiece->isDesertVillage) { + if (isDesertVillage) { if (tile == Tile::treeTrunk_Id) { return 0; - } else if (tile == Tile::stoneBrick_Id) { + } else if (tile == Tile::cobblestone_Id) { return SandStoneTile::TYPE_DEFAULT; } else if (tile == Tile::wood_Id) { return SandStoneTile::TYPE_SMOOTHSIDE; @@ -444,10 +498,13 @@ void VillagePieces::VillagePiece::fillColumnDown(Level* level, int block, StructurePiece::fillColumnDown(level, bblock, bdata, x, startY, z, chunkBB); } +VillagePieces::Well::Well() { + // for reflection +} + VillagePieces::Well::Well(StartPiece* startPiece, int genDepth, Random* random, int west, int north) - : VillagePiece(startPiece, genDepth), isSource(true) { - heightPosition = -1; // 4J added initialiser + : VillagePiece(startPiece, genDepth) { orientation = random->nextInt(4); switch (orientation) { @@ -465,9 +522,7 @@ VillagePieces::Well::Well(StartPiece* startPiece, int genDepth, Random* random, VillagePieces::Well::Well(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction) - : VillagePiece(startPiece, genDepth), isSource(false) { - heightPosition = -1; // 4J added initialiser - + : VillagePiece(startPiece, genDepth) { orientation = direction; boundingBox = stairsBox; } @@ -493,23 +548,6 @@ void VillagePieces::Well::addChildren(StructurePiece* startPiece, getGenDepth()); } -// VillagePieces::Well -// *VillagePieces::Well::createPiece(std::list *pieces, Random -// *random, int footX, int footY, int footZ, int direction, int genDepth) -//{ -// BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, -1, 4 - -// height, 0, width, height, depth, direction); -// -// if (!isOkBox(box) || StructurePiece::findCollisionPiece(pieces, box) != -// NULL) -// { -// delete box; -// return NULL; -// } -// -// return new Well(genDepth, random, box, direction); -// } - bool VillagePieces::Well::postProcess(Level* level, Random* random, BoundingBox* chunkBB) { if (heightPosition < 0) { @@ -520,7 +558,7 @@ bool VillagePieces::Well::postProcess(Level* level, Random* random, boundingBox->move(0, heightPosition - boundingBox->y1 + 3, 0); } - generateBox(level, chunkBB, 1, 0, 1, 4, height - 3, 4, Tile::stoneBrick_Id, + generateBox(level, chunkBB, 1, 0, 1, 4, height - 3, 4, Tile::cobblestone_Id, Tile::water_Id, false); placeBlock(level, 0, 0, 2, height - 3, 2, chunkBB); placeBlock(level, 0, 0, 3, height - 3, 2, chunkBB); @@ -535,8 +573,8 @@ bool VillagePieces::Well::postProcess(Level* level, Random* random, placeBlock(level, Tile::fence_Id, 0, 1, height - 1, 4, chunkBB); placeBlock(level, Tile::fence_Id, 0, 4, height - 2, 4, chunkBB); placeBlock(level, Tile::fence_Id, 0, 4, height - 1, 4, chunkBB); - generateBox(level, chunkBB, 1, height, 1, 4, height, 4, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 1, height, 1, 4, height, 4, + Tile::cobblestone_Id, Tile::cobblestone_Id, false); for (int z = 0; z <= 5; z++) { for (int x = 0; x <= 5; x++) { @@ -552,6 +590,10 @@ bool VillagePieces::Well::postProcess(Level* level, Random* random, return true; } +VillagePieces::StartPiece::StartPiece() { + // for reflection +} + VillagePieces::StartPiece::StartPiece(BiomeSource* biomeSource, int genDepth, Random* random, int west, int north, std::list* pieceSet, @@ -565,9 +607,7 @@ VillagePieces::StartPiece::StartPiece(BiomeSource* biomeSource, int genDepth, m_level = level; Biome* biome = biomeSource->getBiome(west, north); - this->isDesertVillage = - biome == Biome::desert || biome == Biome::desertHills; - this->startPiece = this; + isDesertVillage = biome == Biome::desert || biome == Biome::desertHills; } VillagePieces::StartPiece::~StartPiece() { @@ -579,6 +619,10 @@ VillagePieces::StartPiece::~StartPiece() { BiomeSource* VillagePieces::StartPiece::getBiomeSource() { return biomeSource; } +VillagePieces::StraightRoad::StraightRoad() { + // for reflection +} + VillagePieces::StraightRoad::StraightRoad(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction) @@ -588,6 +632,16 @@ VillagePieces::StraightRoad::StraightRoad(StartPiece* startPiece, int genDepth, length = Math::_max(stairsBox->getXSpan(), stairsBox->getZSpan()); } +void VillagePieces::StraightRoad::addAdditonalSaveData(CompoundTag* tag) { + VillageRoadPiece::addAdditonalSaveData(tag); + tag->putInt(L"Length", length); +} + +void VillagePieces::StraightRoad::readAdditonalSaveData(CompoundTag* tag) { + VillageRoadPiece::readAdditonalSaveData(tag); + length = tag->getInt(L"Length"); +} + void VillagePieces::StraightRoad::addChildren( StructurePiece* startPiece, std::list* pieces, Random* random) { @@ -704,7 +758,7 @@ bool VillagePieces::StraightRoad::postProcess(Level* level, Random* random, for (int z = boundingBox->z0; z <= boundingBox->z1; z++) { if (chunkBB->isInside(x, 64, z)) { int y = level->getTopSolidBlock(x, z) - 1; - level->setTileNoUpdate(x, y, z, tile); + level->setTileAndData(x, y, z, tile, 0, Tile::UPDATE_CLIENTS); } } } @@ -712,19 +766,29 @@ bool VillagePieces::StraightRoad::postProcess(Level* level, Random* random, return true; } -/* -int heightPosition; -const bool hasTerrace;*/ +VillagePieces::SimpleHouse::SimpleHouse() { + hasTerrace = false; + // for reflection +} VillagePieces::SimpleHouse::SimpleHouse(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction) : VillagePiece(startPiece, genDepth), hasTerrace(random->nextBoolean()) { - heightPosition = -1; // 4J added initialiser orientation = direction; boundingBox = stairsBox; } +void VillagePieces::SimpleHouse::addAdditonalSaveData(CompoundTag* tag) { + VillagePiece::addAdditonalSaveData(tag); + tag->putBoolean(L"Terrace", hasTerrace); +} + +void VillagePieces::SimpleHouse::readAdditonalSaveData(CompoundTag* tag) { + VillagePiece::readAdditonalSaveData(tag); + hasTerrace = tag->getBoolean(L"Terrace"); +} + VillagePieces::SimpleHouse* VillagePieces::SimpleHouse::createPiece( StartPiece* startPiece, std::list* pieces, Random* random, int footX, int footY, int footZ, int direction, int genDepth) { @@ -751,8 +815,8 @@ bool VillagePieces::SimpleHouse::postProcess(Level* level, Random* random, } // floor - generateBox(level, chunkBB, 0, 0, 0, 4, 0, 4, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 4, 0, 4, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // roof generateBox(level, chunkBB, 0, 4, 0, 4, 4, 4, Tile::treeTrunk_Id, Tile::treeTrunk_Id, false); @@ -760,18 +824,18 @@ bool VillagePieces::SimpleHouse::postProcess(Level* level, Random* random, false); // window walls - placeBlock(level, Tile::stoneBrick_Id, 0, 0, 1, 0, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 0, 2, 0, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 0, 3, 0, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 1, 0, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 2, 0, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 3, 0, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 0, 1, 4, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 0, 2, 4, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 0, 3, 4, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 1, 4, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 2, 4, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 3, 4, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 0, 1, 0, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 0, 2, 0, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 0, 3, 0, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, 1, 0, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, 2, 0, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, 3, 0, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 0, 1, 4, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 0, 2, 4, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 0, 3, 4, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, 1, 4, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, 2, 4, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, 3, 4, chunkBB); generateBox(level, chunkBB, 0, 1, 1, 0, 3, 3, Tile::wood_Id, Tile::wood_Id, false); generateBox(level, chunkBB, 4, 1, 1, 4, 3, 3, Tile::wood_Id, Tile::wood_Id, @@ -835,7 +899,7 @@ bool VillagePieces::SimpleHouse::postProcess(Level* level, Random* random, for (int z = 0; z < depth; z++) { for (int x = 0; x < width; x++) { generateAirColumnUp(level, x, height, z, chunkBB); - fillColumnDown(level, Tile::stoneBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::cobblestone_Id, 0, x, -1, z, chunkBB); } } @@ -844,6 +908,10 @@ bool VillagePieces::SimpleHouse::postProcess(Level* level, Random* random, return true; } +VillagePieces::SmallTemple::SmallTemple() { + // for reflection +} + VillagePieces::SmallTemple::SmallTemple(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction) @@ -883,51 +951,51 @@ bool VillagePieces::SmallTemple::postProcess(Level* level, Random* random, generateBox(level, chunkBB, 1, 5, 1, 3, 9, 3, 0, 0, false); // floor - generateBox(level, chunkBB, 1, 0, 0, 3, 0, 8, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 1, 0, 0, 3, 0, 8, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // front wall - generateBox(level, chunkBB, 1, 1, 0, 3, 10, 0, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 1, 1, 0, 3, 10, 0, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // left tall wall - generateBox(level, chunkBB, 0, 1, 1, 0, 10, 3, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 1, 1, 0, 10, 3, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // right tall wall - generateBox(level, chunkBB, 4, 1, 1, 4, 10, 3, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 4, 1, 1, 4, 10, 3, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // left low wall - generateBox(level, chunkBB, 0, 0, 4, 0, 4, 7, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 4, 0, 4, 7, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // right low wall - generateBox(level, chunkBB, 4, 0, 4, 4, 4, 7, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 4, 0, 4, 4, 4, 7, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // far low wall - generateBox(level, chunkBB, 1, 1, 8, 3, 4, 8, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 1, 1, 8, 3, 4, 8, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // far upper wall - generateBox(level, chunkBB, 1, 5, 4, 3, 10, 4, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 1, 5, 4, 3, 10, 4, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // low roof - generateBox(level, chunkBB, 1, 5, 5, 3, 5, 7, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 1, 5, 5, 3, 5, 7, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // high roof - generateBox(level, chunkBB, 0, 9, 0, 4, 9, 4, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 9, 0, 4, 9, 4, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // middle floor / roof - generateBox(level, chunkBB, 0, 4, 0, 4, 4, 4, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - placeBlock(level, Tile::stoneBrick_Id, 0, 0, 11, 2, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 4, 11, 2, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 2, 11, 0, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 2, 11, 4, chunkBB); + generateBox(level, chunkBB, 0, 4, 0, 4, 4, 4, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + placeBlock(level, Tile::cobblestone_Id, 0, 0, 11, 2, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 4, 11, 2, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 2, 11, 0, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 2, 11, 4, chunkBB); // altar pieces - placeBlock(level, Tile::stoneBrick_Id, 0, 1, 1, 6, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 1, 1, 7, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 2, 1, 7, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 3, 1, 6, chunkBB); - placeBlock(level, Tile::stoneBrick_Id, 0, 3, 1, 7, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 1, 1, 6, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 1, 1, 7, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 2, 1, 7, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 3, 1, 6, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 3, 1, 7, chunkBB); placeBlock(level, Tile::stairs_stone_Id, getOrientationData(Tile::stairs_stone_Id, 3), 1, 1, 5, chunkBB); placeBlock(level, Tile::stairs_stone_Id, @@ -983,7 +1051,7 @@ bool VillagePieces::SmallTemple::postProcess(Level* level, Random* random, for (int z = 0; z < depth; z++) { for (int x = 0; x < width; x++) { generateAirColumnUp(level, x, height, z, chunkBB); - fillColumnDown(level, Tile::stoneBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::cobblestone_Id, 0, x, -1, z, chunkBB); } } @@ -996,6 +1064,10 @@ int VillagePieces::SmallTemple::getVillagerProfession(int villagerNumber) { return Villager::PROFESSION_PRIEST; } +VillagePieces::BookHouse::BookHouse() { + // for reflection +} + VillagePieces::BookHouse::BookHouse(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction) @@ -1034,15 +1106,15 @@ bool VillagePieces::BookHouse::postProcess(Level* level, Random* random, generateBox(level, chunkBB, 1, 1, 1, 7, 5, 4, 0, 0, false); // floor - generateBox(level, chunkBB, 0, 0, 0, 8, 0, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 8, 0, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // roof - generateBox(level, chunkBB, 0, 5, 0, 8, 5, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 0, 6, 1, 8, 6, 4, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 0, 7, 2, 8, 7, 3, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 5, 0, 8, 5, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 0, 6, 1, 8, 6, 4, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 0, 7, 2, 8, 7, 3, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); int southStairs = getOrientationData(Tile::stairs_wood_Id, 3); int northStairs = getOrientationData(Tile::stairs_wood_Id, 2); for (int d = -1; d <= 2; d++) { @@ -1055,22 +1127,22 @@ bool VillagePieces::BookHouse::postProcess(Level* level, Random* random, } // rock supports - generateBox(level, chunkBB, 0, 1, 0, 0, 1, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 1, 1, 5, 8, 1, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 8, 1, 0, 8, 1, 4, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 2, 1, 0, 7, 1, 0, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 0, 2, 0, 0, 4, 0, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 0, 2, 5, 0, 4, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 8, 2, 5, 8, 4, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 8, 2, 0, 8, 4, 0, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 1, 0, 0, 1, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 1, 1, 5, 8, 1, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 8, 1, 0, 8, 1, 4, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 2, 1, 0, 7, 1, 0, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 0, 2, 0, 0, 4, 0, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 0, 2, 5, 0, 4, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 8, 2, 5, 8, 4, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 8, 2, 0, 8, 4, 0, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // wooden walls generateBox(level, chunkBB, 0, 2, 1, 0, 4, 4, Tile::wood_Id, Tile::wood_Id, @@ -1142,7 +1214,7 @@ bool VillagePieces::BookHouse::postProcess(Level* level, Random* random, for (int z = 0; z < depth; z++) { for (int x = 0; x < width; x++) { generateAirColumnUp(level, x, height, z, chunkBB); - fillColumnDown(level, Tile::stoneBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::cobblestone_Id, 0, x, -1, z, chunkBB); } } @@ -1155,6 +1227,10 @@ int VillagePieces::BookHouse::getVillagerProfession(int villagerNumber) { return Villager::PROFESSION_LIBRARIAN; } +VillagePieces::SmallHut::SmallHut() { + // for reflection +} + VillagePieces::SmallHut::SmallHut(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction) @@ -1167,6 +1243,18 @@ VillagePieces::SmallHut::SmallHut(StartPiece* startPiece, int genDepth, boundingBox = stairsBox; } +void VillagePieces::SmallHut::addAdditonalSaveData(CompoundTag* tag) { + VillagePiece::addAdditonalSaveData(tag); + tag->putInt(L"T", tablePlacement); + tag->putBoolean(L"C", lowCeiling); +} + +void VillagePieces::SmallHut::readAdditonalSaveData(CompoundTag* tag) { + VillagePiece::readAdditonalSaveData(tag); + tablePlacement = tag->getInt(L"T"); + lowCeiling = tag->getBoolean(L"C"); +} + VillagePieces::SmallHut* VillagePieces::SmallHut::createPiece( StartPiece* startPiece, std::list* pieces, Random* random, int footX, int footY, int footZ, int direction, int genDepth) { @@ -1196,8 +1284,8 @@ bool VillagePieces::SmallHut::postProcess(Level* level, Random* random, generateBox(level, chunkBB, 1, 1, 1, 3, 5, 4, 0, 0, false); // floor - generateBox(level, chunkBB, 0, 0, 0, 3, 0, 4, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 3, 0, 4, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); generateBox(level, chunkBB, 1, 0, 1, 2, 0, 3, Tile::dirt_Id, Tile::dirt_Id, false); // roof @@ -1265,7 +1353,7 @@ bool VillagePieces::SmallHut::postProcess(Level* level, Random* random, for (int z = 0; z < depth; z++) { for (int x = 0; x < width; x++) { generateAirColumnUp(level, x, height, z, chunkBB); - fillColumnDown(level, Tile::stoneBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::cobblestone_Id, 0, x, -1, z, chunkBB); } } @@ -1274,11 +1362,14 @@ bool VillagePieces::SmallHut::postProcess(Level* level, Random* random, return true; } +VillagePieces::PigHouse::PigHouse() { + // for reflection +} + VillagePieces::PigHouse::PigHouse(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction) : VillagePiece(startPiece, genDepth) { - heightPosition = -1; // 4J added initialiser orientation = direction; boundingBox = stairsBox; } @@ -1315,7 +1406,7 @@ bool VillagePieces::PigHouse::postProcess(Level* level, Random* random, // pig floor generateBox(level, chunkBB, 2, 0, 6, 8, 0, 10, Tile::dirt_Id, Tile::dirt_Id, false); - placeBlock(level, Tile::stoneBrick_Id, 0, 6, 0, 6, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 6, 0, 6, chunkBB); // pig fence generateBox(level, chunkBB, 2, 1, 6, 2, 1, 10, Tile::fence_Id, Tile::fence_Id, false); @@ -1327,14 +1418,14 @@ bool VillagePieces::PigHouse::postProcess(Level* level, Random* random, // floor generateBox(level, chunkBB, 1, 0, 1, 7, 0, 4, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 0, 0, 0, 0, 3, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 8, 0, 0, 8, 3, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 1, 0, 0, 7, 1, 0, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 1, 0, 5, 7, 1, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 0, 3, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 8, 0, 0, 8, 3, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 1, 0, 0, 7, 1, 0, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 1, 0, 5, 7, 1, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // roof generateBox(level, chunkBB, 1, 2, 0, 7, 3, 0, Tile::wood_Id, Tile::wood_Id, @@ -1415,7 +1506,7 @@ bool VillagePieces::PigHouse::postProcess(Level* level, Random* random, for (int z = 0; z < 5; z++) { for (int x = 0; x < width; x++) { generateAirColumnUp(level, x, height, z, chunkBB); - fillColumnDown(level, Tile::stoneBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::cobblestone_Id, 0, x, -1, z, chunkBB); } } @@ -1431,6 +1522,10 @@ int VillagePieces::PigHouse::getVillagerProfession(int villagerNumber) { return Villager::PROFESSION_FARMER; } +VillagePieces::TwoRoomHouse::TwoRoomHouse() { + // for reflection +} + VillagePieces::TwoRoomHouse::TwoRoomHouse(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction) @@ -1475,18 +1570,18 @@ bool VillagePieces::TwoRoomHouse::postProcess(Level* level, Random* random, false); generateBox(level, chunkBB, 1, 0, 1, 7, 0, 4, Tile::wood_Id, Tile::wood_Id, false); - generateBox(level, chunkBB, 0, 0, 0, 0, 3, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 8, 0, 0, 8, 3, 10, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 1, 0, 0, 7, 2, 0, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 1, 0, 5, 2, 1, 5, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 2, 0, 6, 2, 3, 10, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); - generateBox(level, chunkBB, 3, 0, 10, 7, 3, 10, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 0, 3, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 8, 0, 0, 8, 3, 10, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 1, 0, 0, 7, 2, 0, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 1, 0, 5, 2, 1, 5, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 2, 0, 6, 2, 3, 10, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); + generateBox(level, chunkBB, 3, 0, 10, 7, 3, 10, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // room 1 roof generateBox(level, chunkBB, 1, 2, 0, 7, 3, 0, Tile::wood_Id, Tile::wood_Id, @@ -1595,13 +1690,13 @@ bool VillagePieces::TwoRoomHouse::postProcess(Level* level, Random* random, for (int z = 0; z < 5; z++) { for (int x = 0; x < width; x++) { generateAirColumnUp(level, x, height, z, chunkBB); - fillColumnDown(level, Tile::stoneBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::cobblestone_Id, 0, x, -1, z, chunkBB); } } for (int z = 5; z < depth - 1; z++) { for (int x = 2; x < width; x++) { generateAirColumnUp(level, x, height, z, chunkBB); - fillColumnDown(level, Tile::stoneBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::cobblestone_Id, 0, x, -1, z, chunkBB); } } @@ -1611,7 +1706,7 @@ bool VillagePieces::TwoRoomHouse::postProcess(Level* level, Random* random, } void VillagePieces::Smithy::staticCtor() { - treasureItems = WeighedTreasureArray(13); + treasureItems = WeighedTreasureArray(17); treasureItems[0] = new WeighedTreasure(Item::diamond_Id, 0, 1, 3, 3); treasureItems[1] = new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10); treasureItems[2] = new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5); @@ -1626,13 +1721,25 @@ void VillagePieces::Smithy::staticCtor() { treasureItems[10] = new WeighedTreasure(Item::boots_iron_Id, 0, 1, 1, 5); treasureItems[11] = new WeighedTreasure(Tile::obsidian_Id, 0, 3, 7, 5); treasureItems[12] = new WeighedTreasure(Tile::sapling_Id, 0, 3, 7, 5); + // very rare for villages ... + treasureItems[13] = new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 3); + treasureItems[14] = + new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1); + treasureItems[15] = + new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 1); + treasureItems[16] = + new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1); + // ... +} + +VillagePieces::Smithy::Smithy() { + // for reflection } VillagePieces::Smithy::Smithy(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction) : VillagePiece(startPiece, genDepth) { - heightPosition = -1; // 4J added initialiser hasPlacedChest = false; orientation = direction; @@ -1654,6 +1761,16 @@ VillagePieces::Smithy* VillagePieces::Smithy::createPiece( return new Smithy(startPiece, genDepth, random, box, direction); } +void VillagePieces::Smithy::addAdditonalSaveData(CompoundTag* tag) { + VillagePiece::addAdditonalSaveData(tag); + tag->putBoolean(L"Chest", hasPlacedChest); +} + +void VillagePieces::Smithy::readAdditonalSaveData(CompoundTag* tag) { + VillagePiece::readAdditonalSaveData(tag); + hasPlacedChest = tag->getBoolean(L"Chest"); +} + bool VillagePieces::Smithy::postProcess(Level* level, Random* random, BoundingBox* chunkBB) { if (heightPosition < 0) { @@ -1668,12 +1785,12 @@ bool VillagePieces::Smithy::postProcess(Level* level, Random* random, generateBox(level, chunkBB, 0, 1, 0, 9, 4, 6, 0, 0, false); // floor - generateBox(level, chunkBB, 0, 0, 0, 9, 0, 6, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 0, 0, 9, 0, 6, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); // roof - generateBox(level, chunkBB, 0, 4, 0, 9, 4, 6, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 0, 4, 0, 9, 4, 6, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); generateBox(level, chunkBB, 0, 5, 0, 9, 5, 6, Tile::stoneSlabHalf_Id, Tile::stoneSlabHalf_Id, false); generateBox(level, chunkBB, 1, 5, 1, 8, 5, 5, 0, 0, false); @@ -1704,14 +1821,14 @@ bool VillagePieces::Smithy::postProcess(Level* level, Random* random, Tile::fence_Id, false); // furnace - generateBox(level, chunkBB, 6, 1, 4, 9, 4, 6, Tile::stoneBrick_Id, - Tile::stoneBrick_Id, false); + generateBox(level, chunkBB, 6, 1, 4, 9, 4, 6, Tile::cobblestone_Id, + Tile::cobblestone_Id, false); placeBlock(level, Tile::lava_Id, 0, 7, 1, 5, chunkBB); placeBlock(level, Tile::lava_Id, 0, 8, 1, 5, chunkBB); placeBlock(level, Tile::ironFence_Id, 0, 9, 2, 5, chunkBB); placeBlock(level, Tile::ironFence_Id, 0, 9, 2, 4, chunkBB); generateBox(level, chunkBB, 7, 2, 4, 8, 2, 5, 0, 0, false); - placeBlock(level, Tile::stoneBrick_Id, 0, 6, 1, 3, chunkBB); + placeBlock(level, Tile::cobblestone_Id, 0, 6, 1, 3, chunkBB); placeBlock(level, Tile::furnace_Id, 0, 6, 2, 3, chunkBB); placeBlock(level, Tile::furnace_Id, 0, 6, 3, 3, chunkBB); placeBlock(level, Tile::stoneSlab_Id, 0, 8, 1, 1, chunkBB); @@ -1754,7 +1871,7 @@ bool VillagePieces::Smithy::postProcess(Level* level, Random* random, for (int z = 0; z < depth; z++) { for (int x = 0; x < width; x++) { generateAirColumnUp(level, x, height, z, chunkBB); - fillColumnDown(level, Tile::stoneBrick_Id, 0, x, -1, z, chunkBB); + fillColumnDown(level, Tile::cobblestone_Id, 0, x, -1, z, chunkBB); } } @@ -1767,11 +1884,16 @@ int VillagePieces::Smithy::getVillagerProfession(int villagerNumber) { return Villager::PROFESSION_SMITH; } +VillagePieces::Farmland::Farmland() { + cropsA = 0; + cropsB = 0; + // for reflection +} + VillagePieces::Farmland::Farmland(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction) : VillagePiece(startPiece, genDepth) { - heightPosition = -1; // 4J added initialiser orientation = direction; boundingBox = stairsBox; @@ -1782,7 +1904,7 @@ VillagePieces::Farmland::Farmland(StartPiece* startPiece, int genDepth, int VillagePieces::Farmland::selectCrops(Random* random) { switch (random->nextInt(5)) { default: - return Tile::crops_Id; + return Tile::wheat_Id; case 0: return Tile::carrots_Id; case 1: @@ -1790,6 +1912,18 @@ int VillagePieces::Farmland::selectCrops(Random* random) { } } +void VillagePieces::Farmland::addAdditonalSaveData(CompoundTag* tag) { + VillagePiece::addAdditonalSaveData(tag); + tag->putInt(L"CA", cropsA); + tag->putInt(L"CB", cropsB); +} + +void VillagePieces::Farmland::readAdditonalSaveData(CompoundTag* tag) { + VillagePiece::readAdditonalSaveData(tag); + cropsA = tag->getInt(L"CA"); + cropsB = tag->getInt(L"CB"); +} + VillagePieces::Farmland* VillagePieces::Farmland::createPiece( StartPiece* startPiece, std::list* pieces, Random* random, int footX, int footY, int footZ, int direction, int genDepth) { @@ -1853,6 +1987,14 @@ bool VillagePieces::Farmland::postProcess(Level* level, Random* random, return true; } +VillagePieces::DoubleFarmland::DoubleFarmland() { + cropsA = 0; + cropsB = 0; + cropsC = 0; + cropsD = 0; + // for reflection +} + VillagePieces::DoubleFarmland::DoubleFarmland(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, @@ -1868,10 +2010,26 @@ VillagePieces::DoubleFarmland::DoubleFarmland(StartPiece* startPiece, cropsD = selectCrops(random); } +void VillagePieces::DoubleFarmland::addAdditonalSaveData(CompoundTag* tag) { + VillagePiece::addAdditonalSaveData(tag); + tag->putInt(L"CA", cropsA); + tag->putInt(L"CB", cropsB); + tag->putInt(L"CC", cropsC); + tag->putInt(L"CD", cropsD); +} + +void VillagePieces::DoubleFarmland::readAdditonalSaveData(CompoundTag* tag) { + VillagePiece::readAdditonalSaveData(tag); + cropsA = tag->getInt(L"CA"); + cropsB = tag->getInt(L"CB"); + cropsC = tag->getInt(L"CC"); + cropsD = tag->getInt(L"CD"); +} + int VillagePieces::DoubleFarmland::selectCrops(Random* random) { switch (random->nextInt(5)) { default: - return Tile::crops_Id; + return Tile::wheat_Id; case 0: return Tile::carrots_Id; case 1: @@ -1956,6 +2114,10 @@ bool VillagePieces::DoubleFarmland::postProcess(Level* level, Random* random, return true; } +VillagePieces::LightPost::LightPost() { + // for reflection +} + VillagePieces::LightPost::LightPost(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* box, int direction) @@ -1999,7 +2161,7 @@ bool VillagePieces::LightPost::postProcess(Level* level, Random* random, placeBlock(level, Tile::fence_Id, 0, 1, 2, 0, chunkBB); // head - placeBlock(level, Tile::cloth_Id, DyePowderItem::WHITE, 1, 3, 0, chunkBB); + placeBlock(level, Tile::wool_Id, DyePowderItem::WHITE, 1, 3, 0, chunkBB); // torches placeBlock(level, Tile::torch_Id, 0, 0, 3, 0, chunkBB); diff --git a/Minecraft.World/WorldGen/Structures/VillagePieces.h b/Minecraft.World/WorldGen/Structures/VillagePieces.h index c7e972c5c..5ba7b1063 100644 --- a/Minecraft.World/WorldGen/Structures/VillagePieces.h +++ b/Minecraft.World/WorldGen/Structures/VillagePieces.h @@ -29,6 +29,8 @@ public: EPieceClass_TwoRoomHouse }; + static void loadStatic(); + class PieceWeight { public: EPieceClass @@ -76,13 +78,20 @@ private: */ private: class VillagePiece : public StructurePiece { + protected: + int heightPosition; + private: int spawnedVillagerCount; + bool isDesertVillage; protected: StartPiece* startPiece; + VillagePiece(); VillagePiece(StartPiece* startPiece, int genDepth); + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); StructurePiece* generateHouseNorthernLeft( StartPiece* startPiece, std::list* pieces, Random* random, int yOff, int zOff); @@ -112,26 +121,24 @@ private: */ public: class Well : public VillagePiece { + public: + static StructurePiece* Create() { return new Well(); } + virtual EStructurePiece GetType() { return eStructurePiece_Well; } + private: static const int width = 6; static const int height = 15; static const int depth = 6; - const bool isSource; - int heightPosition; - public: + Well(); Well(StartPiece* startPiece, int genDepth, Random* random, int west, int north); - Well(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); virtual void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); - // static Well *createPiece(std::list *pieces, Random - // *random, int footX, int footY, int footZ, int direction, int - // genDepth); virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB); }; @@ -139,20 +146,28 @@ public: public: class StartPiece : public Well { public: + virtual EStructurePiece GetType() { + return eStructurePiece_VillageStartPiece; + } + + public: + // these fields are only used in generation step and aren't serialized + // :{ BiomeSource* biomeSource; bool isDesertVillage; int villageSize; bool isLibraryAdded; PieceWeight* previousPiece; - std::list* pieceSet; // 4J - was ArrayList + std::list* pieceSet; Level* m_level; - // these queues are used so that the addChildren calls are - // called in a random order - std::vector pendingHouses; // 4J - was ArrayList - std::vector pendingRoads; // 4J - was ArrayList + // these queues are used so that the addChildren calls are called in a + // random order + std::vector pendingHouses; + std::vector pendingRoads; + StartPiece(); StartPiece(BiomeSource* biomeSource, int genDepth, Random* random, int west, int north, std::list* pieceSet, int villageSize, Level* level); // 4J Added level param @@ -164,6 +179,7 @@ public: public: class VillageRoadPiece : public VillagePiece { protected: + VillageRoadPiece() {} VillageRoadPiece(StartPiece* startPiece, int genDepth) : VillagePiece(startPiece, genDepth) {} }; @@ -174,13 +190,26 @@ public: */ public: class StraightRoad : public VillageRoadPiece { + public: + static StructurePiece* Create() { return new StraightRoad(); } + virtual EStructurePiece GetType() { + return eStructurePiece_StraightRoad; + } + private: static const int width = 3; int length; public: + StraightRoad(); StraightRoad(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + void addAdditonalSaveData(CompoundTag* tag); + void readAdditonalSaveData(CompoundTag* tag); + + public: virtual void addChildren(StructurePiece* startPiece, std::list* pieces, Random* random); @@ -198,19 +227,29 @@ public: */ public: class SimpleHouse : public VillagePiece { + public: + static StructurePiece* Create() { return new SimpleHouse(); } + virtual EStructurePiece GetType() { + return eStructurePiece_SimpleHouse; + } + private: static const int width = 5; static const int height = 6; static const int depth = 5; private: - int heightPosition; - const bool hasTerrace; + bool hasTerrace; public: + SimpleHouse(); SimpleHouse(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); + protected: + void addAdditonalSaveData(CompoundTag* tag); + void readAdditonalSaveData(CompoundTag* tag); + public: static SimpleHouse* createPiece(StartPiece* startPiece, std::list* pieces, @@ -222,6 +261,12 @@ public: public: class SmallTemple : public VillagePiece { + public: + static StructurePiece* Create() { return new SmallTemple(); } + virtual EStructurePiece GetType() { + return eStructurePiece_SmallTemple; + } + private: static const int width = 5; static const int height = 12; @@ -230,6 +275,7 @@ public: int heightPosition; public: + SmallTemple(); SmallTemple(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); @@ -244,6 +290,10 @@ public: public: class BookHouse : public VillagePiece { + public: + static StructurePiece* Create() { return new BookHouse(); } + virtual EStructurePiece GetType() { return eStructurePiece_BookHouse; } + private: static const int width = 9; static const int height = 9; @@ -252,6 +302,7 @@ public: int heightPosition; public: + BookHouse(); BookHouse(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); @@ -266,18 +317,28 @@ public: public: class SmallHut : public VillagePiece { + public: + static StructurePiece* Create() { return new SmallHut(); } + virtual EStructurePiece GetType() { return eStructurePiece_SmallHut; } + private: static const int width = 4; static const int height = 6; static const int depth = 5; - int heightPosition; - const bool lowCeiling; - const int tablePlacement; + bool lowCeiling; + int tablePlacement; public: + SmallHut(); SmallHut(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: static SmallHut* createPiece(StartPiece* startPiece, std::list* pieces, Random* random, int footX, int footY, @@ -288,14 +349,17 @@ public: public: class PigHouse : public VillagePiece { + public: + static StructurePiece* Create() { return new PigHouse(); } + virtual EStructurePiece GetType() { return eStructurePiece_PigHouse; } + private: static const int width = 9; static const int height = 7; static const int depth = 11; - int heightPosition; - public: + PigHouse(); PigHouse(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); static PigHouse* createPiece(StartPiece* startPiece, @@ -309,6 +373,12 @@ public: public: class TwoRoomHouse : public VillagePiece { + public: + static StructurePiece* Create() { return new TwoRoomHouse(); } + virtual EStructurePiece GetType() { + return eStructurePiece_TwoRoomHouse; + } + private: static const int width = 9; static const int height = 7; @@ -317,6 +387,7 @@ public: int heightPosition; public: + TwoRoomHouse(); TwoRoomHouse(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); static TwoRoomHouse* createPiece(StartPiece* startPiece, @@ -330,12 +401,15 @@ public: public: class Smithy : public VillagePiece { + public: + static StructurePiece* Create() { return new Smithy(); } + virtual EStructurePiece GetType() { return eStructurePiece_Smithy; } + private: static const int width = 10; static const int height = 6; static const int depth = 7; - int heightPosition; bool hasPlacedChest; static WeighedTreasureArray treasureItems; @@ -343,12 +417,19 @@ public: public: static void staticCtor(); + Smithy(); Smithy(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); static Smithy* createPiece(StartPiece* startPiece, std::list* pieces, Random* random, int footX, int footY, int footZ, int direction, int genDepth); + + protected: + void addAdditonalSaveData(CompoundTag* tag); + void readAdditonalSaveData(CompoundTag* tag); + + public: virtual bool postProcess(Level* level, Random* random, BoundingBox* chunkBB); virtual int getVillagerProfession(int villagerNumber); @@ -356,21 +437,30 @@ public: public: class Farmland : public VillagePiece { + public: + static StructurePiece* Create() { return new Farmland(); } + virtual EStructurePiece GetType() { return eStructurePiece_Farmland; } + private: static const int width = 7; static const int height = 4; static const int depth = 9; - int heightPosition; - int cropsA; int cropsB; int selectCrops(Random* random); public: + Farmland(); Farmland(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: static Farmland* createPiece(StartPiece* startPiece, std::list* pieces, Random* random, int footX, int footY, @@ -381,6 +471,12 @@ public: public: class DoubleFarmland : public VillagePiece { + public: + static StructurePiece* Create() { return new DoubleFarmland(); } + virtual EStructurePiece GetType() { + return eStructurePiece_DoubleFarmland; + } + private: static const int width = 13; static const int height = 4; @@ -396,8 +492,15 @@ public: int selectCrops(Random* random); public: + DoubleFarmland(); DoubleFarmland(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* stairsBox, int direction); + + protected: + virtual void addAdditonalSaveData(CompoundTag* tag); + virtual void readAdditonalSaveData(CompoundTag* tag); + + public: static DoubleFarmland* createPiece(StartPiece* startPiece, std::list* pieces, Random* random, int footX, int footY, @@ -409,6 +512,10 @@ public: public: class LightPost : public VillagePiece { + public: + static StructurePiece* Create() { return new LightPost(); } + virtual EStructurePiece GetType() { return eStructurePiece_LightPost; } + private: static const int width = 3; static const int height = 4; @@ -417,6 +524,7 @@ public: int heightPosition; public: + LightPost(); LightPost(StartPiece* startPiece, int genDepth, Random* random, BoundingBox* box, int direction); static BoundingBox* findPieceBox(StartPiece* startPiece,