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);
329#if PROTOCOL_VERSION > 774
330 short fluid_count = ReadData<short>(iter, length);
334 unsigned char bits_per_block = ReadData<unsigned char>(iter, length);
338 int palette_length = 0;
339 int palette_value = 0;
340 std::vector<int> palette;
341 switch (palette_type)
344 palette_value = ReadData<VarInt>(iter, length);
347 if (bits_per_block < 4)
351 palette_length = ReadData<VarInt>(iter, length);
352 palette = std::vector<int>(palette_length);
354 for (
int i = 0; i < palette_length; ++i)
356 palette[i] = ReadData<VarInt>(iter, length);
366 unsigned int individual_value_mask =
static_cast<unsigned int>((1 << bits_per_block) - 1);
369#if PROTOCOL_VERSION < 770
370 const int data_array_size = ReadData<VarInt>(iter, length);
372 const int data_array_size = bits_per_block == 0 ? 0 :
377 std::vector<unsigned long long int> data_array(data_array_size);
378 for (
int i = 0; i < data_array_size; ++i)
380 data_array[i] = ReadData<unsigned long long int>(iter, length);
386 if (block_count != 0)
391 for (
int block_z = 0; block_z <
CHUNK_WIDTH; ++block_z)
394 for (
int block_x = 0; block_x <
CHUNK_WIDTH; ++block_x)
404 if (64 - (bit_offset % 64) < bits_per_block)
406 bit_offset += 64 - (bit_offset % 64);
408 int start_long_index = bit_offset / 64;
409 int end_long_index = start_long_index;
410 int start_offset = bit_offset % 64;
411 bit_offset += bits_per_block;
414 if (start_long_index == end_long_index)
416 raw_id =
static_cast<unsigned int>(data_array[start_long_index] >> start_offset);
420 int end_offset = 64 - start_offset;
421 raw_id =
static_cast<unsigned int>(data_array[start_long_index] >> start_offset | data_array[end_long_index] << end_offset);
423 raw_id &= individual_value_mask;
427 raw_id = palette[raw_id];
448#if PROTOCOL_VERSION < 757
455 block_entities_data.clear();
457 for (
int i = 0; i < block_entities.size(); ++i)
459#if PROTOCOL_VERSION < 757
460 if (block_entities[i].HasData())
462 if (block_entities[i].contains(
"x") &&
463 block_entities[i][
"x"].is<int>() &&
464 block_entities[i].contains(
"y") &&
465 block_entities[i][
"y"].is<int>() &&
466 block_entities[i].contains(
"z") &&
467 block_entities[i][
"z"].is<int>())
473 const int x = (block_entities[i].GetPackedXZ() >> 4) & 15;
474 const int z = (block_entities[i].GetPackedXZ() & 15);
481 modified_since_last_rendered =
true;
528#if PROTOCOL_VERSION < 347
531 Blockstate::IdToIdMetadata(
static_cast<unsigned int>(stored_id), block_id.first, block_id.second);
540 if (block ==
nullptr)
542#if PROTOCOL_VERSION < 347
564#if PROTOCOL_VERSION < 347
578#if PROTOCOL_VERSION < 347
579 const unsigned short block_id =
static_cast<unsigned short>(Blockstate::IdMetadataToId(
id.first,
id.second));
581 const unsigned short block_id =
static_cast<unsigned short>(id);
622 const unsigned char first_value = *packed_value & 0x0F;
623 *packed_value = first_value | ((v & 0x0F) << 4);
627 const unsigned char second_value = *packed_value & 0xF0;
628 *packed_value = second_value | (v & 0x0F);
668 const unsigned char first_value = *packed_value & 0x0F;
669 *packed_value = first_value | ((v & 0x0F) << 4);
673 const unsigned char second_value = *packed_value & 0xF0;
674 *packed_value = second_value | (v & 0x0F);
703#if PROTOCOL_VERSION < 552
731 return GetBiome((((y -
min_y) >> 2) & 63) << 4 | ((z >> 2) & 3) << 2 | ((x >> 2) & 3));
736 if (i < 0 || i >
biomes.size() - 1)
748 LOG_ERROR(
"Trying to set biomes with a wrong size");
751 biomes = std::vector<unsigned char>(new_biomes.size());
752 for (
size_t idx = 0; idx < new_biomes.size(); ++idx)
754 biomes[idx] =
static_cast<unsigned char>(new_biomes[idx]);
765 SetBiome((((y -
min_y) >> 2) & 63) << 4 | ((z >> 2) & 3) << 2 | ((x >> 2) & 3), new_biome);
770 if (i < 0 || i >
biomes.size() - 1)
775 biomes[i] =
static_cast<unsigned char>(new_biome);
783#if PROTOCOL_VERSION > 761
786 if (data.size() == 0)
788 LOG_WARNING(
"Cannot load chunk biomes data without data");
792 std::vector<unsigned char>::const_iterator iter = data.begin();
793 size_t length = data.size();
794 for (
int section_y = 0; section_y < height /
SECTION_HEIGHT; ++section_y)
796 LoadSectionBiomeData(section_y, iter, length);
812 this_dest_position.
x = -1;
813 this_src_position.
x = 0;
819 this_dest_position.
y = y;
820 this_src_position.
y = y;
821 neighbour_src_position.
y = y;
822 neighbour_dest_position.
y = y;
825 this_dest_position.
z = z;
826 this_src_position.
z = z;
827 neighbour_src_position.
z = z;
828 neighbour_dest_position.
z = z;
830 if (neighbour ==
nullptr)
832 SetBlock(this_dest_position,
nullptr);
848 neighbour_src_position.
x = 0;
849 neighbour_dest_position.
x = -1;
853 this_dest_position.
y = y;
854 this_src_position.
y = y;
855 neighbour_src_position.
y = y;
856 neighbour_dest_position.
y = y;
859 this_dest_position.
z = z;
860 this_src_position.
z = z;
861 neighbour_src_position.
z = z;
862 neighbour_dest_position.
z = z;
864 if (neighbour ==
nullptr)
866 SetBlock(this_dest_position,
nullptr);
880 this_dest_position.
z = -1;
881 this_src_position.
z = 0;
887 this_dest_position.
y = y;
888 this_src_position.
y = y;
889 neighbour_src_position.
y = y;
890 neighbour_dest_position.
y = y;
893 this_dest_position.
x = x;
894 this_src_position.
x = x;
895 neighbour_src_position.
x = x;
896 neighbour_dest_position.
x = x;
898 if (neighbour ==
nullptr)
900 SetBlock(this_dest_position,
nullptr);
916 neighbour_src_position.
z = 0;
917 neighbour_dest_position.
z = -1;
921 this_dest_position.
y = y;
922 this_src_position.
y = y;
923 neighbour_src_position.
y = y;
924 neighbour_dest_position.
y = y;
927 this_dest_position.
x = x;
928 this_src_position.
x = x;
929 neighbour_src_position.
x = x;
930 neighbour_dest_position.
x = x;
932 if (neighbour ==
nullptr)
934 SetBlock(this_dest_position,
nullptr);
965 if (ignore_gui_borders)
982#if PROTOCOL_VERSION > 756
986 unsigned char bits_per_biome = ReadData<unsigned char>(iter, length);
990 int palette_value = 0;
991 int palette_length = 0;
992 std::vector<int> palette;
993 switch (palette_type)
996 palette_value = ReadData<VarInt>(iter, length);
999 palette_length = ReadData<VarInt>(iter, length);
1000 palette = std::vector<int>(palette_length);
1001 for (
int i = 0; i < palette_length; ++i)
1003 palette[i] = ReadData<VarInt>(iter, length);
1013 unsigned int individual_value_mask =
static_cast<unsigned int>((1 << bits_per_biome) - 1);
1016#if PROTOCOL_VERSION < 770
1017 const int data_array_size = ReadData<VarInt>(iter, length);
1019 const int data_array_size = bits_per_biome == 0 ? 0 :
1025 std::vector<unsigned long long int> data_array = std::vector<unsigned long long int>(data_array_size);
1026 for (
int i = 0; i < data_array_size; ++i)
1028 data_array[i] = ReadData<unsigned long long int>(iter, length);
1035 for (
int block_z = 0; block_z <
CHUNK_WIDTH / 4; ++block_z)
1037 for (
int block_x = 0; block_x <
CHUNK_WIDTH / 4; ++block_x)
1039 const int biome_index = section_y * 64 + block_y * 16 + block_z * 4 + block_x;
1042 SetBiome(biome_index, palette_value);
1047 if (64 - (bit_offset % 64) < bits_per_biome)
1049 bit_offset += 64 - (bit_offset % 64);
1051 int start_long_index = bit_offset / 64;
1052 int end_long_index = start_long_index;
1053 int start_offset = bit_offset % 64;
1054 bit_offset += bits_per_biome;
1056 unsigned int raw_id;
1057 if (start_long_index == end_long_index)
1059 raw_id =
static_cast<unsigned int>(data_array[start_long_index] >> start_offset);
1063 int end_offset = 64 - start_offset;
1064 raw_id =
static_cast<unsigned int>(data_array[start_long_index] >> start_offset | data_array[end_long_index] << end_offset);
1066 raw_id &= individual_value_mask;
1070 raw_id = palette[raw_id];
1073 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)