TU19: merge Minecraft.World/WorldGen

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

View file

@ -7,8 +7,8 @@ BeachBiome::BeachBiome(int id) : Biome(id) {
// remove default mob spawn settings
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;

View file

@ -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::MobSpawnerData*>* 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;
}

View file

@ -86,6 +86,7 @@ protected:
std::vector<MobSpawnerData*> friendlies_chicken;
std::vector<MobSpawnerData*> friendlies_wolf;
std::vector<MobSpawnerData*> friendlies_mushroomcow;
std::vector<MobSpawnerData*> 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:

View file

@ -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;
}
}

View file

@ -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;
};
};

View file

@ -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();

View file

@ -239,6 +239,7 @@ void BiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z,
*/
bool BiomeSource::containsOnly(int x, int z, int r,
std::vector<Biome*> 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<Biome*> 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);
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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<double>(temperature));
Arrays::fill(temperatures, 0, w * h, (double)temperature);
}
/**
* @brief Fills a float array with downfall values for a rectangular region.
*/
void FixedBiomeSource::getDownfallBlock(floatArray& downfalls, int x, int z,
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<double>(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<Biome*> allowed,
std::vector<Biome*> 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<Biome*> allowed) {
std::vector<Biome*> allowed) {
return find(allowed.begin(), allowed.end(), biome) != allowed.end();
}
}

View file

@ -1,16 +1,16 @@
#pragma once
#include <vector>
#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<Biome*> allowed,
virtual TilePos* findBiome(int x, int z, int r, std::vector<Biome*> 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<Biome*> allowed);
virtual bool containsOnly(int x, int z, int r, std::vector<Biome*> allowed);
};

View file

@ -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));

View file

@ -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));

View file

@ -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;

View file

@ -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) {

View file

@ -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);
}

View file

@ -50,7 +50,7 @@ bool BirchFeature::place(Level* level, Random* random, int x, int y, int z) {
}
}
level->setTileNoUpdate(x, y - 1, z, Tile::dirt_Id);
placeBlock(level, x, y - 1, z, Tile::dirt_Id);
for (int yy = y - 3 + treeHeight; yy <= y + treeHeight; yy++) {
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);
}

View file

@ -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<ChestTileEntity> chest =
std::dynamic_pointer_cast<ChestTileEntity>(
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;
}

View file

@ -12,7 +12,8 @@ bool CactusFeature::place(Level* level, Random* random, int x, int y, int z) {
int h = 1 + random->nextInt(random->nextInt(3) + 1);
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);
}
}
}

View file

@ -129,7 +129,7 @@ void CanyonFeature::addTunnel(int64_t seed, int xOffs, int zOffs,
if ((xd * xd + zd * zd) * rs[yy] + (yd * yd / 6) < 1) {
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) {

View file

@ -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;
}

View file

@ -22,7 +22,8 @@ bool ClayFeature::place(Level* level, Random* random, int x, int y, int z) {
for (int yy = y - yr; yy <= y + yr; yy++) {
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);
}
}
}

View file

@ -17,7 +17,8 @@ bool DeadBushFeature::place(Level* level, Random* random, int x, int y, int z) {
int z2 = z + random->nextInt(8) - random->nextInt(8);
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);
}
}
}

View file

@ -26,57 +26,62 @@ bool DesertWellFeature::place(Level* level, Random* random, int x, int y,
for (int oy = -1; oy <= 0; oy++) {
for (int 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;

View file

@ -132,7 +132,7 @@ void DungeonFeature::addTunnel(int xOffs, int zOffs, byteArray blocks,
if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) {
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;

View file

@ -59,7 +59,7 @@ bool EndPodiumFeature::place(Level* level, Random* random, int x, int y,
for (int xx = x - (r - 1); xx <= x + (r - 1); xx++) {
for (int 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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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);

View file

@ -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);
}
}
}

View file

@ -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,

View file

@ -9,8 +9,9 @@ bool HellFireFeature::place(Level* level, Random* random, int x, int y, int z) {
int y2 = y + random->nextInt(4) - random->nextInt(4);
int 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;

View file

@ -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;

View file

@ -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);

View file

@ -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);
};

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -9,9 +9,7 @@ LakeFeature::LakeFeature(int tile) { this->tile = tile; }
bool LakeFeature::place(Level* level, Random* random, int x, int y, int z) {
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;
}
}

View file

