From 1f107077333b17993eede7a0bb1d1d7be9458c9f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 11 Dec 2019 21:37:00 +0100 Subject: [PATCH] Chunk: add support for Minecraft 1.15 biome map --- src/World/Chunk.cpp | 29 ++++++++++++++++++++++------- src/World/Chunk.hpp | 14 +++++++------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index dfc46db..1e4872f 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -43,13 +43,16 @@ Chunk::Chunk(const ChunkData *data) { if (!sectionsTag || sectionsTag->empty()) return; - biomeBytes = level->get("Biomes"); - biomeInts = level->get("Biomes"); - assertValue(biomeBytes || biomeInts); + auto biomesIntArray = level->get("Biomes"); + auto biomesByteArray = level->get("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("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) diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 77299ec..1a40635 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -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> sections; std::shared_ptr biomeBytes; + std::shared_ptr biomeIntsPre115; std::shared_ptr 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: