#include "stdafx.h" #include "net.minecraft.world.level.h" #include "net.minecraft.world.level.levelgen.structure.h" #include "StructureStart.h" #include "StructurePiece.h" #include "BoundingBox.h" StructureStart::StructureStart() { chunkX = chunkZ = 0; boundingBox = nullptr; // 4J added initialiser dirty = true; } StructureStart::StructureStart(int x, int z) { this->chunkX = x; this->chunkZ = z; boundingBox = nullptr; } StructureStart::~StructureStart() { for(auto& piece : pieces) { delete piece; } delete boundingBox; } BoundingBox *StructureStart::getBoundingBox() { return boundingBox; } list *StructureStart::getPieces() { return &pieces; } void StructureStart::postProcess(Level *level, Random *random, BoundingBox *chunkBB) { auto it = pieces.begin(); while( it != pieces.end() ) { StructurePiece *piece = *it; if( piece->getBoundingBox()->intersects(chunkBB) && !piece->postProcess(level, random, chunkBB) ) { // this piece can't be placed, so remove it to avoid future // attempts it = pieces.erase(it); } else { if( piece->isDirty() ) { dirty = true; piece->clearDirty(); } it++; } } } void StructureStart::calculateBoundingBox() { boundingBox = BoundingBox::getUnknownBox(); for(auto& piece : pieces) { boundingBox->expand(piece->getBoundingBox()); } } byteArray StructureStart::createTag(int chunkX, int chunkZ) { ByteArrayOutputStream baos; DataOutputStream dos(&baos); dos.writeInt(1); // version dos.writeUTF(StructureFeatureIO::getEncodeId(this)); dos.writeInt(chunkX); dos.writeInt(chunkZ); boundingBox->write(&dos); for (auto it = pieces.begin(); it != pieces.end(); ++it) { StructurePiece *piece = *it; piece->write(&dos); } addAdditionalSaveData(&dos); return baos.toByteArray(); } void StructureStart::addAdditionalSaveData(DataOutputStream *dos) { } void StructureStart::load(Level *level, DataInputStream *dis) { chunkX = dis->readInt(); chunkZ = dis->readInt(); boundingBox = new BoundingBox(); boundingBox->read(dis); int count = dis->readInt(); for (int i = 0; i < count; i++) { pieces.push_back(StructureFeatureIO::loadStaticPiece(dis, level)); } readAdditonalSaveData(dis); } void StructureStart::readAdditonalSaveData(DataInputStream *dis) { } void StructureStart::moveBelowSeaLevel(Level *level, Random *random, int offset) { const int MAX_Y = level->seaLevel - offset; // set lowest possible position (at bedrock) int y1Pos = boundingBox->getYSpan() + 1; // move up randomly within the available span if (y1Pos < MAX_Y) { y1Pos += random->nextInt(MAX_Y - y1Pos); } // move all bounding boxes int dy = y1Pos - boundingBox->y1; boundingBox->move(0, dy, 0); for(auto& piece : pieces) { piece->getBoundingBox()->move(0, dy, 0); } } void StructureStart::moveInsideHeights(Level *level, Random *random, int lowestAllowed, int highestAllowed) { int heightSpan = highestAllowed - lowestAllowed + 1 - boundingBox->getYSpan(); int y0Pos = 1; if (heightSpan > 1) { y0Pos = lowestAllowed + random->nextInt(heightSpan); } else { y0Pos = lowestAllowed; } // move all bounding boxes int dy = y0Pos - boundingBox->y0; boundingBox->move(0, dy, 0); for(auto& piece : pieces) { piece->getBoundingBox()->move(0, dy, 0); } } bool StructureStart::isValid() { return true; } int StructureStart::getChunkX() { return chunkX; } int StructureStart::getChunkZ() { return chunkZ; } void StructureStart::clearDirty() { dirty = false; } bool StructureStart::isDirty() { return dirty; }