@ -135,7 +135,7 @@ void LargeCaveFeature::addTunnel(int64_t seed, int xOffs, int zOffs,
if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) {
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) {

View file

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

View file

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

View file

@ -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);
}
}
}

View file

@ -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);
};

View file

@ -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;

View file

@ -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();

View file

@ -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<std::wstring, std::wstring> options) {
chance = 0.01;
for (AUTO_VAR(it, options.begin()); it != options.end(); ++it) {
if (it->first.compare(OPTION_CHANCE) == 0) {
chance = Mth::getDouble(it->second, chance);
}
}
}
bool MineShaftFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) {
bool 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)));
}

View file

@ -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<std::wstring, std::wstring> options);
protected:
virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false);
virtual StructureStart* createStructureStart(int x, int z);

View file

@ -4,8 +4,28 @@
#include "../../Headers/net.minecraft.world.level.tile.h"
#include "../../Headers/net.minecraft.world.level.tile.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<ChestTileEntity> chest =
std::dynamic_pointer_cast<ChestTileEntity>(
level->getTileEntity(xc, yc, zc));
if (chest != NULL) {
for (int j = 0; j < 8; j++) {
std::shared_ptr<ItemInstance> 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<MobSpawnerTileEntity> entity =
std::dynamic_pointer_cast<MobSpawnerTileEntity>(
level->getTileEntity(x, y, z));
if (entity != NULL) {
entity->setEntityId(randomEntityId(random));
entity->getSpawner()->setEntityId(randomEntityId(random));
}
return true;
}
std::shared_ptr<ItemInstance> MonsterRoomFeature::randomItem(Random* random) {
int type = random->nextInt(12);
if (type == 0)
return std::shared_ptr<ItemInstance>(new ItemInstance(Item::saddle));
if (type == 1)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::ironIngot, random->nextInt(4) + 1));
if (type == 2)
return std::shared_ptr<ItemInstance>(new ItemInstance(Item::bread));
if (type == 3)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::wheat, random->nextInt(4) + 1));
if (type == 4)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::sulphur, random->nextInt(4) + 1));
if (type == 5)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::string, random->nextInt(4) + 1));
if (type == 6)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::bucket_empty));
if (type == 7 && random->nextInt(100) == 0)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::apple_gold));
if (type == 8 && random->nextInt(2) == 0)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::redStone, random->nextInt(4) + 1));
if (type == 9 && random->nextInt(10) == 0)
return std::shared_ptr<ItemInstance>(new ItemInstance(
Item::items[Item::record_01->id + random->nextInt(2)]));
if (type == 10)
return std::shared_ptr<ItemInstance>(
new ItemInstance(Item::dye_powder, 1, DyePowderItem::BROWN));
if (type == 11) return Item::enchantedBook->createForRandomLoot(random);
return std::shared_ptr<ItemInstance>();
}
std::wstring MonsterRoomFeature::randomEntityId(Random* random) {
int id = random->nextInt(4);
if (id == 0) return std::wstring(L"Skeleton");

View file

@ -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<ItemInstance> randomItem(Random* random);
std::wstring randomEntityId(Random* random);
};

View file

@ -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<Biome::MobSpawnerData*>* 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);

View file

@ -13,6 +13,7 @@ private:
public:
NetherBridgeFeature();
~NetherBridgeFeature();
std::wstring getFeatureName();
std::vector<Biome::MobSpawnerData*>* 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);
};
};

View file

@ -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);
}
}
}

View file

@ -11,8 +11,8 @@ bool PumpkinFeature::place(Level* level, Random* random, int x, int y, int z) {
if (level->isEmptyTile(x2, y2, z2) &&
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);
}
}
}

View file

@ -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<Biome*> 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<std::wstring, std::wstring> options) {
_init();
for (AUTO_VAR(it, options.begin()); it != options.end(); ++it) {
if (it->first.compare(OPTION_SPACING) == 0) {
spacing = Mth::getInt(it->second, spacing, minSeparation + 1);
}
}
}
std::wstring RandomScatteredLargeFeature::getFeatureName() { return L"Temple"; }
bool RandomScatteredLargeFeature::isFeatureChunk(int x, int z,
bool 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<ScatteredFeatureStart*>(structureAt)) ||
structureAt->pieces.empty()) {
return false;
}
StructurePiece* first = NULL;
AUTO_VAR(it, structureAt->pieces.begin());
if (it != structureAt->pieces.end()) first = *it;
return dynamic_cast<ScatteredFeaturePieces::SwamplandHut*>(first) != NULL;
}
std::vector<Biome::MobSpawnerData*>*
RandomScatteredLargeFeature::getSwamphutEnemies() {
return &swamphutEnemies;
}

