Add quirk for stone_slab rename

The old stone_slab block from pre-1.14 has been renamed to
smooth_stone_slab, and the name stone_slab was reused for a new block.
Resolve the palette entry depending on the chunk's dataVersion.
This commit is contained in:
Matthias Schiffer 2019-05-25 19:51:28 +02:00
parent 359ace4932
commit ae68c3bab4
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
4 changed files with 24 additions and 9 deletions

View file

@ -143,7 +143,7 @@
/* 41 */ simple("gold_block"), /* 41 */ simple("gold_block"),
/* 42 */ simple("iron_block"), /* 42 */ simple("iron_block"),
/* 43 */ { /* 43 */ {
"stone_slab", "smooth_stone_slab",
"sandstone_slab", "sandstone_slab",
"oak_slab", "oak_slab",
"cobblestone_slab", "cobblestone_slab",
@ -153,7 +153,7 @@
"quartz_slab", "quartz_slab",
}, },
/* 44 */ { /* 44 */ {
"stone_slab", "smooth_stone_slab",
"sandstone_slab", "sandstone_slab",
"oak_slab", "oak_slab",
"cobblestone_slab", "cobblestone_slab",

View file

@ -25,6 +25,7 @@
#include "Chunk.hpp" #include "Chunk.hpp"
#include "../NBT/IntTag.hpp"
#include "../NBT/ListTag.hpp" #include "../NBT/ListTag.hpp"
#include "../NBT/StringTag.hpp" #include "../NBT/StringTag.hpp"
@ -51,9 +52,12 @@ Chunk::Chunk(const ChunkData *data) {
else if (biomeInts && biomeInts->getLength() != SIZE*SIZE) else if (biomeInts && biomeInts->getLength() != SIZE*SIZE)
throw std::invalid_argument("corrupt biome data"); throw std::invalid_argument("corrupt biome data");
auto dataVersionTag = data->getRoot().get<NBT::IntTag>("DataVersion");
uint32_t dataVersion = dataVersionTag ? dataVersionTag->getValue() : 0;
for (auto &sTag : *sectionsTag) { for (auto &sTag : *sectionsTag) {
auto s = std::dynamic_pointer_cast<const NBT::CompoundTag>(sTag); auto s = std::dynamic_pointer_cast<const NBT::CompoundTag>(sTag);
std::unique_ptr<Section> section = Section::makeSection(s); std::unique_ptr<Section> section = Section::makeSection(s, dataVersion);
size_t Y = section->getY(); size_t Y = section->getY();
sections.resize(Y); sections.resize(Y);
sections.push_back(std::move(section)); sections.push_back(std::move(section));

View file

@ -44,12 +44,12 @@ const Resource::BlockType * Section::getBlockStateAt(size_t, size_t, size_t) con
return nullptr; return nullptr;
} }
std::unique_ptr<Section> Section::makeSection(const std::shared_ptr<const NBT::CompoundTag> &section) { std::unique_ptr<Section> Section::makeSection(const std::shared_ptr<const NBT::CompoundTag> &section, uint32_t dataVersion) {
std::shared_ptr<const NBT::LongArrayTag> blockStates = section->get<NBT::LongArrayTag>("BlockStates"); std::shared_ptr<const NBT::LongArrayTag> blockStates = section->get<NBT::LongArrayTag>("BlockStates");
if (blockStates) { if (blockStates) {
const std::shared_ptr<const NBT::ListTag> palette = assertValue(section->get<NBT::ListTag>("Palette")); const std::shared_ptr<const NBT::ListTag> palette = assertValue(section->get<NBT::ListTag>("Palette"));
return std::unique_ptr<Section>(new PaletteSection(section, std::move(blockStates), palette)); return std::unique_ptr<Section>(new PaletteSection(section, std::move(blockStates), palette, dataVersion));
} }
std::shared_ptr<const NBT::ByteArrayTag> blocks = section->get<NBT::ByteArrayTag>("Blocks"); std::shared_ptr<const NBT::ByteArrayTag> blocks = section->get<NBT::ByteArrayTag>("Blocks");
@ -71,10 +71,18 @@ const Resource::BlockType * LegacySection::getBlockStateAt(size_t x, size_t y, s
} }
const Resource::BlockType * PaletteSection::lookup(const std::string &name, uint32_t dataVersion) {
if (dataVersion < 1900 && name == "minecraft:stone_slab")
return Resource::BlockType::lookup("minecraft:smooth_stone_slab");
return Resource::BlockType::lookup(name);
}
PaletteSection::PaletteSection( PaletteSection::PaletteSection(
const std::shared_ptr<const NBT::CompoundTag> &section, const std::shared_ptr<const NBT::CompoundTag> &section,
std::shared_ptr<const NBT::LongArrayTag> &&blockStates0, std::shared_ptr<const NBT::LongArrayTag> &&blockStates0,
const std::shared_ptr<const NBT::ListTag> &paletteData const std::shared_ptr<const NBT::ListTag> &paletteData,
uint32_t dataVersion
) : Section(section), blockStates(blockStates0) { ) : Section(section), blockStates(blockStates0) {
if (blockStates->getLength() % 64) if (blockStates->getLength() % 64)
throw std::invalid_argument("corrupt section data"); throw std::invalid_argument("corrupt section data");
@ -90,7 +98,7 @@ PaletteSection::PaletteSection(
const NBT::CompoundTag &paletteEntry = *assertValue(dynamic_cast<const NBT::CompoundTag *>(entry.get())); const NBT::CompoundTag &paletteEntry = *assertValue(dynamic_cast<const NBT::CompoundTag *>(entry.get()));
std::string name = assertValue(paletteEntry.get<NBT::StringTag>("Name"))->getValue(); std::string name = assertValue(paletteEntry.get<NBT::StringTag>("Name"))->getValue();
const Resource::BlockType *type = Resource::BlockType::lookup(name); const Resource::BlockType *type = lookup(name, dataVersion);
if (!type) if (!type)
std::fprintf(stderr, "Warning: unknown block type: %s\n", name.c_str()); std::fprintf(stderr, "Warning: unknown block type: %s\n", name.c_str());

View file

@ -81,7 +81,7 @@ public:
return getHalf(blockLight->getValue(), x, y, z); return getHalf(blockLight->getValue(), x, y, z);
} }
static std::unique_ptr<Section> makeSection(const std::shared_ptr<const NBT::CompoundTag> &section); static std::unique_ptr<Section> makeSection(const std::shared_ptr<const NBT::CompoundTag> &section, uint32_t dataVersion);
}; };
class LegacySection : public Section { class LegacySection : public Section {
@ -116,6 +116,8 @@ private:
uint16_t mask; uint16_t mask;
static const Resource::BlockType * lookup(const std::string &name, uint32_t dataVersion);
static size_t mangleByteIndex(size_t index) { static size_t mangleByteIndex(size_t index) {
return (index & ~(size_t)7) + 7 - (index & 7); return (index & ~(size_t)7) + 7 - (index & 7);
} }
@ -124,7 +126,8 @@ public:
PaletteSection( PaletteSection(
const std::shared_ptr<const NBT::CompoundTag> &section, const std::shared_ptr<const NBT::CompoundTag> &section,
std::shared_ptr<const NBT::LongArrayTag> &&blockStates0, std::shared_ptr<const NBT::LongArrayTag> &&blockStates0,
const std::shared_ptr<const NBT::ListTag> &paletteData const std::shared_ptr<const NBT::ListTag> &paletteData,
uint32_t dataVersion
); );
virtual const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const; virtual const Resource::BlockType * getBlockStateAt(size_t x, size_t y, size_t z) const;