diff options
Diffstat (limited to 'src/World/Chunk.hpp')
-rw-r--r-- | src/World/Chunk.hpp | 89 |
1 files changed, 75 insertions, 14 deletions
diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 22054db..333d5e5 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -30,8 +30,11 @@ #include "Block.hpp" #include "../Buffer.hpp" #include "../UniqueCPtr.hpp" +#include "../Util.hpp" #include "../NBT/CompoundTag.hpp" #include "../NBT/ListTag.hpp" +#include "../NBT/ByteTag.hpp" +#include "../NBT/ByteArrayTag.hpp" #include <cstdint> #include <tuple> @@ -40,42 +43,100 @@ namespace MinedMap { namespace World { -class Chunk : public std::shared_ptr<const NBT::CompoundTag> { +class Chunk { public: static const size_t SIZE = 16; + class Section { + private: + static size_t getIndex(size_t x, size_t y, size_t z) { + if (x >= SIZE || y >= SIZE || z >= SIZE) + throw std::range_error("Chunk::getIndex(): bad coordinates"); + + return SIZE*SIZE*y + SIZE*z + x; + } + + std::shared_ptr<const NBT::ByteArrayTag> blocks; + std::shared_ptr<const NBT::ByteArrayTag> data; + + std::shared_ptr<const NBT::ByteArrayTag> blockLight; + std::shared_ptr<const NBT::ByteArrayTag> skyLight; + + unsigned Y; + + public: + Section(const NBT::CompoundTag &s) { + blocks = assertValue(s.get<NBT::ByteArrayTag>("Blocks")); + data = assertValue(s.get<NBT::ByteArrayTag>("Data")); + blockLight = assertValue(s.get<NBT::ByteArrayTag>("BlockLight")); + skyLight = assertValue(s.get<NBT::ByteArrayTag>("SkyLight")); + + if (blocks->getLength() != SIZE*SIZE*SIZE || data->getLength() != SIZE*SIZE*SIZE/2 + || blockLight->getLength() != SIZE*SIZE*SIZE/2 || skyLight->getLength() != SIZE*SIZE*SIZE/2) + throw std::invalid_argument("corrupt chunk data"); + + Y = assertValue(s.get<NBT::ByteTag>("Y"))->getValue() * SIZE; + } + + uint8_t getBlockAt(size_t x, size_t y, size_t z) const { + return blocks->get(getIndex(x, y, z)); + } + + uint8_t getDataAt(size_t x, size_t y, size_t z) const { + return data->getHalf(getIndex(x, y, z)); + } + + uint8_t getBlockLightAt(size_t x, size_t y, size_t z) const { + return blockLight->getHalf(getIndex(x, y, z)); + } + + uint8_t getSkyLightAt(size_t x, size_t y, size_t z) const { + return skyLight->getHalf(getIndex(x, y, z)); + } + + unsigned getY() const { + return Y; + } + }; + struct Blocks { Block blocks[SIZE][SIZE]; }; private: - static size_t getIndex(size_t x, size_t y, size_t z) { - if (x >= SIZE || y >= SIZE || z >= SIZE) - throw std::range_error("Chunk::getIndex(): bad coordinates"); - - return 256*y + 16*z + x; - } - size_t len; UniqueCPtr<uint8_t[]> data; + std::shared_ptr<const NBT::CompoundTag> root; std::shared_ptr<const NBT::CompoundTag> level; - std::shared_ptr<const NBT::ListTag<NBT::CompoundTag>> sections; + + std::vector<Section> sections; unsigned maxY; + std::unique_ptr<Block[]> blocks; + + Block & getBlock(size_t x, size_t y, size_t z) { + return blocks[SIZE*SIZE*y + SIZE*z + x]; + } + + const Block & getBlock(size_t x, size_t y, size_t z) const { + return blocks[SIZE*SIZE*y + SIZE*z + x]; + } + void inflateChunk(Buffer buffer); void parseChunk(); void analyzeChunk(); - uint8_t getBlockAt(const std::shared_ptr<const NBT::CompoundTag> §ion, size_t x, size_t y, size_t z) const; - uint8_t getDataAt(const std::shared_ptr<const NBT::CompoundTag> §ion, size_t x, size_t y, size_t z) const; - public: Chunk(Buffer buffer); - const NBT::ListTag<NBT::CompoundTag> & getSections() const { - return *sections; + const NBT::CompoundTag & getLevel() const { + return *level; + } + + const std::vector<Section> & getSections() const { + return sections; } Blocks getTopLayer() const; |