2020-08-13 04:15:51 +01:00
|
|
|
#include "Chunk.h"
|
|
|
|
#include "World.h"
|
|
|
|
|
|
|
|
namespace Feather
|
|
|
|
{
|
2020-08-13 18:06:28 +01:00
|
|
|
Chunk::Chunk(ChunkPos& pos, std::unique_ptr<NBT::CompoundTag> tag)
|
|
|
|
: pos(pos), nbt(std::move(tag))
|
2020-08-13 04:15:51 +01:00
|
|
|
{
|
|
|
|
using namespace NBT;
|
2020-08-13 18:06:28 +01:00
|
|
|
CompoundTag level = nbt->GetCompound("Level");
|
2020-08-13 04:15:51 +01:00
|
|
|
|
2020-08-14 02:42:21 +01:00
|
|
|
//Log::Trace("Loading chunk ({}, {}) from NBT", pos.x, pos.z);
|
2020-08-13 04:15:51 +01:00
|
|
|
|
|
|
|
if (pos.x != level.Get<int>("xPos") || pos.z != level.Get<int>("zPos"))
|
|
|
|
{
|
|
|
|
Log::Error("Tried to load chunk ({}, {}) from NBT but NBT says chunk pos is ({}, {})",
|
|
|
|
pos.x, pos.z,
|
|
|
|
level.Get<int>("xPos"), level.Get<int>("zPos")
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-08-13 04:54:13 +01:00
|
|
|
// TODO: Heightmaps
|
2020-08-13 04:15:51 +01:00
|
|
|
|
|
|
|
ListTag<CompoundTag> sectionsList = level.GetList<CompoundTag>("Sections");
|
|
|
|
|
|
|
|
int n = 0;
|
|
|
|
for (CompoundTag& sectData : sectionsList)
|
|
|
|
{
|
|
|
|
//std::cout << sectData << "\n";
|
|
|
|
|
|
|
|
|
|
|
|
int8_t y = sectData.Get<int8_t>("Y");
|
|
|
|
if (y < 0 || y >= NUM_SECTIONS) {
|
2020-08-14 02:42:21 +01:00
|
|
|
//Log::Trace("Skipping section {}", y);
|
2020-08-13 04:15:51 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-08-14 02:42:21 +01:00
|
|
|
//Log::Trace("Loading section {}/{} at Y {}", n + 1, NUM_SECTIONS, y);
|
2020-08-13 04:15:51 +01:00
|
|
|
|
|
|
|
if (n >= NUM_SECTIONS)
|
|
|
|
{
|
|
|
|
Log::Error("Chunk ({}, {}) has more than {} sections!", pos.x, pos.z, NUM_SECTIONS);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-08-13 04:54:48 +01:00
|
|
|
ChunkSection* section = §ions[y];
|
|
|
|
|
2020-08-13 04:15:51 +01:00
|
|
|
// Palette
|
|
|
|
|
|
|
|
ListTag<CompoundTag> palette = sectData.GetList<CompoundTag>("Palette");
|
|
|
|
|
2020-08-13 15:54:57 +01:00
|
|
|
for (size_t i = 0; i < palette.GetLength(); i++)
|
2020-08-13 04:15:51 +01:00
|
|
|
{
|
|
|
|
CompoundTag state = palette[i];
|
|
|
|
const char* name = state.Get<StringTag>("Name").GetValue();
|
|
|
|
|
|
|
|
BlockState stateLookup(name);
|
2020-08-14 02:47:19 +01:00
|
|
|
|
|
|
|
CompoundTag properties = state.GetCompound("Properties");
|
|
|
|
if (properties)
|
|
|
|
{
|
|
|
|
for (auto& prop : properties)
|
|
|
|
{
|
|
|
|
stateLookup.AddProperty(prop.GetName(), prop.GetValueString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-13 04:15:51 +01:00
|
|
|
int id;
|
|
|
|
|
|
|
|
// TODO: handle this in IdMapper
|
|
|
|
try {
|
|
|
|
id = World::GLOBAL_PALETTE.GetID(stateLookup);
|
|
|
|
}
|
|
|
|
catch (std::out_of_range& err) {
|
|
|
|
(void)err;
|
2020-08-14 02:45:34 +01:00
|
|
|
int defaultId = World::GLOBAL_PALETTE.GetDefaultID();
|
|
|
|
section->localPalette.AddMapping(i, defaultId);
|
2020-08-13 04:15:51 +01:00
|
|
|
Log::Warn("Chunk Section Palette maps id {} to invalid block state with name '{}'", i, name);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-08-13 04:54:48 +01:00
|
|
|
// TODO: could use Add()
|
|
|
|
section->localPalette.AddMapping(i, id);
|
|
|
|
|
2020-08-14 02:42:21 +01:00
|
|
|
//Log::Trace(" {} -> {} {}", i, id, name);
|
2020-08-13 04:15:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Block States
|
|
|
|
|
|
|
|
LongArrayTag blockStates = sectData.Get<LongArrayTag>("BlockStates");
|
|
|
|
|
|
|
|
if (!blockStates) {
|
|
|
|
Log::Warn("Skipping section with no block states.");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2020-08-23 02:44:28 +01:00
|
|
|
Assert(blockStates.GetLength() < ChunkSection::MaximumLongCount);
|
2020-08-13 04:15:51 +01:00
|
|
|
|
2020-08-13 15:54:57 +01:00
|
|
|
for (size_t i = 0; i < blockStates.GetLength(); i++)
|
2020-08-13 04:54:48 +01:00
|
|
|
section->blockStates[i] = blockStates[i];
|
2020-08-13 15:54:57 +01:00
|
|
|
|
|
|
|
section->bitsPerBlock = (blockStates.GetLength() * 64) / (16 * 16 * 16);
|
2020-08-13 04:15:51 +01:00
|
|
|
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|