View file

@ -5,17 +5,44 @@
class RandomScatteredLargeFeature : public StructureFeature {
public:
static const std::wstring OPTION_SPACING;
static void staticCtor();
static std::vector<Biome*> allowedBiomes;
private:
std::vector<Biome::MobSpawnerData*> swamphutEnemies;
int spacing;
int minSeparation;
void _init();
public:
RandomScatteredLargeFeature();
RandomScatteredLargeFeature(
std::unordered_map<std::wstring, std::wstring> 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<Biome::MobSpawnerData*>* getSwamphutEnemies();
};

View file

@ -30,7 +30,8 @@ bool ReedsFeature::place(Level* level, Random* random, int x, int y, int z) {
int h = 2 + random->nextInt(random->nextInt(3) + 1);
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);
}
}
}

View file

@ -43,7 +43,8 @@ bool SandFeature::place(Level* level, Random* random, int x, int y, int z) {
for (int yy = y - yr; yy <= y + yr; yy++) {
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);
}
}
}

View file

@ -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++;
}

View file

@ -19,18 +19,18 @@ bool SpringFeature::place(Level* level, Random* random, int x, int y, int z) {
}
}
if (level->getTile(x, y + 1, z) != Tile::rock_Id) return false;
if (level->getTile(x, y - 1, z) != Tile::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);

View file

@ -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<Biome*> 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<std::wstring, std::wstring> options) {
_init();
for (AUTO_VAR(it, options.begin()); it != options.end(); ++it) {
if (it->first.compare(OPTION_DISTANCE) == 0) {
distance = Mth::getDouble(it->second, distance, 1);
} else if (it->first.compare(OPTION_COUNT) == 0) {
// 4J-JEV: Removed, we only have the one stronghold.
// strongholdPos = new ChunkPos[ Mth::getInt(it->second,
// strongholdPos_length, 1) ];
assert(false);
} else if (it->first.compare(OPTION_SPREAD) == 0) {
spread = Mth::getInt(it->second, spread, 1);
}
}
}
StrongholdFeature::~StrongholdFeature() {
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);
}
}

View file

@ -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<std::wstring, std::wstring> options);
~StrongholdFeature();
std::wstring getFeatureName();
protected:
virtual bool isFeatureChunk(int x, int z, bool bIsSuperflat = false);
std::vector<TilePos>* 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);
};
};

View file

@ -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<StructurePiece> 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<StructurePiece*>* 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<TilePos>* StructureFeature::getGuesstimatedFeaturePositions() {
return NULL;
}
void StructureFeature::restoreSavedData(Level* level) {
#ifdef ENABLE_STRUCTURE_SAVING
if (savedData == NULL) {
savedData = std::dynamic_pointer_cast<StructureFeatureSavedData>(
level->getSavedData(typeid(StructureFeatureSavedData),
getFeatureName()));
if (savedData == NULL) {
savedData = std::shared_ptr<StructureFeatureSavedData>(
new StructureFeatureSavedData(getFeatureName()));
level->setSavedData(getFeatureName(), savedData);
} else {
CompoundTag* fullTag = savedData->getFullTag();
std::vector<Tag*>* allTags = fullTag->getAllTags();
for (AUTO_VAR(it, allTags->begin()); it != allTags->end(); ++it) {
Tag* featureTag = *it;
if (featureTag->getId() == Tag::TAG_Compound) {
CompoundTag* ct = (CompoundTag*)featureTag;
if (ct->contains(L"ChunkX") && ct->contains(L"ChunkZ")) {
int cx = ct->getInt(L"ChunkX");
int cz = ct->getInt(L"ChunkZ");
StructureStart* start =
StructureFeatureIO::loadStaticStart(ct, level);
// System.out.println("Loaded " +
// start.getClass().getSimpleName() + " from file");
cachedStructures[ChunkPos::hashCode(cx, cz)] = start;
}
}
}
delete allTags;
}
}
#endif
}
void StructureFeature::saveFeature(int chunkX, int chunkZ,
StructureStart* feature) {
#ifdef ENABLE_STRUCTURE_SAVING
savedData->putFeatureTag(feature->createTag(chunkX, chunkZ), chunkX,
chunkZ);
savedData->setDirty();
#endif
}

