FeatherMC/src/world/Chunk.cpp

119 lines
2.8 KiB
C++
Raw Normal View History

2020-08-13 04:15:51 +01:00
#include "Chunk.h"
#include "World.h"
namespace Feather
{
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;
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 = &sections[y];
// Section Palette
2020-08-13 04:15:51 +01:00
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;
int defaultId = World::GLOBAL_PALETTE.GetDefaultID();
section->blockStates.palette.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->blockStates.palette.AddMapping(i, id);
2020-08-13 04:54:48 +01:00
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;
}
Assert(blockStates.GetLength() < section->blockStates.GetNumLongs());
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++)
section->blockStates.data[i] = blockStates[i];
2020-08-13 15:54:57 +01:00
section->blockStates.SetBits(Math::CeilDiv(blockStates.GetLength() * bitsizeof(int64), ChunkSection::NUM_BLOCKS));
2020-08-13 04:15:51 +01:00
n++;
}
}
bool Chunk::SetBlock(BlockPos& pos, BlockState& state)
{
ChunkSection& section = sections[GetSection(pos)];
return false;
}
}