12#if PROTOCOL_VERSION > 756
19#if PROTOCOL_VERSION < 757
20 Chunk::Chunk(
const size_t dim_index,
const bool has_sky_light_)
22 Chunk::Chunk(
const int min_y_,
const unsigned int height_,
const size_t dim_index,
const bool has_sky_light_)
25 dimension_index = dim_index;
26 has_sky_light = has_sky_light_;
27#if PROTOCOL_VERSION > 756
32#if PROTOCOL_VERSION < 552
36 biomes = std::vector<unsigned char>(64 * height /
SECTION_HEIGHT, 0);
38 sections = std::vector<std::shared_ptr<Section> >(height /
SECTION_HEIGHT);
41 modified_since_last_rendered =
true;
51#if PROTOCOL_VERSION > 756
57 for (
int i = 0; i < c.
sections.size(); i++)
76 static_cast<int>(std::floor(pos.
x /
static_cast<double>(
CHUNK_WIDTH))),
78 static_cast<int>(std::floor(pos.
z /
static_cast<double>(
CHUNK_WIDTH)))
104#if PROTOCOL_VERSION < 757
105#if PROTOCOL_VERSION < 552
106 void Chunk::LoadChunkData(
const std::vector<unsigned char>& data,
const int primary_bit_mask,
const bool ground_up_continuous)
107#elif PROTOCOL_VERSION < 755
110 void Chunk::LoadChunkData(
const std::vector<unsigned char>& data,
const std::vector<unsigned long long int>& primary_bit_mask)
113 std::vector<unsigned char>::const_iterator iter = data.begin();
114 size_t length = data.size();
116 if (data.size() == 0)
118 LOG_ERROR(
"Cannot load chunk data without data");
123 for (
int sectionY = 0; sectionY < height /
SECTION_HEIGHT; ++sectionY)
125#if PROTOCOL_VERSION < 755
126 if (!(primary_bit_mask & (1 << sectionY)))
128 if (!(primary_bit_mask[sectionY / 64] & (1 << (sectionY % 64))))
134#if PROTOCOL_VERSION > 404
135 short block_count = ReadData<short>(iter, length);
137 unsigned char bits_per_block = ReadData<unsigned char>(iter, length);
141#if PROTOCOL_VERSION < 384
142 int palette_length = ReadData<VarInt>(iter, length);
144 int palette_length = 0;
147 palette_length = ReadData<VarInt>(iter, length);
150 std::vector<int> palette(palette_length);
153 if (bits_per_block < 4)
155 LOG_ERROR(
"Bits per block must be between 4 and 8 when using a palette (current: " << bits_per_block <<
"). Stop loading current chunk data");
159 for (
int i = 0; i < palette_length; ++i)
161 palette[i] = ReadData<VarInt>(iter, length);
166 if (palette_length != 0)
168 LOG_ERROR(
"Palette length should be 0 for global palette (current: " << palette_length <<
"). Stop loading current chunk data");
174 unsigned int individual_value_mask =
static_cast<unsigned int>((1 << bits_per_block) - 1);
177 int data_array_size = ReadData<VarInt>(iter, length);
180 std::vector<unsigned long long int> data_array(data_array_size);
181 for (
int i = 0; i < data_array_size; ++i)
183 data_array[i] = ReadData<unsigned long long int>(iter, length);
187#if PROTOCOL_VERSION > 712
194 for (
int block_z = 0; block_z <
CHUNK_WIDTH; ++block_z)
197 for (
int block_x = 0; block_x <
CHUNK_WIDTH; ++block_x)
200#if PROTOCOL_VERSION > 712
203 if (64 - (bit_offset % 64) < bits_per_block)
205 bit_offset += 64 - (bit_offset % 64);
207 int start_long_index = bit_offset / 64;
208 int end_long_index = start_long_index;
209 int start_offset = bit_offset % 64;
210 bit_offset += bits_per_block;
213 int start_long_index = (block_index * bits_per_block) / 64;
214 int start_offset = (block_index * bits_per_block) % 64;
215 int end_long_index = ((block_index + 1) * bits_per_block - 1) / 64;
218 if (start_long_index == end_long_index)
220 raw_id =
static_cast<unsigned int>(data_array[start_long_index] >> start_offset);
224 int end_offset = 64 - start_offset;
225 raw_id =
static_cast<unsigned int>(data_array[start_long_index] >> start_offset | data_array[end_long_index] << end_offset);
227 raw_id &= individual_value_mask;
231 raw_id = palette[raw_id];
234#if PROTOCOL_VERSION < 347
236 unsigned char metadata;
238 Blockstate::IdToIdMetadata(raw_id,
id, metadata);
240 SetBlock(pos, { id, metadata });
242 SetBlock(pos, raw_id);
248#if PROTOCOL_VERSION <= 404
253 for (
int block_z = 0; block_z <
CHUNK_WIDTH; ++block_z)
256 for (
int block_x = 0; block_x <
CHUNK_WIDTH; block_x += 2)
259 unsigned char two_light_values = ReadData<unsigned char>(iter, length);
261 SetBlockLight(pos, two_light_values & 0x0F);
263 SetBlockLight(pos, (two_light_values >> 4) & 0x0F);
274 for (
int block_z = 0; block_z <
CHUNK_WIDTH; ++block_z)
277 for (
int block_x = 0; block_x <
CHUNK_WIDTH; block_x += 2)
280 unsigned char two_light_values = ReadData<unsigned char>(iter, length);
282 SetSkyLight(pos, two_light_values & 0x0F);
284 SetSkyLight(pos, (two_light_values >> 4) & 0x0F);
292#if PROTOCOL_VERSION < 552
294 if (ground_up_continuous)
296 for (
int block_z = 0; block_z <
CHUNK_WIDTH; ++block_z)
298 for (
int block_x = 0; block_x <
CHUNK_WIDTH; ++block_x)
300#if PROTOCOL_VERSION < 358
301 SetBiome(block_x, block_z, ReadData<unsigned char>(iter, length));
303 SetBiome(block_x, block_z, ReadData<int>(iter, length));
310 modified_since_last_rendered =
true;
316 std::vector<unsigned char>::const_iterator iter = data.begin();
317 size_t length = data.size();
319 if (data.size() == 0)
321 LOG_WARNING(
"Cannot load chunk data without data");
328 short block_count = ReadData<short>(iter, length);
331 unsigned char bits_per_block = ReadData<unsigned char>(iter, length);
335 int palette_length = 0;
336 int palette_value = 0;
337 std::vector<int> palette;
338 switch (palette_type)
341 palette_value = ReadData<VarInt>(iter, length);
344 if (bits_per_block < 4)
348 palette_length = ReadData<VarInt>(iter, length);
349 palette = std::vector<int>(palette_length);
351 for (
int i = 0; i < palette_length; ++i)
353 palette[i] = ReadData<VarInt>(iter, length);
363 unsigned int individual_value_mask =
static_cast<unsigned int>((1 << bits_per_block) - 1);
366 int data_array_size = ReadData<VarInt>(iter, length);
369 std::vector<unsigned long long int> data_array(data_array_size);
370 for (
int i = 0; i < data_array_size; ++i)
372 data_array[i] = ReadData<unsigned long long int>(iter, length);
378 if (block_count != 0)
383 for (
int block_z = 0; block_z <
CHUNK_WIDTH; ++block_z)
386 for (
int block_x = 0; block_x <
CHUNK_WIDTH; ++block_x)
396 if (64 - (bit_offset % 64) < bits_per_block)
398 bit_offset += 64 - (bit_offset % 64);
400 int start_long_index = bit_offset / 64;
401 int end_long_index = start_long_index;
402 int start_offset = bit_offset % 64;
403 bit_offset += bits_per_block;
406 if (start_long_index == end_long_index)
408 raw_id =
static_cast<unsigned int>(data_array[start_long_index] >> start_offset);
412 int end_offset = 64 - start_offset;
413 raw_id =
static_cast<unsigned int>(data_array[start_long_index] >> start_offset | data_array[end_long_index] << end_offset);
415 raw_id &= individual_value_mask;
419 raw_id = palette[raw_id];
440#if PROTOCOL_VERSION < 757
447 block_entities_data.clear();
449 for (
int i = 0; i < block_entities.size(); ++i)
451#if PROTOCOL_VERSION < 757
452 if (block_entities[i].HasData())
454 if (block_entities[i].contains(
"x") &&
455 block_entities[i][
"x"].is<int>() &&
456 block_entities[i].contains(
"y") &&
457 block_entities[i][
"y"].is<int>() &&
458 block_entities[i].contains(
"z") &&
459 block_entities[i][
"z"].is<int>())
465 const int x = (block_entities[i].GetPackedXZ() >> 4) & 15;
466 const int z = (block_entities[i].GetPackedXZ() & 15);
473 modified_since_last_rendered =
true;
520#if PROTOCOL_VERSION < 347
523 Blockstate::IdToIdMetadata(
static_cast<unsigned int>(stored_id), block_id.first, block_id.second);
532 if (block ==
nullptr)
534#if PROTOCOL_VERSION < 347
556#if PROTOCOL_VERSION < 347
570#if PROTOCOL_VERSION < 347
571 const unsigned short block_id =
static_cast<unsigned short>(Blockstate::IdMetadataToId(
id.first,
id.second));
573 const unsigned short block_id =
static_cast<unsigned short>(id);
614 const unsigned char first_value = *packed_value & 0x0F;
615 *packed_value = first_value | ((v & 0x0F) << 4);
619 const unsigned char second_value = *packed_value & 0xF0;
620 *packed_value = second_value | (v & 0x0F);
660 const unsigned char first_value = *packed_value & 0x0F;
661 *packed_value = first_value | ((v & 0x0F) << 4);
665 const unsigned char second_value = *packed_value & 0xF0;
666 *packed_value = second_value | (v & 0x0F);
695#if PROTOCOL_VERSION < 552
723 return GetBiome((((y -
min_y) >> 2) & 63) << 4 | ((z >> 2) & 3) << 2 | ((x >> 2) & 3));
728 if (i < 0 || i >
biomes.size() - 1)
740 LOG_ERROR(
"Trying to set biomes with a wrong size");
743 biomes = std::vector<unsigned char>(new_biomes.size());
744 for (
size_t idx = 0; idx < new_biomes.size(); ++idx)
746 biomes[idx] =
static_cast<unsigned char>(new_biomes[idx]);
757 SetBiome((((y -
min_y) >> 2) & 63) << 4 | ((z >> 2) & 3) << 2 | ((x >> 2) & 3), new_biome);
762 if (i < 0 || i >
biomes.size() - 1)
767 biomes[i] =
static_cast<unsigned char>(new_biome);
775#if PROTOCOL_VERSION > 761
778 if (data.size() == 0)
780 LOG_WARNING(
"Cannot load chunk biomes data without data");
784 std::vector<unsigned char>::const_iterator iter = data.begin();
785 size_t length = data.size();
786 for (
int section_y = 0; section_y < height /
SECTION_HEIGHT; ++section_y)
788 LoadSectionBiomeData(section_y, iter, length);
804 this_dest_position.
x = -1;
805 this_src_position.
x = 0;
811 this_dest_position.
y = y;
812 this_src_position.
y = y;
813 neighbour_src_position.
y = y;
814 neighbour_dest_position.
y = y;
817 this_dest_position.
z = z;
818 this_src_position.
z = z;
819 neighbour_src_position.
z = z;
820 neighbour_dest_position.
z = z;
822 if (neighbour ==
nullptr)
824 SetBlock(this_dest_position,
nullptr);
840 neighbour_src_position.
x = 0;
841 neighbour_dest_position.
x = -1;
845 this_dest_position.
y = y;
846 this_src_position.
y = y;
847 neighbour_src_position.
y = y;
848 neighbour_dest_position.
y = y;
851 this_dest_position.
z = z;
852 this_src_position.
z = z;
853 neighbour_src_position.
z = z;
854 neighbour_dest_position.
z = z;
856 if (neighbour ==
nullptr)
858 SetBlock(this_dest_position,
nullptr);
872 this_dest_position.
z = -1;
873 this_src_position.
z = 0;
879 this_dest_position.
y = y;
880 this_src_position.
y = y;
881 neighbour_src_position.
y = y;
882 neighbour_dest_position.
y = y;
885 this_dest_position.
x = x;
886 this_src_position.
x = x;
887 neighbour_src_position.
x = x;
888 neighbour_dest_position.
x = x;
890 if (neighbour ==
nullptr)
892 SetBlock(this_dest_position,
nullptr);
908 neighbour_src_position.
z = 0;
909 neighbour_dest_position.
z = -1;
913 this_dest_position.
y = y;
914 this_src_position.
y = y;
915 neighbour_src_position.
y = y;
916 neighbour_dest_position.
y = y;
919 this_dest_position.
x = x;
920 this_src_position.
x = x;
921 neighbour_src_position.
x = x;
922 neighbour_dest_position.
x = x;
924 if (neighbour ==
nullptr)
926 SetBlock(this_dest_position,
nullptr);
957 if (ignore_gui_borders)
974#if PROTOCOL_VERSION > 756
978 unsigned char bits_per_biome = ReadData<unsigned char>(iter, length);
982 int palette_value = 0;
983 int palette_length = 0;
984 std::vector<int> palette;
985 switch (palette_type)
988 palette_value = ReadData<VarInt>(iter, length);
991 palette_length = ReadData<VarInt>(iter, length);
992 palette = std::vector<int>(palette_length);
993 for (
int i = 0; i < palette_length; ++i)
995 palette[i] = ReadData<VarInt>(iter, length);
1005 unsigned int individual_value_mask =
static_cast<unsigned int>((1 << bits_per_biome) - 1);
1008 int data_array_size = ReadData<VarInt>(iter, length);
1011 std::vector<unsigned long long int> data_array = std::vector<unsigned long long int>(data_array_size);
1012 for (
int i = 0; i < data_array_size; ++i)
1014 data_array[i] = ReadData<unsigned long long int>(iter, length);
1021 for (
int block_z = 0; block_z <
CHUNK_WIDTH / 4; ++block_z)
1023 for (
int block_x = 0; block_x <
CHUNK_WIDTH / 4; ++block_x)
1025 const int biome_index = section_y * 64 + block_y * 16 + block_z * 4 + block_x;
1028 SetBiome(biome_index, palette_value);
1033 if (64 - (bit_offset % 64) < bits_per_biome)
1035 bit_offset += 64 - (bit_offset % 64);
1037 int start_long_index = bit_offset / 64;
1038 int end_long_index = start_long_index;
1039 int start_offset = bit_offset % 64;
1040 bit_offset += bits_per_biome;
1042 unsigned int raw_id;
1043 if (start_long_index == end_long_index)
1045 raw_id =
static_cast<unsigned int>(data_array[start_long_index] >> start_offset);
1049 int end_offset = 64 - start_offset;
1050 raw_id =
static_cast<unsigned int>(data_array[start_long_index] >> start_offset | data_array[end_long_index] << end_offset);
1052 raw_id &= individual_value_mask;
1056 raw_id = palette[raw_id];
1059 SetBiome(biome_index, raw_id);
#define LOG_ERROR(osstream)
#define LOG_WARNING(osstream)
const Biome * GetBiome(const int id) const
static AssetsManager & getInstance()
const Blockstate * GetBlockstate(const BlockstateId id) const
BlockstateId GetId() const
void AddSection(const int y)
unsigned char GetSkyLight(const Position &pos) const
void SetBiomes(const std::vector< int > &new_biomes)
void AddLoader(const std::thread::id &thread_id)
Add a thread to the loaders list.
const Biome * GetBiome(const int x, const int y, const int z) const
std::vector< unsigned char > biomes
std::unordered_set< std::thread::id > loaded_from
bool IsInsideChunk(const Position &pos, const bool ignore_gui_borders) const
void RemoveBlockEntityData(const Position &pos)
bool modified_since_last_rendered
bool GetHasSkyLight() const
bool HasSection(const int y) const
ProtocolCraft::NBT::Value GetBlockEntityData(const Position &pos) const
size_t RemoveLoader(const std::thread::id &thread_id)
Remove a thread from the loaders list.
void LoadBiomesData(const std::vector< unsigned char > &data)
Chunk(const int min_y_, const unsigned int height_, const size_t dim_index, const bool has_sky_light_)
void LoadSectionBiomeData(const int section_y, ProtocolCraft::ReadIterator &iter, size_t &length)
bool GetModifiedSinceLastRender() const
void UpdateNeighbour(Chunk *const neighbour, const Orientation direction)
std::vector< std::shared_ptr< Section > > sections
size_t GetDimensionIndex() const
void LoadChunkData(const std::vector< unsigned char > &data)
std::unordered_map< Position, ProtocolCraft::NBT::Value > block_entities_data
const Blockstate * GetBlock(const Position &pos) const
void SetBlockEntityData(const Position &pos, const ProtocolCraft::NBT::Value &block_entity)
void SetBlockLight(const Position &pos, const unsigned char v)
void SetModifiedSinceLastRender(const bool b)
void SetBiome(const int x, const int y, const int z, const int new_biome)
void LoadChunkBlockEntitiesData(const std::vector< ProtocolCraft::BlockEntityInfo > &block_entities)
void SetSkyLight(const Position &pos, const unsigned char v)
unsigned char GetBlockLight(const Position &pos) const
static Position BlockCoordsToChunkCoords(const Position &pos)
void SetBlock(const Position &pos, const Blockstate *block)
static constexpr int SECTION_HEIGHT
static constexpr int CHUNK_WIDTH
unsigned int BlockstateId
std::vector< unsigned char >::const_iterator ReadIterator
static size_t CoordsToLightIndex(const int x, const int y, const int z)
static size_t CoordsToBlockIndex(const int x, const int y, const int z)