diff --git a/src/logic/scripting/lua/libs/libworld.cpp b/src/logic/scripting/lua/libs/libworld.cpp index 5db150b0..362d08c7 100644 --- a/src/logic/scripting/lua/libs/libworld.cpp +++ b/src/logic/scripting/lua/libs/libworld.cpp @@ -126,11 +126,21 @@ static int l_get_chunk_data(lua::State* L) { int x = static_cast(lua::tointeger(L, 1)); int z = static_cast(lua::tointeger(L, 2)); const auto& chunk = level->chunks->getChunk(x, z); + + std::vector chunkData; if (chunk == nullptr) { - lua::pushnil(L); - return 0; + auto& regions = level->getWorld()->wfile->getRegions(); + auto voxelData = regions.getVoxels(x, z); + if (voxelData == nullptr) { + return 0; + } + static util::Buffer rleBuffer(CHUNK_DATA_LEN * 2); + auto metadata = regions.getBlocksData(x, z); + chunkData = + compressed_chunks::encode(voxelData.get(), metadata, rleBuffer); + } else { + chunkData = compressed_chunks::encode(*chunk); } - auto chunkData = compressed_chunks::encode(*chunk); return lua::newuserdata(L, std::move(chunkData)); } diff --git a/src/voxels/compressed_chunks.cpp b/src/voxels/compressed_chunks.cpp index 64000a79..24cc02dd 100644 --- a/src/voxels/compressed_chunks.cpp +++ b/src/voxels/compressed_chunks.cpp @@ -2,28 +2,24 @@ #include "coders/rle.hpp" #include "coders/gzip.hpp" -#include "coders/byte_utils.hpp" + #include "files/WorldFiles.hpp" -#include "voxels/Chunk.hpp" inline constexpr int HAS_VOXELS = 0x1; inline constexpr int HAS_METADATA = 0x2; -std::vector compressed_chunks::encode(const Chunk& chunk) { - auto data = chunk.encode(); - - /// world.get_chunk_data is only available in the main Lua state - static util::Buffer rleBuffer; - if (rleBuffer.size() < CHUNK_DATA_LEN * 2) { - rleBuffer = util::Buffer(CHUNK_DATA_LEN * 2); - } +std::vector compressed_chunks::encode( + const ubyte* data, + const BlocksMetadata& metadata, + util::Buffer& rleBuffer +) { size_t rleCompressedSize = - extrle::encode16(data.get(), CHUNK_DATA_LEN, rleBuffer.data()); + extrle::encode16(data, CHUNK_DATA_LEN, rleBuffer.data()); const auto gzipCompressedData = gzip::compress( rleBuffer.data(), rleCompressedSize ); - auto metadataBytes = chunk.blocksMetadata.serialize(); + auto metadataBytes = metadata.serialize(); ByteBuilder builder(2 + 8 + gzipCompressedData.size() + metadataBytes.size()); builder.put(HAS_VOXELS | HAS_METADATA); // flags @@ -35,6 +31,14 @@ std::vector compressed_chunks::encode(const Chunk& chunk) { return builder.build(); } +std::vector compressed_chunks::encode(const Chunk& chunk) { + auto data = chunk.encode(); + + /// world.get_chunk_data is only available in the main Lua state + static util::Buffer rleBuffer(CHUNK_DATA_LEN * 2); + return encode(data.get(), chunk.blocksMetadata, rleBuffer); +} + static void read_voxel_data(ByteReader& reader, util::Buffer& dst) { size_t gzipCompressedSize = reader.getInt32(); diff --git a/src/voxels/compressed_chunks.hpp b/src/voxels/compressed_chunks.hpp index 2181669c..dd00bc66 100644 --- a/src/voxels/compressed_chunks.hpp +++ b/src/voxels/compressed_chunks.hpp @@ -1,13 +1,19 @@ #pragma once #include "typedefs.hpp" +#include "Chunk.hpp" +#include "coders/byte_utils.hpp" #include -class Chunk; class WorldRegions; namespace compressed_chunks { + std::vector encode( + const ubyte* voxelData, + const BlocksMetadata& metadata, + util::Buffer& rleBuffer + ); std::vector encode(const Chunk& chunk); void decode(Chunk& chunk, const ubyte* src, size_t size); void save(int x, int z, std::vector bytes, WorldRegions& regions);