mirror of
https://github.com/GabsPuNs/Project-Zenith-Main.git
synced 2026-05-22 18:54:33 +00:00
1343 lines
46 KiB
C++
1343 lines
46 KiB
C++
#include "stdafx.h"
|
|
#include "..\Minecraft.Client\Minecraft.h"
|
|
#include "net.minecraft.h"
|
|
#include "net.minecraft.world.level.h"
|
|
#include "net.minecraft.world.level.storage.h"
|
|
#include "net.minecraft.world.level.tile.h"
|
|
#include "net.minecraft.world.level.levelgen.h"
|
|
#include "net.minecraft.world.level.levelgen.structure.h"
|
|
#include "net.minecraft.world.item.h"
|
|
#include "net.minecraft.world.level.dimension.h"
|
|
#include "net.minecraft.world.entity.npc.h"
|
|
#include "WeighedTreasure.h"
|
|
#include "VillagePieces.h"
|
|
#include "VillageFeature.h"
|
|
#include "Direction.h"
|
|
#include "JavaMath.h"
|
|
#include "BiomeSource.h"
|
|
|
|
WeighedTreasureArray VillagePieces::Smithy::treasureItems;
|
|
|
|
void VillagePieces::loadStatic()
|
|
{
|
|
StructureFeatureIO::setPieceId(eStructurePiece_BookHouse, BookHouse::Create, L"ViBH");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_DoubleFarmland, DoubleFarmland::Create, L"ViDF");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_Farmland, Farmland::Create, L"ViF");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_LightPost, LightPost::Create, L"ViL");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_PigHouse, PigHouse::Create, L"ViPH");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_SimpleHouse, SimpleHouse::Create, L"ViSH");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_SmallHut, SmallHut::Create, L"ViSmH");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_SmallTemple, SmallTemple::Create, L"ViST");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_Smithy, Smithy::Create, L"ViS");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_VillageStartPiece, StartPiece::Create, L"ViStart");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_StraightRoad, StraightRoad::Create, L"ViSR");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_TwoRoomHouse, TwoRoomHouse::Create, L"ViTRH");
|
|
StructureFeatureIO::setPieceId(eStructurePiece_Well, Well::Create, L"ViW");
|
|
}
|
|
|
|
VillagePieces::PieceWeight::PieceWeight(VillagePieces::EPieceClass pieceClass, int weight, int maxPlaceCount) : weight(weight)
|
|
{
|
|
this->placeCount = 0; // 4J added initialiser
|
|
this->pieceClass = pieceClass;
|
|
this->maxPlaceCount = maxPlaceCount;
|
|
}
|
|
|
|
bool VillagePieces::PieceWeight::doPlace(int depth)
|
|
{
|
|
return maxPlaceCount == 0 || placeCount < maxPlaceCount;
|
|
}
|
|
|
|
bool VillagePieces::PieceWeight::isValid()
|
|
{
|
|
return maxPlaceCount == 0 || placeCount < maxPlaceCount;
|
|
}
|
|
|
|
list<VillagePieces::PieceWeight *> *VillagePieces::createPieceSet(Random *random, int villageSize)
|
|
{
|
|
list<PieceWeight *> *newPieces = new list<PieceWeight *>;
|
|
|
|
StructureTable* table = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructureFeature* feature = table->getStructureFeature(eMinecraftStructureFeature_VillageFeature);
|
|
|
|
int size = feature->options[0] + villageSize;
|
|
|
|
newPieces->push_back(new PieceWeight(VillagePieces::EPieceClass_SimpleHouse, 4, Mth::nextInt(random, 2 + size, 4 + size * 2)));
|
|
newPieces->push_back(new PieceWeight(VillagePieces::EPieceClass_SmallTemple, 20, Mth::nextInt(random, 0 + size, 1 + size)));
|
|
newPieces->push_back(new PieceWeight(VillagePieces::EPieceClass_BookHouse, 20, Mth::nextInt(random, 0 + size, 2 + size)));
|
|
newPieces->push_back(new PieceWeight(VillagePieces::EPieceClass_SmallHut, 3, Mth::nextInt(random, 2 + size, 5 + size * 3)));
|
|
newPieces->push_back(new PieceWeight(VillagePieces::EPieceClass_PigHouse, 15, Mth::nextInt(random, 0 + size, 2 + size)));
|
|
newPieces->push_back(new PieceWeight(VillagePieces::EPieceClass_DoubleFarmland, 3, Mth::nextInt(random, 1 + size, 4 + size)));
|
|
newPieces->push_back(new PieceWeight(VillagePieces::EPieceClass_Farmland, 3, Mth::nextInt(random, 2 + size, 4 + size * 2)));
|
|
newPieces->push_back(new PieceWeight(VillagePieces::EPieceClass_Smithy, 15, Mth::nextInt(random, 0, 1 + size)));
|
|
newPieces->push_back(new PieceWeight(VillagePieces::EPieceClass_TwoRoomHouse, 8, Mth::nextInt(random, 0 + size, 3 + size * 2)));
|
|
|
|
// silly way of filtering "infinite" buildings
|
|
auto it = newPieces->begin();
|
|
while( it != newPieces->end() )
|
|
{
|
|
if( (*it)->maxPlaceCount == 0 )
|
|
{
|
|
delete (*it);
|
|
it = newPieces->erase(it);
|
|
}
|
|
else
|
|
{
|
|
it++;
|
|
}
|
|
}
|
|
|
|
return newPieces;
|
|
}
|
|
|
|
int VillagePieces::updatePieceWeight(list<PieceWeight *> *currentPieces)
|
|
{
|
|
bool hasAnyPieces = false;
|
|
int totalWeight = 0;
|
|
for(auto& piece : *currentPieces)
|
|
{
|
|
if (piece->maxPlaceCount > 0 && piece->placeCount < piece->maxPlaceCount)
|
|
{
|
|
hasAnyPieces = true;
|
|
}
|
|
totalWeight += piece->weight;
|
|
}
|
|
return (hasAnyPieces ? totalWeight : -1);
|
|
}
|
|
|
|
VillagePieces::VillagePiece *VillagePieces::findAndCreatePieceFactory(StartPiece *startPiece, VillagePieces::PieceWeight *piece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int depth)
|
|
{
|
|
VillagePieces::EPieceClass pieceClass = piece->pieceClass;
|
|
VillagePiece *villagePiece = nullptr;
|
|
|
|
if (pieceClass == VillagePieces::EPieceClass_SimpleHouse)
|
|
{
|
|
villagePiece = SimpleHouse::createPiece(startPiece, pieces, random, footX, footY, footZ, direction, depth);
|
|
}
|
|
else if (pieceClass == VillagePieces::EPieceClass_SmallTemple)
|
|
{
|
|
villagePiece = SmallTemple::createPiece(startPiece, pieces, random, footX, footY, footZ, direction, depth);
|
|
}
|
|
else if (pieceClass == VillagePieces::EPieceClass_BookHouse)
|
|
{
|
|
villagePiece = BookHouse::createPiece(startPiece, pieces, random, footX, footY, footZ, direction, depth);
|
|
}
|
|
else if (pieceClass == VillagePieces::EPieceClass_SmallHut)
|
|
{
|
|
villagePiece = SmallHut::createPiece(startPiece, pieces, random, footX, footY, footZ, direction, depth);
|
|
}
|
|
else if (pieceClass == VillagePieces::EPieceClass_PigHouse)
|
|
{
|
|
villagePiece = PigHouse::createPiece(startPiece, pieces, random, footX, footY, footZ, direction, depth);
|
|
}
|
|
else if (pieceClass == VillagePieces::EPieceClass_DoubleFarmland)
|
|
{
|
|
villagePiece = DoubleFarmland::createPiece(startPiece, pieces, random, footX, footY, footZ, direction, depth);
|
|
}
|
|
else if (pieceClass == VillagePieces::EPieceClass_Farmland)
|
|
{
|
|
villagePiece = Farmland::createPiece(startPiece, pieces, random, footX, footY, footZ, direction, depth);
|
|
}
|
|
else if (pieceClass == VillagePieces::EPieceClass_Smithy)
|
|
{
|
|
villagePiece = Smithy::createPiece(startPiece, pieces, random, footX, footY, footZ, direction, depth);
|
|
}
|
|
else if (pieceClass == VillagePieces::EPieceClass_TwoRoomHouse)
|
|
{
|
|
villagePiece = TwoRoomHouse::createPiece(startPiece, pieces, random, footX, footY, footZ, direction, depth);
|
|
}
|
|
|
|
return villagePiece;
|
|
}
|
|
|
|
VillagePieces::VillagePiece *VillagePieces::generatePieceFromSmallDoor(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int depth)
|
|
{
|
|
int totalWeight = updatePieceWeight(startPiece->pieceSet);
|
|
if (totalWeight <= 0)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
int numAttempts = 0;
|
|
while (numAttempts < 5)
|
|
{
|
|
numAttempts++;
|
|
|
|
int weightSelection = random->nextInt(totalWeight);
|
|
for ( PieceWeight *piece : *startPiece->pieceSet )
|
|
{
|
|
weightSelection -= piece->weight;
|
|
if (weightSelection < 0)
|
|
{
|
|
if (!piece->doPlace(depth) || (piece == startPiece->previousPiece && startPiece->pieceSet->size() > 1))
|
|
{
|
|
break;
|
|
}
|
|
|
|
VillagePiece *villagePiece = findAndCreatePieceFactory(startPiece, piece, pieces, random, footX, footY, footZ, direction, depth);
|
|
if (villagePiece != nullptr)
|
|
{
|
|
piece->placeCount++;
|
|
startPiece->previousPiece = piece;
|
|
|
|
if (!piece->isValid())
|
|
{
|
|
startPiece->pieceSet->remove(piece);
|
|
}
|
|
return villagePiece;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// attempt to place a light post instead
|
|
{
|
|
BoundingBox *box = LightPost::findPieceBox(startPiece, pieces, random, footX, footY, footZ, direction);
|
|
if (box != nullptr)
|
|
{
|
|
return new LightPost(startPiece, depth, random, box, direction);
|
|
}
|
|
delete box;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
StructurePiece *VillagePieces::generateAndAddPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int depth)
|
|
{
|
|
if (depth > MAX_DEPTH)
|
|
{
|
|
return nullptr;
|
|
}
|
|
if (abs(footX - startPiece->getBoundingBox()->x0) > 7 * 16 || abs(footZ - startPiece->getBoundingBox()->z0) > 7 * 16)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
StructurePiece *newPiece = generatePieceFromSmallDoor(startPiece, pieces, random, footX, footY, footZ, direction, depth + 1);
|
|
if (newPiece != nullptr)
|
|
{
|
|
int x = (newPiece->boundingBox->x0 + newPiece->boundingBox->x1) / 2;
|
|
int z = (newPiece->boundingBox->z0 + newPiece->boundingBox->z1) / 2;
|
|
int xs = newPiece->boundingBox->x1 - newPiece->boundingBox->x0;
|
|
int zs = newPiece->boundingBox->z1 - newPiece->boundingBox->z0;
|
|
int r = xs > zs ? xs : zs;
|
|
if (startPiece->getBiomeSource()->containsOnly(x, z, r / 2 + 4, VillageFeature::allowedBiomes))
|
|
{
|
|
pieces->push_back(newPiece);
|
|
startPiece->pendingHouses.push_back(newPiece);
|
|
return newPiece;
|
|
}
|
|
delete newPiece;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
StructurePiece *VillagePieces::generateAndAddRoadPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int depth)
|
|
{
|
|
if (depth > BASE_ROAD_DEPTH + startPiece->villageSize)
|
|
{
|
|
return nullptr;
|
|
}
|
|
if (abs(footX - startPiece->getBoundingBox()->x0) > 7 * 16 || abs(footZ - startPiece->getBoundingBox()->z0) > 7 * 16)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
BoundingBox *box = StraightRoad::findPieceBox(startPiece, pieces, random, footX, footY, footZ, direction);
|
|
if (box != nullptr && box->y0 > LOWEST_Y_POSITION)
|
|
{
|
|
StructurePiece *newPiece = new StraightRoad(startPiece, depth, random, box, direction);
|
|
int x = (newPiece->boundingBox->x0 + newPiece->boundingBox->x1) / 2;
|
|
int z = (newPiece->boundingBox->z0 + newPiece->boundingBox->z1) / 2;
|
|
int xs = newPiece->boundingBox->x1 - newPiece->boundingBox->x0;
|
|
int zs = newPiece->boundingBox->z1 - newPiece->boundingBox->z0;
|
|
int r = xs > zs ? xs : zs;
|
|
if (startPiece->getBiomeSource()->containsOnly(x, z, r / 2 + 4, VillageFeature::allowedBiomes))
|
|
{
|
|
pieces->push_back(newPiece);
|
|
startPiece->pendingRoads.push_back(newPiece);
|
|
return newPiece;
|
|
}
|
|
// 4J Stu - The dtor for newPiece will destroy box
|
|
delete newPiece;
|
|
}
|
|
else if(box != nullptr)
|
|
{
|
|
delete box;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
VillagePieces::VillagePiece::VillagePiece()
|
|
{
|
|
objectPlacedFlags.clear();
|
|
featureConditions.clear();
|
|
tileOptionRemap.clear();
|
|
entitySpawnCounts.clear();
|
|
heightPosition = -1;
|
|
spawnedVillagerCount = 0;
|
|
isDesertVillage = false;
|
|
startPiece = nullptr;
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::VillagePiece::VillagePiece(StartPiece *startPiece, int genDepth) : StructurePiece(genDepth)
|
|
{
|
|
objectPlacedFlags.clear();
|
|
featureConditions.clear();
|
|
tileOptionRemap.clear();
|
|
entitySpawnCounts.clear();
|
|
heightPosition = -1;
|
|
isDesertVillage = false;
|
|
spawnedVillagerCount = 0;
|
|
this->startPiece = startPiece;
|
|
if (startPiece != nullptr)
|
|
{
|
|
this->isDesertVillage = startPiece->isDesertVillage;
|
|
}
|
|
}
|
|
|
|
void VillagePieces::VillagePiece::addAdditionalSaveData(DataOutputStream *dos)
|
|
{
|
|
if (startPiece != nullptr)
|
|
{
|
|
this->isDesertVillage = startPiece->isDesertVillage;
|
|
}
|
|
|
|
dos->writeInt(heightPosition);
|
|
addStructurePieceSaveData(dos, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
dos->writeInt(spawnedVillagerCount);
|
|
dos->writeBoolean(isDesertVillage);
|
|
}
|
|
|
|
void VillagePieces::VillagePiece::readAdditonalSaveData(DataInputStream *dis)
|
|
{
|
|
heightPosition = dis->readInt();
|
|
readStructurePieceSaveData(dis, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
spawnedVillagerCount = dis->readInt();
|
|
|
|
bool isDesertVillageValue = dis->readBoolean();
|
|
isDesertVillage = startPiece != nullptr ? startPiece->isDesertVillage : isDesertVillageValue;
|
|
}
|
|
|
|
StructurePiece *VillagePieces::VillagePiece::generateHouseNorthernLeft(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int yOff, int zOff)
|
|
{
|
|
switch (orientation)
|
|
{
|
|
case Direction::NORTH:
|
|
return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0 + yOff, boundingBox->z0 + zOff, Direction::WEST, getGenDepth());
|
|
case Direction::SOUTH:
|
|
return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 - 1, boundingBox->y0 + yOff, boundingBox->z0 + zOff, Direction::WEST, getGenDepth());
|
|
case Direction::WEST:
|
|
return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + zOff, boundingBox->y0 + yOff, boundingBox->z0 - 1, Direction::NORTH, getGenDepth());
|
|
case Direction::EAST:
|
|
return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + zOff, boundingBox->y0 + yOff, boundingBox->z0 - 1, Direction::NORTH, getGenDepth());
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
StructurePiece *VillagePieces::VillagePiece::generateHouseNorthernRight(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int yOff, int zOff)
|
|
{
|
|
switch (orientation)
|
|
{
|
|
case Direction::NORTH:
|
|
return generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0 + yOff, boundingBox->z0 + zOff, Direction::EAST, getGenDepth());
|
|
case Direction::SOUTH:
|
|
return generateAndAddPiece(startPiece, pieces, random, boundingBox->x1 + 1, boundingBox->y0 + yOff, boundingBox->z0 + zOff, Direction::EAST, getGenDepth());
|
|
case Direction::WEST:
|
|
return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + zOff, boundingBox->y0 + yOff, boundingBox->z1 + 1, Direction::SOUTH, getGenDepth());
|
|
case Direction::EAST:
|
|
return generateAndAddPiece(startPiece, pieces, random, boundingBox->x0 + zOff, boundingBox->y0 + yOff, boundingBox->z1 + 1, Direction::SOUTH, getGenDepth());
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
int VillagePieces::VillagePiece::getAverageGroundHeight(Level *level, BoundingBox *chunkBB)
|
|
{
|
|
int total = 0;
|
|
int count = 0;
|
|
for (int z = boundingBox->z0; z <= boundingBox->z1; z++)
|
|
{
|
|
for (int x = boundingBox->x0; x <= boundingBox->x1; x++)
|
|
{
|
|
if (chunkBB->isInside(x, 64, z))
|
|
{
|
|
total += Math::_max(level->getTopSolidBlock(x, z), level->dimension->getSpawnYPosition());
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count == 0)
|
|
{
|
|
return -1;
|
|
}
|
|
return total / count;
|
|
}
|
|
|
|
bool VillagePieces::VillagePiece::isOkBox(BoundingBox *box, StartPiece *startRoom)
|
|
{
|
|
bool bIsOk = false;
|
|
|
|
if(box != nullptr)
|
|
{
|
|
if( box->y0 > LOWEST_Y_POSITION ) bIsOk = true;
|
|
|
|
int xzSize = startRoom->m_level->getLevelData()->getXZSize();
|
|
int blockMin = -( (xzSize << 4) / 2) + 1;
|
|
int blockMax = ( (xzSize << 4) / 2 ) - 1;
|
|
|
|
if(box->x0 <= blockMin) bIsOk = false;
|
|
if(box->z0 <= blockMin) bIsOk = false;
|
|
if(box->x1 >= blockMax) bIsOk = false;
|
|
if(box->z1 >= blockMax) bIsOk = false;
|
|
}
|
|
|
|
return bIsOk;
|
|
}
|
|
|
|
void VillagePieces::VillagePiece::spawnVillagers(Level *level, BoundingBox *chunkBB, int x, int y, int z, int count)
|
|
{
|
|
if (spawnedVillagerCount >= count)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (int i = spawnedVillagerCount; i < count; i++)
|
|
{
|
|
int worldX = getWorldX(x + i, z);
|
|
int worldY = getWorldY(y);
|
|
int worldZ = getWorldZ(x + i, z);
|
|
|
|
if (chunkBB->isInside(worldX, worldY, worldZ))
|
|
{
|
|
spawnedVillagerCount++;
|
|
|
|
shared_ptr<Villager> villager = std::make_shared<Villager>(level, getVillagerProfession(i));
|
|
villager->moveTo(worldX + 0.5, worldY, worldZ + 0.5, 0, 0);
|
|
level->addEntity(villager);
|
|
}
|
|
else
|
|
{
|
|
// try again later
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int VillagePieces::VillagePiece::getVillagerProfession(int villagerNumber)
|
|
{
|
|
return Villager::PROFESSION_FARMER;
|
|
}
|
|
|
|
int VillagePieces::VillagePiece::biomeBlock(int tile, int data)
|
|
{
|
|
if (startPiece != nullptr)
|
|
this->isDesertVillage = startPiece->isDesertVillage;
|
|
|
|
if (!isDesertVillage)
|
|
return tile;
|
|
|
|
StructureTable* table = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructureFeature* feature = table->getStructureFeature(eMinecraftStructureFeature_VillageFeature);
|
|
|
|
|
|
auto it = feature->tiles.find(tile);
|
|
if (it != feature->tiles.end())
|
|
{
|
|
return it->second;
|
|
}
|
|
|
|
return tile;
|
|
}
|
|
|
|
int VillagePieces::VillagePiece::biomeData(int tile, int data)
|
|
{
|
|
if (startPiece != nullptr)
|
|
this->isDesertVillage = startPiece->isDesertVillage;
|
|
|
|
if (!isDesertVillage)
|
|
return data;
|
|
|
|
if (tile == Tile::treeTrunk_Id || tile == Tile::cobblestone_Id)
|
|
return SandStoneTile::TYPE_DEFAULT;
|
|
else if (tile == Tile::wood_Id)
|
|
return SandStoneTile::TYPE_SMOOTHSIDE;
|
|
|
|
return data;
|
|
}
|
|
|
|
void VillagePieces::VillagePiece::placeBlock(Level *level, int block, int data, int x, int y, int z, BoundingBox *chunkBB)
|
|
{
|
|
int bblock = biomeBlock(block, data);
|
|
int bdata = biomeData(block, data);
|
|
StructurePiece::placeBlock(level, bblock, bdata, x, y, z, chunkBB);
|
|
}
|
|
|
|
void VillagePieces::VillagePiece::generateBox(Level *level, BoundingBox *chunkBB, int x0, int y0, int z0, int x1, int y1, int z1, int edgeTile, int fillTile, bool skipAir)
|
|
{
|
|
int bEdge = biomeBlock(edgeTile, 0);
|
|
int bEdgeData = biomeData(edgeTile, 0);
|
|
int bFill = biomeBlock(fillTile, 0);
|
|
int bFillData = biomeData(fillTile, 0);
|
|
StructurePiece::generateBox(level, chunkBB, x0, y0, z0, x1, y1, z1, bEdge, bEdgeData, bFill, bFillData, skipAir);
|
|
}
|
|
|
|
void VillagePieces::VillagePiece::fillColumnDown(Level *level, int block, int data, int x, int startY, int z, BoundingBox *chunkBB)
|
|
{
|
|
int bblock = biomeBlock(block, data);
|
|
int bdata = biomeData(block, data);
|
|
StructurePiece::fillColumnDown(level, bblock, bdata, x, startY, z, chunkBB);
|
|
}
|
|
|
|
void VillagePieces::VillagePiece::fillBoxDown(Level* level, int x0, int y0, int z0, int x1, int y1, int z1, int tile, int tileData, BoundingBox* chunkBB)
|
|
{
|
|
int bblock = biomeBlock(x0, y0);
|
|
int bdata = biomeData(x0, y0);
|
|
StructurePiece::fillBoxDown(level, bblock, bdata, x0, y0, z0, x1, z1, chunkBB);
|
|
}
|
|
|
|
VillagePieces::Well::Well()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::Well::Well(StartPiece *startPiece, int genDepth, Random *random, int west, int north) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
orientation = random->nextInt(4);
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_Well);
|
|
|
|
switch (orientation)
|
|
{
|
|
case Direction::NORTH:
|
|
case Direction::SOUTH:
|
|
boundingBox = new BoundingBox(west, 64, north, west + piece->width - 1, 64 + piece->height - 1, north + piece->depth - 1);
|
|
break;
|
|
default:
|
|
boundingBox = new BoundingBox(west, 64, north, west + piece->depth - 1, 64 + piece->height - 1, north + piece->width - 1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
VillagePieces::Well::Well(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
}
|
|
|
|
void VillagePieces::Well::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random)
|
|
{
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x0 - 1, boundingBox->y1 - 4, boundingBox->z0 + 1, Direction::WEST, getGenDepth());
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x1 + 1, boundingBox->y1 - 4, boundingBox->z0 + 1, Direction::EAST, getGenDepth());
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x0 + 1, boundingBox->y1 - 4, boundingBox->z0 - 1, Direction::NORTH, getGenDepth());
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x0 + 1, boundingBox->y1 - 4, boundingBox->z1 + 1, Direction::SOUTH, getGenDepth());
|
|
}
|
|
|
|
bool VillagePieces::Well::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + 3, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_Well);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
}
|
|
|
|
VillagePieces::StartPiece::StartPiece()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::StartPiece::StartPiece(BiomeSource *biomeSource, int genDepth, Random *random, int west, int north, list<PieceWeight *> *pieceSet, int villageSize, Level *level) : Well(nullptr, 0, random, west, north)
|
|
{
|
|
isLibraryAdded = false; // 4J - added initialiser
|
|
previousPiece = nullptr; // 4J - added initialiser
|
|
this->biomeSource = biomeSource;
|
|
this->pieceSet = pieceSet;
|
|
this->villageSize = villageSize;
|
|
m_level = level;
|
|
|
|
Biome *biome = biomeSource->getBiome(west, north);
|
|
isDesertVillage = biome == Biome::desert || biome == Biome::desertHills;
|
|
}
|
|
|
|
VillagePieces::StartPiece::~StartPiece()
|
|
{
|
|
for(auto& it : *pieceSet)
|
|
{
|
|
delete it;
|
|
}
|
|
delete pieceSet;
|
|
}
|
|
|
|
BiomeSource *VillagePieces::StartPiece::getBiomeSource()
|
|
{
|
|
return biomeSource;
|
|
}
|
|
|
|
VillagePieces::StraightRoad::StraightRoad()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::StraightRoad::StraightRoad(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillageRoadPiece(startPiece, genDepth)
|
|
{
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
length = Math::_max(stairsBox->getXSpan(), stairsBox->getZSpan());
|
|
}
|
|
|
|
void VillagePieces::StraightRoad::addAdditionalSaveData(DataOutputStream *dos)
|
|
{
|
|
VillageRoadPiece::addAdditionalSaveData(dos);
|
|
dos->writeInt(length);
|
|
}
|
|
|
|
void VillagePieces::StraightRoad::readAdditonalSaveData(DataInputStream *dis)
|
|
{
|
|
VillageRoadPiece::readAdditonalSaveData(dis);
|
|
length = dis->readInt();
|
|
}
|
|
|
|
void VillagePieces::StraightRoad::addChildren(StructurePiece *startPiece, list<StructurePiece *> *pieces, Random *random)
|
|
{
|
|
bool hasHouses = false;
|
|
|
|
StructureTable* table = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructureFeature* feature = table->getStructureFeature(eMinecraftStructureFeature_VillageFeature);
|
|
|
|
int roadExtensionChance = feature->options[1];
|
|
int endBuffer = feature->options[3];
|
|
int houseSpacing = feature->options[4];
|
|
|
|
// place left houses
|
|
int depth = random->nextInt(houseSpacing);
|
|
while (depth < length - endBuffer)
|
|
{
|
|
StructurePiece *piece = generateHouseNorthernLeft(static_cast<StartPiece *>(startPiece), pieces, random, 0, depth);
|
|
if (piece != nullptr)
|
|
{
|
|
depth += Math::_max(piece->boundingBox->getXSpan(), piece->boundingBox->getZSpan());
|
|
hasHouses = true;
|
|
}
|
|
depth += 2 + random->nextInt(houseSpacing);
|
|
}
|
|
|
|
// place right houses
|
|
depth = random->nextInt(houseSpacing);
|
|
while (depth < length - endBuffer)
|
|
{
|
|
StructurePiece *piece = generateHouseNorthernRight(static_cast<StartPiece *>(startPiece), pieces, random, 0, depth);
|
|
if (piece != nullptr)
|
|
{
|
|
depth += Math::_max(piece->boundingBox->getXSpan(), piece->boundingBox->getZSpan());
|
|
hasHouses = true;
|
|
}
|
|
depth += 2 + random->nextInt(houseSpacing);
|
|
}
|
|
|
|
if (hasHouses && random->nextInt(roadExtensionChance) > 0)
|
|
{
|
|
switch (orientation)
|
|
{
|
|
case Direction::NORTH:
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x0 - 1, boundingBox->y0, boundingBox->z0, Direction::WEST, getGenDepth());
|
|
break;
|
|
case Direction::SOUTH:
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x0 - 1, boundingBox->y0, boundingBox->z1 - 2, Direction::WEST, getGenDepth());
|
|
break;
|
|
case Direction::EAST:
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x1 - 2, boundingBox->y0, boundingBox->z0 - 1, Direction::NORTH, getGenDepth());
|
|
break;
|
|
case Direction::WEST:
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x0, boundingBox->y0, boundingBox->z0 - 1, Direction::NORTH, getGenDepth());
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hasHouses && random->nextInt(roadExtensionChance) > 0)
|
|
{
|
|
switch (orientation)
|
|
{
|
|
case Direction::NORTH:
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x1 + 1, boundingBox->y0, boundingBox->z0, Direction::EAST, getGenDepth());
|
|
break;
|
|
case Direction::SOUTH:
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x1 + 1, boundingBox->y0, boundingBox->z1 - 2, Direction::EAST, getGenDepth());
|
|
break;
|
|
case Direction::EAST:
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x1 - 2, boundingBox->y0, boundingBox->z1 + 1, Direction::SOUTH, getGenDepth());
|
|
break;
|
|
case Direction::WEST:
|
|
generateAndAddRoadPiece(static_cast<StartPiece *>(startPiece), pieces, random, boundingBox->x0, boundingBox->y0, boundingBox->z1 + 1, Direction::SOUTH, getGenDepth());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
BoundingBox *VillagePieces::StraightRoad::findPieceBox(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction)
|
|
{
|
|
StructureTable *table = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructureFeature *feature = table->getStructureFeature(eMinecraftStructureFeature_VillageFeature);
|
|
|
|
int size = feature->options[2];
|
|
int length = size * (Mth::nextInt(random, 3, 5));
|
|
|
|
while (length >= size)
|
|
{
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, width, 3, length, direction);
|
|
|
|
if (isOkBox(box, startPiece) && StructurePiece::findCollisionPiece(pieces, box) == nullptr)
|
|
{
|
|
return box;
|
|
}
|
|
delete box;
|
|
length -= size;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool VillagePieces::StraightRoad::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructureFeature *feature = structureTable->getStructureFeature(eMinecraftStructureFeature_VillageFeature);
|
|
|
|
int tileId = feature->options[5];
|
|
|
|
int tile = biomeBlock(tileId, 0);
|
|
for (int x = boundingBox->x0; x <= boundingBox->x1; x++)
|
|
{
|
|
for (int z = boundingBox->z0; z <= boundingBox->z1; z++)
|
|
{
|
|
if (chunkBB->isInside(x, 64, z))
|
|
{
|
|
int y = level->getTopSolidBlock(x, z) - 1;
|
|
level->setTileAndData(x, y, z,tile, 0, Tile::UPDATE_CLIENTS);
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
VillagePieces::SimpleHouse::SimpleHouse()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::SimpleHouse::SimpleHouse(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
}
|
|
|
|
void VillagePieces::SimpleHouse::addAdditionalSaveData(DataOutputStream *dos)
|
|
{
|
|
VillagePiece::addAdditionalSaveData(dos);
|
|
}
|
|
|
|
void VillagePieces::SimpleHouse::readAdditonalSaveData(DataInputStream *dis)
|
|
{
|
|
VillagePiece::readAdditonalSaveData(dis);
|
|
}
|
|
|
|
VillagePieces::SimpleHouse *VillagePieces::SimpleHouse::createPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_SimpleHouse);
|
|
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, piece->width, piece->height, piece->depth, direction);
|
|
|
|
if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != nullptr)
|
|
{
|
|
delete box;
|
|
return nullptr;
|
|
}
|
|
|
|
SimpleHouse *simpleHouse = new SimpleHouse(startPiece, genDepth, random, box, direction);
|
|
simpleHouse->getRandomValuesFromDataSet(piece, random, simpleHouse->featureConditions, simpleHouse->tileOptionRemap);
|
|
|
|
return simpleHouse;
|
|
}
|
|
|
|
bool VillagePieces::SimpleHouse::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + height - 1, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_SimpleHouse);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
VillagePieces::SmallTemple::SmallTemple()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::SmallTemple::SmallTemple(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
heightPosition = -1; // 4J added initialiser
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
}
|
|
|
|
VillagePieces::SmallTemple *VillagePieces::SmallTemple::createPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_SmallTemple);
|
|
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, piece->width, piece->height, piece->depth, direction);
|
|
|
|
if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != nullptr)
|
|
{
|
|
delete box;
|
|
return nullptr;
|
|
}
|
|
|
|
SmallTemple *smallTemple = new SmallTemple(startPiece, genDepth, random, box, direction);
|
|
smallTemple->getRandomValuesFromDataSet(piece, random, smallTemple->featureConditions, smallTemple->tileOptionRemap);
|
|
|
|
return smallTemple;
|
|
}
|
|
|
|
bool VillagePieces::SmallTemple::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + height - 1, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_SmallTemple);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
}
|
|
|
|
int VillagePieces::SmallTemple::getVillagerProfession(int villagerNumber)
|
|
{
|
|
return Villager::PROFESSION_PRIEST;
|
|
}
|
|
|
|
VillagePieces::BookHouse::BookHouse()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::BookHouse::BookHouse(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
heightPosition = -1; // 4J added initialiser
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
}
|
|
|
|
VillagePieces::BookHouse *VillagePieces::BookHouse::createPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_BookHouse);
|
|
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, piece->width, piece->height, piece->depth, direction);
|
|
|
|
if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != nullptr)
|
|
{
|
|
delete box;
|
|
return nullptr;
|
|
}
|
|
|
|
BookHouse *bookHouse = new BookHouse(startPiece, genDepth, random, box, direction);
|
|
bookHouse->getRandomValuesFromDataSet(piece, random, bookHouse->featureConditions, bookHouse->tileOptionRemap);
|
|
|
|
return bookHouse;
|
|
}
|
|
|
|
bool VillagePieces::BookHouse::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + height - 1, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_BookHouse);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
}
|
|
|
|
int VillagePieces::BookHouse::getVillagerProfession(int villagerNumber)
|
|
{
|
|
return Villager::PROFESSION_LIBRARIAN;
|
|
}
|
|
|
|
VillagePieces::SmallHut::SmallHut()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::SmallHut::SmallHut(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
heightPosition = -1; // 4J added initialiser
|
|
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
}
|
|
|
|
void VillagePieces::SmallHut::addAdditionalSaveData(DataOutputStream *dos)
|
|
{
|
|
VillagePiece::addAdditionalSaveData(dos);
|
|
}
|
|
|
|
void VillagePieces::SmallHut::readAdditonalSaveData(DataInputStream *dis)
|
|
{
|
|
VillagePiece::readAdditonalSaveData(dis);
|
|
}
|
|
|
|
VillagePieces::SmallHut *VillagePieces::SmallHut::createPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_SmallHut);
|
|
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, piece->width, piece->height, piece->depth, direction);
|
|
|
|
if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != nullptr)
|
|
{
|
|
delete box;
|
|
return nullptr;
|
|
}
|
|
|
|
SmallHut *hut = new SmallHut(startPiece, genDepth, random, box, direction);
|
|
hut->getRandomValuesFromDataSet(piece, random, hut->featureConditions, hut->tileOptionRemap);
|
|
|
|
return hut;
|
|
}
|
|
|
|
bool VillagePieces::SmallHut::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + height - 1, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_SmallHut);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
}
|
|
|
|
VillagePieces::PigHouse::PigHouse()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::PigHouse::PigHouse(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
}
|
|
|
|
VillagePieces::PigHouse *VillagePieces::PigHouse::createPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_PigHouse);
|
|
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, piece->width, piece->height, piece->depth, direction);
|
|
|
|
if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != nullptr)
|
|
{
|
|
delete box;
|
|
return nullptr;
|
|
}
|
|
|
|
PigHouse *pigHouse = new PigHouse(startPiece, genDepth, random, box, direction);
|
|
pigHouse->getRandomValuesFromDataSet(piece, random, pigHouse->featureConditions, pigHouse->tileOptionRemap);
|
|
|
|
return pigHouse;
|
|
}
|
|
|
|
bool VillagePieces::PigHouse::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + height - 1, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_PigHouse);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
int VillagePieces::PigHouse::getVillagerProfession(int villagerNumber)
|
|
{
|
|
if (villagerNumber == 0)
|
|
{
|
|
return Villager::PROFESSION_BUTCHER;
|
|
}
|
|
return Villager::PROFESSION_FARMER;
|
|
}
|
|
|
|
VillagePieces::TwoRoomHouse::TwoRoomHouse()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::TwoRoomHouse::TwoRoomHouse(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
heightPosition = -1; // 4J added initialiser
|
|
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
}
|
|
|
|
VillagePieces::TwoRoomHouse *VillagePieces::TwoRoomHouse::createPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_TwoRoomHouse);
|
|
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, piece->width, piece->height, piece->depth, direction);
|
|
|
|
if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != nullptr)
|
|
{
|
|
delete box;
|
|
return nullptr;
|
|
}
|
|
|
|
TwoRoomHouse *twoRoomHouse = new TwoRoomHouse(startPiece, genDepth, random, box, direction);
|
|
twoRoomHouse->getRandomValuesFromDataSet(piece, random, twoRoomHouse->featureConditions, twoRoomHouse->tileOptionRemap);
|
|
|
|
return twoRoomHouse;
|
|
}
|
|
|
|
bool VillagePieces::TwoRoomHouse::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + height - 1, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_TwoRoomHouse);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
void VillagePieces::Smithy::staticCtor()
|
|
{
|
|
treasureItems = WeighedTreasureArray(17);
|
|
treasureItems[0] = new WeighedTreasure(Item::diamond_Id, 0, 1, 3, 3);
|
|
treasureItems[1] = new WeighedTreasure(Item::ironIngot_Id, 0, 1, 5, 10);
|
|
treasureItems[2] = new WeighedTreasure(Item::goldIngot_Id, 0, 1, 3, 5);
|
|
treasureItems[3] = new WeighedTreasure(Item::bread_Id, 0, 1, 3, 15);
|
|
treasureItems[4] = new WeighedTreasure(Item::apple_Id, 0, 1, 3, 15);
|
|
treasureItems[5] = new WeighedTreasure(Item::pickAxe_iron_Id, 0, 1, 1, 5);
|
|
treasureItems[6] = new WeighedTreasure(Item::sword_iron_Id, 0, 1, 1, 5);
|
|
treasureItems[7] = new WeighedTreasure(Item::chestplate_iron_Id, 0, 1, 1, 5);
|
|
treasureItems[8] = new WeighedTreasure(Item::helmet_iron_Id, 0, 1, 1, 5);
|
|
treasureItems[9] = new WeighedTreasure(Item::leggings_iron_Id, 0, 1, 1, 5);
|
|
treasureItems[10] = new WeighedTreasure(Item::boots_iron_Id, 0, 1, 1, 5);
|
|
treasureItems[11] = new WeighedTreasure(Tile::obsidian_Id, 0, 3, 7, 5);
|
|
treasureItems[12] = new WeighedTreasure(Tile::sapling_Id, 0, 3, 7, 5);
|
|
// very rare for villages ...
|
|
treasureItems[13] = new WeighedTreasure(Item::saddle_Id, 0, 1, 1, 3);
|
|
treasureItems[14] = new WeighedTreasure(Item::horseArmorMetal_Id, 0, 1, 1, 1);
|
|
treasureItems[15] = new WeighedTreasure(Item::horseArmorGold_Id, 0, 1, 1, 1);
|
|
treasureItems[16] = new WeighedTreasure(Item::horseArmorDiamond_Id, 0, 1, 1, 1);
|
|
// ...
|
|
}
|
|
|
|
VillagePieces::Smithy::Smithy()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::Smithy::Smithy(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
}
|
|
|
|
VillagePieces::Smithy *VillagePieces::Smithy::createPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_Smithy);
|
|
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, piece->width, piece->height, piece->depth, direction);
|
|
|
|
if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != nullptr)
|
|
{
|
|
delete box;
|
|
return nullptr;
|
|
}
|
|
|
|
Smithy *smithy = new Smithy(startPiece, genDepth, random, box, direction);
|
|
smithy->getRandomValuesFromDataSet(piece, random, smithy->featureConditions, smithy->tileOptionRemap);
|
|
|
|
return smithy;
|
|
}
|
|
|
|
void VillagePieces::Smithy::addAdditionalSaveData(DataOutputStream *dos)
|
|
{
|
|
VillagePiece::addAdditionalSaveData(dos);
|
|
}
|
|
|
|
void VillagePieces::Smithy::readAdditonalSaveData(DataInputStream *dis)
|
|
{
|
|
VillagePiece::readAdditonalSaveData(dis);
|
|
}
|
|
|
|
bool VillagePieces::Smithy::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + height - 1, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_Smithy);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
int VillagePieces::Smithy::getVillagerProfession(int villagerNumber)
|
|
{
|
|
return Villager::PROFESSION_SMITH;
|
|
}
|
|
|
|
VillagePieces::Farmland::Farmland()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::Farmland::Farmland(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
}
|
|
|
|
void VillagePieces::Farmland::addAdditionalSaveData(DataOutputStream *dos)
|
|
{
|
|
VillagePiece::addAdditionalSaveData(dos);
|
|
}
|
|
|
|
void VillagePieces::Farmland::readAdditonalSaveData(DataInputStream *dis)
|
|
{
|
|
VillagePiece::readAdditonalSaveData(dis);
|
|
}
|
|
|
|
VillagePieces::Farmland *VillagePieces::Farmland::createPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_Farmland);
|
|
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, piece->width, piece->height, piece->depth, direction);
|
|
|
|
if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != nullptr)
|
|
{
|
|
delete box;
|
|
return nullptr;
|
|
}
|
|
|
|
Farmland *farmland = new Farmland(startPiece, genDepth, random, box, direction);
|
|
farmland->getRandomValuesFromDataSet(piece, random, farmland->featureConditions, farmland->tileOptionRemap);
|
|
|
|
return farmland;
|
|
}
|
|
|
|
bool VillagePieces::Farmland::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + height - 1, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_Farmland);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
}
|
|
|
|
VillagePieces::DoubleFarmland::DoubleFarmland()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::DoubleFarmland::DoubleFarmland(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *stairsBox, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
heightPosition = -1; // 4J added initialiser
|
|
orientation = direction;
|
|
boundingBox = stairsBox;
|
|
}
|
|
|
|
void VillagePieces::DoubleFarmland::addAdditionalSaveData(DataOutputStream *dos)
|
|
{
|
|
VillagePiece::addAdditionalSaveData(dos);
|
|
}
|
|
|
|
void VillagePieces::DoubleFarmland::readAdditonalSaveData(DataInputStream *dis)
|
|
{
|
|
VillagePiece::readAdditonalSaveData(dis);
|
|
}
|
|
|
|
VillagePieces::DoubleFarmland *VillagePieces::DoubleFarmland::createPiece(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction, int genDepth)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_DoubleFarmland);
|
|
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, piece->width, piece->height, piece->depth, direction);
|
|
|
|
if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != nullptr)
|
|
{
|
|
delete box;
|
|
return nullptr;
|
|
}
|
|
|
|
DoubleFarmland *farmland = new DoubleFarmland(startPiece, genDepth, random, box, direction);
|
|
farmland->getRandomValuesFromDataSet(piece, random, farmland->featureConditions, farmland->tileOptionRemap);
|
|
|
|
return farmland;
|
|
}
|
|
|
|
bool VillagePieces::DoubleFarmland::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + height - 1, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_DoubleFarmland);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
}
|
|
|
|
VillagePieces::LightPost::LightPost()
|
|
{
|
|
// for reflection
|
|
}
|
|
|
|
VillagePieces::LightPost::LightPost(StartPiece *startPiece, int genDepth, Random *random, BoundingBox *box, int direction) : VillagePiece(startPiece, genDepth)
|
|
{
|
|
heightPosition = -1; // 4J - added initialiser
|
|
orientation = direction;
|
|
boundingBox = box;
|
|
}
|
|
|
|
BoundingBox *VillagePieces::LightPost::findPieceBox(StartPiece *startPiece, list<StructurePiece *> *pieces, Random *random, int footX, int footY, int footZ, int direction)
|
|
{
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_LightPost);
|
|
|
|
BoundingBox *box = BoundingBox::orientBox(footX, footY, footZ, 0, 0, 0, piece->width, piece->height, piece->depth, direction);
|
|
|
|
if (!isOkBox(box, startPiece) || StructurePiece::findCollisionPiece(pieces, box) != nullptr)
|
|
{
|
|
delete box;
|
|
return nullptr;
|
|
}
|
|
|
|
return box;
|
|
}
|
|
|
|
bool VillagePieces::LightPost::postProcess(Level *level, Random *random, BoundingBox *chunkBB)
|
|
{
|
|
if (heightPosition < 0)
|
|
{
|
|
heightPosition = getAverageGroundHeight(level, chunkBB);
|
|
if (heightPosition < 0)
|
|
{
|
|
return true;
|
|
}
|
|
boundingBox->move(0, heightPosition - boundingBox->y1 + height - 1, 0);
|
|
}
|
|
|
|
StructureTable *structureTable = Minecraft::GetInstance()->getStructureTable();
|
|
StructureTable::StructurePiece *piece = structureTable->getStructurePiece(eMinecraftStructurePiece_LightPost);
|
|
|
|
generateStructureFromData(level, chunkBB, random, piece, objectPlacedFlags, featureConditions, tileOptionRemap, entitySpawnCounts);
|
|
|
|
return true;
|
|
}
|