#include "MultiblockStructure.h" #include "Block.h" #include "Game.h" using namespace Framework; MultiblockStructure::MultiblockStructure(int dimensionId, __int64 structureId, Framework::Vec3 uniquePosition, int structureTypeId) : ReferenceCounter(), uniquePosition(uniquePosition), dimensionId(dimensionId), structureId(structureId), structureTypeId(structureTypeId), isLoading(1) {} MultiblockStructure::~MultiblockStructure() {} void MultiblockStructure::onBlockLoaded(Block* block) { if (isBlockMember(block)) { loadedMembers.add(block); isLoading = 0; } else block->release(); } void MultiblockStructure::onBlockUnloaded(Block* zBlock) { for (auto i = loadedMembers.begin(); i; ++i) { if ((Block*)i == zBlock) { i.remove(); return; } } } void MultiblockStructure::addMemberPosition(Framework::Vec3 blockPos) { memberBlockPositions.add(blockPos); Punkt center = Game::INSTANCE->getChunkCenter(blockPos.x, blockPos.y); for (const Punkt& p : affectedChunks) { if (p == center) return; } affectedChunks.add(center); } void MultiblockStructure::onBlockRemoved(Block* zBlock) { for (auto i = memberBlockPositions.begin(); i; ++i) { if (i.val() == zBlock->getPos()) { Punkt center = Game::INSTANCE->getChunkCenter(i.val().x, i.val().y); i.remove(); // check if other blocks in the same chunk exists for (Vec3 pos : memberBlockPositions) { if (center == Game::INSTANCE->getChunkCenter(pos.x, pos.y)) return; } // remove chunk from affected chunks if no other block is in this // chunk for (auto p = affectedChunks.begin(); p; ++p) { if (p.val() == center) p.remove(); } return; } } } bool MultiblockStructure::isEmpty() const { return memberBlockPositions.getEintragAnzahl() == 0 && !isLoading; } bool MultiblockStructure::isFullyLoaded() const { for (Punkt p : affectedChunks) { if (!Game::INSTANCE->isChunkLoaded(p.x, p.y, dimensionId)) return 0; } return 1; } bool MultiblockStructure::isFullyUnloaded() const { if (isLoading) return 0; for (Punkt p : affectedChunks) { if (Game::INSTANCE->isChunkLoaded(p.x, p.y, dimensionId)) return 0; } return 1; } bool MultiblockStructure::isBlockMember(Block* zBlock) const { for (const Vec3& pos : memberBlockPositions) { if (pos == zBlock->getPos()) return 1; } return 0; } __int64 MultiblockStructure::getStructureId() const { return structureId; } Framework::Vec3 MultiblockStructure::getUniquePosition() const { return uniquePosition; } int MultiblockStructure::getStructureTypeId() const { return structureTypeId; } MultiblockStructureType::MultiblockStructureType(int id) : ReferenceCounter(), id(id) {} MultiblockStructureType::~MultiblockStructureType() {} void MultiblockStructureType::loadSuperStructure( MultiblockStructure* zStructure, Framework::StreamReader* zReader) const { zStructure->affectedChunks.leeren(); zStructure->memberBlockPositions.leeren(); int blockCount; zReader->lese((char*)&blockCount, 4); for (int i = 0; i < blockCount; i++) { Framework::Vec3 pos; zReader->lese((char*)&pos.x, 4); zReader->lese((char*)&pos.y, 4); zReader->lese((char*)&pos.z, 4); zStructure->addMemberPosition(pos); } } void MultiblockStructureType::saveSuperStructure( MultiblockStructure* zStructure, Framework::StreamWriter* zWriter) const { int blockCount = zStructure->memberBlockPositions.getEintragAnzahl(); zWriter->schreibe((char*)&blockCount, 4); for (Framework::Vec3 pos : zStructure->memberBlockPositions) { zWriter->schreibe((char*)&pos.x, 4); zWriter->schreibe((char*)&pos.y, 4); zWriter->schreibe((char*)&pos.z, 4); } } MultiblockStructure* MultiblockStructureType::loadStructure(int dimensionId, __int64 structureId, Framework::Vec3 uniquePosition, Framework::StreamReader* zReader) const { MultiblockStructure* str = createStructure(dimensionId, structureId, uniquePosition); loadSuperStructure(str, zReader); return str; } void MultiblockStructureType::saveStructure( MultiblockStructure* zStructure, Framework::StreamWriter* zWriter) const { saveSuperStructure(zStructure, zWriter); } int MultiblockStructureType::getId() const { return id; }