summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/World/Chunk.cpp26
-rw-r--r--src/World/Chunk.hpp13
2 files changed, 34 insertions, 5 deletions
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 <iostream>
#include <stdexcept>
@@ -82,15 +83,32 @@ void Chunk::parseChunk() {
if (!(*this) || tag.first != "")
throw std::invalid_argument("invalid root tag");
- sections = (*this)->get<const NBT::ListTag<NBT::CompoundTag>>("Level", "Sections");
- if (!sections)
- throw std::invalid_argument("no sections found");
+ level = assertValue((*this)->get<NBT::CompoundTag>("Level"));
+ sections = assertValue(level->get<NBT::ListTag<NBT::CompoundTag>>("Sections"));
}
void Chunk::analyzeChunk() {
maxY = (assertValue(sections->back()->get<NBT::ByteTag>("Y"))->getValue() + 1) * SIZE;
- std::cerr << "maxY: " << maxY << std::endl;
+ for (auto &section : *sections) {
+ if (assertValue(section->get<NBT::ByteArrayTag>("Blocks"))->getLength() != SIZE*SIZE*SIZE
+ || assertValue(section->get<NBT::ByteArrayTag>("Data"))->getLength() != SIZE*SIZE*SIZE/2)
+ throw std::invalid_argument("corrupt chunk data");
+ }
+}
+
+uint8_t Chunk::getBlockAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z) {
+ return (*section->get<NBT::ByteArrayTag>("Blocks"))[getIndex(x, y, z)];
+}
+
+uint8_t Chunk::getDataAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z) {
+ size_t i = getIndex(x, y, z);
+ uint8_t v = (*section->get<NBT::ByteArrayTag>("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<uint8_t[]> data;
+ std::shared_ptr<const NBT::CompoundTag> level;
+ std::shared_ptr<const NBT::ListTag<NBT::CompoundTag>> sections;
+
unsigned maxY;
void inflateChunk(uint8_t *data, size_t len);
void parseChunk();
void analyzeChunk();
- std::shared_ptr<const NBT::ListTag<NBT::CompoundTag>> 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<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z);
+ uint8_t getDataAt(const std::shared_ptr<const NBT::CompoundTag> &section, size_t x, size_t y, size_t z);
public:
Chunk(uint8_t *buffer, size_t buflen);