Chunk: add support for Minecraft 1.15 biome map

This commit is contained in:
Matthias Schiffer 2019-12-11 21:37:00 +01:00
parent 466f393d26
commit 1f10707733
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
2 changed files with 29 additions and 14 deletions

View file

@ -43,13 +43,16 @@ Chunk::Chunk(const ChunkData *data) {
if (!sectionsTag || sectionsTag->empty())
return;
biomeBytes = level->get<NBT::ByteArrayTag>("Biomes");
biomeInts = level->get<NBT::IntArrayTag>("Biomes");
assertValue(biomeBytes || biomeInts);
auto biomesIntArray = level->get<NBT::IntArrayTag>("Biomes");
auto biomesByteArray = level->get<NBT::ByteArrayTag>("Biomes");
if (biomeBytes && biomeBytes->getLength() != SIZE*SIZE)
throw std::invalid_argument("corrupt biome data");
else if (biomeInts && biomeInts->getLength() != SIZE*SIZE)
if (biomesIntArray && biomesIntArray->getLength() == BSIZE*BSIZE*BMAXY)
biomeInts = std::move(biomesIntArray);
else if (biomesIntArray && biomesIntArray->getLength() == SIZE*SIZE)
biomeIntsPre115 = std::move(biomesIntArray);
else if (biomesByteArray && biomesByteArray->getLength() == SIZE*SIZE)
biomeBytes = std::move(biomesByteArray);
else
throw std::invalid_argument("corrupt biome data");
auto dataVersionTag = data->getRoot().get<NBT::IntTag>("DataVersion");
@ -64,6 +67,18 @@ Chunk::Chunk(const ChunkData *data) {
}
}
uint8_t Chunk::getBiome(size_t x, size_t y, size_t z) const {
if (x > SIZE || y > MAXY || z > SIZE)
throw std::invalid_argument("corrupt chunk data");
if (biomeInts)
return biomeInts->getValue((y/BGROUP)*BSIZE*BSIZE + (z/BGROUP)*BSIZE + (x/BGROUP));
else if (biomeIntsPre115)
return biomeIntsPre115->getValue(z*SIZE + x);
else
return biomeBytes->getValue(z*SIZE + x);
}
bool Chunk::getBlock(Block *block, const Section *section, size_t x, size_t y, size_t z, uint8_t prev_light) const {
if (block->height > 0)
return false;
@ -75,7 +90,7 @@ bool Chunk::getBlock(Block *block, const Section *section, size_t x, size_t y, s
if (!block->type) {
block->type = type;
block->blockLight = prev_light;
block->biome = getBiomeAt(x, z);
block->biome = getBiome(x, y, z);
}
if (type->blue)

View file

@ -44,6 +44,11 @@ namespace World {
class Chunk {
public:
static const size_t SIZE = Section::SIZE;
static const size_t MAXY = 256;
static const size_t BGROUP = 4;
static const size_t BSIZE = SIZE / BGROUP;
static const size_t BMAXY = MAXY / BGROUP;
struct Blocks {
Block blocks[SIZE][SIZE];
@ -54,15 +59,10 @@ private:
std::vector<std::unique_ptr<Section>> sections;
std::shared_ptr<const NBT::ByteArrayTag> biomeBytes;
std::shared_ptr<const NBT::IntArrayTag> biomeIntsPre115;
std::shared_ptr<const NBT::IntArrayTag> biomeInts;
uint8_t getBiomeAt(size_t x, size_t z) const {
if (biomeBytes)
return biomeBytes->getValue(z*SIZE + x);
else
return biomeInts->getValue(z*SIZE + x);
}
uint8_t getBiome(size_t x, size_t y, size_t z) const;
bool getBlock(Block *block, const Section *section, size_t x, size_t y, size_t z, uint8_t prev_light) const;
public: