From 18ed3d4c5df83336229357cf8e468c8db7c4f7ca Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 1 Feb 2015 05:54:42 +0100 Subject: Further chunk parsing --- src/World/Chunk.cpp | 26 ++++++++++++++++++++++---- src/World/Chunk.hpp | 13 ++++++++++++- 2 files changed, 34 insertions(+), 5 deletions(-) (limited to 'src/World') diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index 90ad21f..c2c59e0 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -27,6 +27,7 @@ #include "Chunk.hpp" #include "../Util.hpp" #include "../NBT/ByteTag.hpp" +#include "../NBT/ByteArrayTag.hpp" #include #include @@ -82,15 +83,32 @@ void Chunk::parseChunk() { if (!(*this) || tag.first != "") throw std::invalid_argument("invalid root tag"); - sections = (*this)->get>("Level", "Sections"); - if (!sections) - throw std::invalid_argument("no sections found"); + level = assertValue((*this)->get("Level")); + sections = assertValue(level->get>("Sections")); } void Chunk::analyzeChunk() { maxY = (assertValue(sections->back()->get("Y"))->getValue() + 1) * SIZE; - std::cerr << "maxY: " << maxY << std::endl; + for (auto §ion : *sections) { + if (assertValue(section->get("Blocks"))->getLength() != SIZE*SIZE*SIZE + || assertValue(section->get("Data"))->getLength() != SIZE*SIZE*SIZE/2) + throw std::invalid_argument("corrupt chunk data"); + } +} + +uint8_t Chunk::getBlockAt(const std::shared_ptr §ion, size_t x, size_t y, size_t z) { + return (*section->get("Blocks"))[getIndex(x, y, z)]; +} + +uint8_t Chunk::getDataAt(const std::shared_ptr §ion, size_t x, size_t y, size_t z) { + size_t i = getIndex(x, y, z); + uint8_t v = (*section->get("Data"))[i / 2]; + + if (i % 2) + return (v >> 4); + else + return (v & 0xf); } Chunk::Chunk(uint8_t *buffer, size_t buflen) { diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 639d1a7..36628b4 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -46,13 +46,24 @@ private: size_t len; UniqueCPtr data; + std::shared_ptr level; + std::shared_ptr> sections; + unsigned maxY; void inflateChunk(uint8_t *data, size_t len); void parseChunk(); void analyzeChunk(); - std::shared_ptr> sections; + 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; + } + + uint8_t getBlockAt(const std::shared_ptr §ion, size_t x, size_t y, size_t z); + uint8_t getDataAt(const std::shared_ptr §ion, size_t x, size_t y, size_t z); public: Chunk(uint8_t *buffer, size_t buflen); -- cgit v1.2.3