From fac2e4c8da6fd0af2178318bb6adfea341bbcbaf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 12 Dec 2021 12:18:18 +0100 Subject: [PATCH] World: Chunk: add support for unordered sections MC1.18 doesn't always store sections sorted by their Y value, possibly related to "optimize world". --- src/World/Chunk.cpp | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index 136c3bf..b9d27c5 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -52,17 +52,35 @@ Chunk::Chunk(const ChunkData *data) { auto dataVersionTag = data->getRoot()->get("DataVersion"); uint32_t dataVersion = dataVersionTag ? dataVersionTag->getValue() : 0; + std::vector> tmpSections; + section_idx_t minY = std::numeric_limits::max(); + section_idx_t maxY = std::numeric_limits::min(); + for (auto &sTag : *sectionsTag) { auto s = std::dynamic_pointer_cast(sTag); std::unique_ptr
section = Section::makeSection(s, dataVersion); section_idx_t Y = section->getY(); - if (sections.empty()) - sectionOffset = Y; + if (Y < minY) + minY = Y; + if (Y > maxY) + maxY = Y; + tmpSections.push_back(std::move(section)); + } + + if (tmpSections.empty()) + return; + + assertValue(minY <= maxY); + sectionOffset = minY; + sections.resize(maxY - minY + 1); + + for (auto §ion : tmpSections) { + section_idx_t Y = section->getY(); Y -= sectionOffset; - assertValue(Y >= 0 && size_t(Y) >= sections.size()); - sections.resize(Y); - sections.push_back(std::move(section)); + assertValue(Y >= 0 && size_t(Y) < sections.size()); + assertValue(!sections[Y]); + sections[Y] = std::move(section); } }