summaryrefslogtreecommitdiffstats
path: root/src/World/Chunk.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/World/Chunk.hpp')
-rw-r--r--src/World/Chunk.hpp89
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> &section, size_t x, size_t y, size_t z) const;
- uint8_t getDataAt(const std::shared_ptr<const NBT::CompoundTag> &section, 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;