Handle lighting and depth

This commit is contained in:
Matthias Schiffer 2015-02-01 14:02:04 +01:00
parent d26fe3d9f8
commit 8b09f6f4ec
7 changed files with 220 additions and 72 deletions

View file

@ -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;