View file

@ -1,7 +1,11 @@
#pragma once
#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<StructureFeatureSavedData> savedData;
#endif
protected:
std::unordered_map<int64_t, StructureStart*> 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<TilePos>* getGuesstimatedFeaturePositions();
private:
virtual void restoreSavedData(Level* level);
virtual void saveFeature(int chunkX, int chunkZ, StructureStart* feature);
/**
* Returns true if the given chunk coordinates should hold a structure
* source.

View file

@ -21,7 +21,8 @@ bool TallGrassFeature::place(Level* level, Random* random, int x, int y,
int z2 = z + random->nextInt(8) - random->nextInt(8);
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);
}
}
}

View file

@ -83,7 +83,8 @@ bool TreeFeature::place(Level* level, Random* random, int x, int y, int z) {
if (abs(xo) == offs && abs(zo) == offs &&
(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);
}
}

View file

@ -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);

View file

@ -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<Biome*> 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<std::wstring, std::wstring> options, int iXZSize) {
_init(iXZSize);
for (AUTO_VAR(it, options.begin()); it != options.end(); ++it) {
if (it->first.compare(OPTION_SIZE_MODIFIER) == 0) {
villageSizeModifier =
Mth::getInt(it->second, villageSizeModifier, 0);
} else if (it->first.compare(OPTION_SPACING) == 0) {
townSpacing =
Mth::getInt(it->second, townSpacing, minTownSeparation + 1);
}
}
}
std::wstring VillageFeature::getFeatureName() { return L"Village"; }
bool VillageFeature::isFeatureChunk(int x, int z, bool bIsSuperflat) {
int townSpacing = this->townSpacing;
if (!bIsSuperflat
#ifdef _LARGE_WORLDS
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");
}

View file

@ -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<Biome*> allowedBiomes;
VillageFeature(int villageSizeModifier, int iXZSize);
VillageFeature(int iXZSize);
VillageFeature(std::unordered_map<std::wstring, std::wstring> options,
int iXZSize);
std::wstring getFeatureName();
protected:
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;

View file

@ -14,10 +14,11 @@ bool VinesFeature::place(Level* level, Random* random, int x, int y, int z) {
if (level->isEmptyTile(x, y, z)) {
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;
}
}

View file

@ -11,7 +11,8 @@ bool WaterlilyFeature::place(Level* level, Random* random, int x, int y,
int z2 = z + random->nextInt(8) - random->nextInt(8);
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);
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,4 @@
#include "../../Platform/stdafx.h"
#include "../../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;
}
}

View file

@ -34,7 +34,7 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType) {
islandLayer = std::shared_ptr<Layer>(new ZoomLayer(2003, islandLayer));
islandLayer = std::shared_ptr<Layer>(new AddIslandLayer(4, islandLayer));
// islandLayer = std::shared_ptr<Layer>(new AddMushroomIslandLayer(5,
//islandLayer)); // 4J - old position of mushroom island layer
// islandLayer)); // 4J - old position of mushroom island layer
int zoomLevel = 4;
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<BiomeOverrideLayer>(new BiomeOverrideLayer(1));
}

View file

@ -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;
};
};

View file

@ -21,7 +21,7 @@ FlatLevelSource::FlatLevelSource(Level* level, int64_t seed,
seed); // 4J - added, so that we can have a separate random for doing
// 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
}

View file

@ -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);
};

View file

@ -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) {}

View file

@ -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);
};

View file

@ -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<Biome::MobSpawnerData*>* 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);
}

View file

@ -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);
};

View file

@ -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) {
}

View file

@ -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);
};

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,5 @@
#include "../../Platform/stdafx.h"
#include "../../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<IntArrayTag>* entrances = new ListTag<IntArrayTag>(L"Entrances");
for (AUTO_VAR(it, childEntranceBoxes.begin());
it != childEntranceBoxes.end(); ++it) {
BoundingBox* bb = *it;
entrances->add(bb->createTag(L""));
}
tag->put(L"Entrances", entrances);
}
void MineShaftPieces::MineShaftRoom::readAdditonalSaveData(CompoundTag* tag) {
ListTag<IntArrayTag>* entrances =
(ListTag<IntArrayTag>*)tag->getList(L"Entrances");
for (int i = 0; i < entrances->size(); i++) {
childEntranceBoxes.push_back(new BoundingBox(entrances->get(i)->data));
}
}
MineShaftPieces::MineShaftCorridor::MineShaftCorridor() {
// for reflection
}
void MineShaftPieces::MineShaftCorridor::addAdditonalSaveData(
CompoundTag* tag) {
tag->putBoolean(L"hr", hasRails);
tag->putBoolean(L"sc", spiderCorridor);
tag->putBoolean(L"hps", hasPlacedSpider);
tag->putInt(L"Num", numSections);
}
void MineShaftPieces::MineShaftCorridor::readAdditonalSaveData(
CompoundTag* tag) {
hasRails = tag->getBoolean(L"hr");
spiderCorridor = tag->getBoolean(L"sc");
hasPlacedSpider = tag->getBoolean(L"hps");
numSections = tag->getInt(L"Num");
}
MineShaftPieces::MineShaftCorridor::MineShaftCorridor(int genDepth,
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<MinecartChest> chest =
std::shared_ptr<MinecartChest>(new MinecartChest(
level, worldX + 0.5f, worldY + 0.5f, worldZ + 0.5f));
WeighedTreasure::addChestItems(random, treasure, chest, numRolls);
level->addEntity(chest);
return true;
}
}
return false;
}
bool MineShaftPieces::MineShaftCorridor::postProcess(Level* level,
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<MobSpawnerTileEntity> entity =
std::dynamic_pointer_cast<MobSpawnerTileEntity>(
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<StructurePiece*>* pieces, Random* random, int footX, int footY,
int footZ, int direction) {

View file

@ -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<StructurePiece*>* 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<BoundingBox*> 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<StructurePiece*>* 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<StructurePiece*>* pieces,
Random* random, int footX, int footY,
int footZ, int direction);

View file

@ -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);
}
}

View file

@ -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);
};

View file

@ -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<PieceWeight*>* 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<MobSpawnerTileEntity> entity =
std::dynamic_pointer_cast<MobSpawnerTileEntity>(
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) {

View file

@ -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<PieceWeight*>* 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<StructurePiece*>* 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<StructurePiece*> 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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* 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,

View file

@ -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;
ScatteredFeaturePieces::JunglePyramidPiece::stoneSelector;
ScatteredFeaturePieces::SwamplandHut::SwamplandHut() {
spawnedWitch = false;
// for reflection
}
ScatteredFeaturePieces::SwamplandHut::SwamplandHut(Random* random, int west,
int north)
: ScatteredFeaturePiece(random, west, 64, north, 7, 5, 9) {
spawnedWitch = false;
}
void ScatteredFeaturePieces::SwamplandHut::addAdditonalSaveData(
CompoundTag* tag) {
ScatteredFeaturePiece::addAdditonalSaveData(tag);
tag->putBoolean(L"Witch", spawnedWitch);
}
void ScatteredFeaturePieces::SwamplandHut::readAdditonalSaveData(
CompoundTag* tag) {
ScatteredFeaturePiece::readAdditonalSaveData(tag);
spawnedWitch = tag->getBoolean(L"Witch");
}
bool ScatteredFeaturePieces::SwamplandHut::postProcess(Level* level,
Random* random,
BoundingBox* chunkBB) {
if (!updateAverageGroundHeight(level, chunkBB, 0)) {
return false;
}
// floor and ceiling
generateBox(level, chunkBB, 1, 1, 1, 5, 1, 7, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
generateBox(level, chunkBB, 1, 4, 2, 5, 4, 7, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
generateBox(level, chunkBB, 2, 1, 0, 4, 1, 0, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
// walls
generateBox(level, chunkBB, 2, 2, 2, 3, 3, 2, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
generateBox(level, chunkBB, 1, 2, 3, 1, 3, 6, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
generateBox(level, chunkBB, 5, 2, 3, 5, 3, 6, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
generateBox(level, chunkBB, 2, 2, 7, 4, 3, 7, Tile::wood_Id,
TreeTile::DARK_TRUNK, Tile::wood_Id, TreeTile::DARK_TRUNK,
false);
// pillars
generateBox(level, chunkBB, 1, 0, 2, 1, 3, 2, Tile::treeTrunk_Id,
Tile::treeTrunk_Id, false);
generateBox(level, chunkBB, 5, 0, 2, 5, 3, 2, Tile::treeTrunk_Id,
Tile::treeTrunk_Id, false);
generateBox(level, chunkBB, 1, 0, 7, 1, 3, 7, Tile::treeTrunk_Id,
Tile::treeTrunk_Id, false);
generateBox(level, chunkBB, 5, 0, 7, 5, 3, 7, Tile::treeTrunk_Id,
Tile::treeTrunk_Id, false);
// windows
placeBlock(level, Tile::fence_Id, 0, 2, 3, 2, chunkBB);
placeBlock(level, Tile::fence_Id, 0, 3, 3, 7, chunkBB);
placeBlock(level, 0, 0, 1, 3, 4, chunkBB);
placeBlock(level, 0, 0, 5, 3, 4, chunkBB);
placeBlock(level, 0, 0, 5, 3, 5, chunkBB);
placeBlock(level, Tile::flowerPot_Id, FlowerPotTile::TYPE_MUSHROOM_RED, 1,
3, 5, chunkBB);
// decoration
placeBlock(level, Tile::workBench_Id, 0, 3, 2, 6, chunkBB);
placeBlock(level, Tile::cauldron_Id, 0, 4, 2, 6, chunkBB);
// front railings
placeBlock(level, Tile::fence_Id, 0, 1, 2, 1, chunkBB);
placeBlock(level, Tile::fence_Id, 0, 5, 2, 1, chunkBB);
// placeBlock(level, Tile.torch.id, 0, 1, 3, 1, chunkBB);
// placeBlock(level, Tile.torch.id, 0, 5, 3, 1, chunkBB);
// ceiling edges
int south = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_NORTH);
int east = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_WEST);
int west = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_EAST);
int north = getOrientationData(Tile::stairs_wood_Id, StairTile::DIR_SOUTH);
generateBox(level, chunkBB, 0, 4, 1, 6, 4, 1, Tile::stairs_sprucewood_Id,
south, Tile::stairs_sprucewood_Id, south, false);
generateBox(level, chunkBB, 0, 4, 2, 0, 4, 7, Tile::stairs_sprucewood_Id,
west, Tile::stairs_sprucewood_Id, west, false);
generateBox(level, chunkBB, 6, 4, 2, 6, 4, 7, Tile::stairs_sprucewood_Id,
east, Tile::stairs_sprucewood_Id, east, false);
generateBox(level, chunkBB, 0, 4, 8, 6, 4, 8, Tile::stairs_sprucewood_Id,
north, Tile::stairs_sprucewood_Id, north, false);
// fill pillars down to solid ground
for (int z = 2; z <= 7; z += 5) {
for (int x = 1; x <= 5; x += 4) {
fillColumnDown(level, Tile::treeTrunk_Id, 0, x, -1, z, chunkBB);
}
}
if (!spawnedWitch) {
int wx = getWorldX(2, 5);
int wy = getWorldY(2);
int wz = getWorldZ(2, 5);
if (chunkBB->isInside(wx, wy, wz)) {
spawnedWitch = true;
std::shared_ptr<Witch> witch =
std::shared_ptr<Witch>(new Witch(level));
witch->moveTo(wx + .5, wy, wz + .5, 0, 0);
witch->finalizeMobSpawn(NULL);
level->addEntity(witch);
}
}
return true;
}

View file

@ -3,6 +3,9 @@
#include "StructurePiece.h"
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);
};
};

View file

@ -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::PieceWeight*> 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<int>(entryDoor));
}
void StrongholdPieces::StrongholdPiece::readAdditonalSaveData(
CompoundTag* tag) {
entryDoor = (SmallDoorType)_fromString<int>(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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* 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<MobSpawnerTileEntity> entity =
std::dynamic_pointer_cast<MobSpawnerTileEntity>(
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) {

View file

@ -28,6 +28,10 @@ private:
EPieceClass_PortalRoom
};
public:
static void loadStatic();
private:
class PieceWeight {
public:
EPieceClass pieceClass; // 4J - was Class<? extends StrongholdPiece>
@ -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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*> 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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* 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<StructurePiece*>* pieces, Random* random);
static PortalRoom* createPiece(std::list<StructurePiece*>* pieces,

View file

@ -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<StructurePiece*>* 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<ChestTileEntity> chest =
std::dynamic_pointer_cast<ChestTileEntity>(
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<DispenserTileEntity> dispenser =
std::dynamic_pointer_cast<DispenserTileEntity>(
level->getTileEntity(worldX, worldY, worldZ));

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