World: factor out Section handling to a generic interface

This commit is contained in:
Matthias Schiffer 2018-07-24 20:00:16 +02:00
parent dd432af298
commit 210f651807
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
7 changed files with 248 additions and 143 deletions

View file

@ -29,13 +29,13 @@
#include "Block.hpp"
#include "ChunkData.hpp"
#include "../Util.hpp"
#include "../NBT/ListTag.hpp"
#include "../NBT/ByteTag.hpp"
#include "Section.hpp"
#include "../NBT/ByteArrayTag.hpp"
#include "../NBT/IntArrayTag.hpp"
#include "../Resource/BlockType.hpp"
#include "../Util.hpp"
#include <cstdint>
#include <tuple>
namespace MinedMap {
@ -43,63 +43,28 @@ namespace World {
class Chunk {
public:
static const size_t SIZE = 16;
static const size_t SIZE = Section::SIZE;
struct Blocks {
Block blocks[SIZE][SIZE];
};
private:
std::shared_ptr<const NBT::CompoundTag> level;
std::shared_ptr<const NBT::ListTag> sections;
std::vector<std::unique_ptr<Section>> sections;
unsigned maxY;
std::unique_ptr<uint8_t[]> blockIDs;
std::unique_ptr<uint8_t[]> blockData;
std::unique_ptr<uint8_t[]> blockSkyLight;
std::unique_ptr<uint8_t[]> blockBlockLight;
const uint8_t *biomes;
size_t getIndex(size_t x, size_t y, size_t z) const {
if (x >= SIZE || y >= maxY || z >= SIZE)
throw std::range_error("Chunk::getIndex(): bad coordinates");
return SIZE*SIZE*y + SIZE*z + x;
}
uint8_t getHalf(const uint8_t *v, size_t x, size_t y, size_t z) const {
size_t i = getIndex(x, y, z);
if (i % 2)
return (v[i/2] >> 4);
else
return (v[i/2] & 0xf);
}
uint8_t getBlockAt(size_t x, size_t y, size_t z) const {
return blockIDs[getIndex(x, y, z)];
}
uint8_t getDataAt(size_t x, size_t y, size_t z) const {
return getHalf(blockData.get(), x, y, z);
}
uint8_t getBlockLightAt(size_t x, size_t y, size_t z) const {
return getHalf(blockBlockLight.get(), x, y, z);
}
uint8_t getSkyLightAt(size_t x, size_t y, size_t z) const {
return getHalf(blockSkyLight.get(), x, y, z);
}
std::shared_ptr<const NBT::ByteArrayTag> biomeBytes;
std::shared_ptr<const NBT::IntArrayTag> biomeInts;
uint8_t getBiomeAt(size_t x, size_t z) const {
return biomes[z*SIZE + x];
if (biomeBytes)
return biomeBytes->getValue()[z*SIZE + x];
else
return biomeInts->getValue(z*SIZE + x);
}
bool getBlock(Block *block, const Section *section, size_t x, size_t y, size_t z, uint8_t prev_light) const;
public:
Chunk(const ChunkData *data);
@ -107,11 +72,15 @@ public:
return *level;
}
const NBT::ListTag & getSections() const {
return *sections;
const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const {
size_t Y = y / SIZE;
if (Y >= sections.size() || !sections[Y])
return nullptr;
return sections[Y]->getBlockStateAt(x, y % SIZE, z);
}
Block getBlock(size_t x, size_t y, size_t z) const;
Blocks getTopLayer() const;
};