diff --git a/src/logic/scripting/lua/libs/libworld.cpp b/src/logic/scripting/lua/libs/libworld.cpp index 1acc1ad7..832f2e2e 100644 --- a/src/logic/scripting/lua/libs/libworld.cpp +++ b/src/logic/scripting/lua/libs/libworld.cpp @@ -7,6 +7,7 @@ #include "coders/compression.hpp" #include "coders/gzip.hpp" #include "coders/json.hpp" +#include "coders/rle.hpp" #include "engine/Engine.hpp" #include "files/engine_paths.hpp" #include "files/files.hpp" @@ -123,45 +124,44 @@ static int l_get_generator(lua::State* L) { } static int l_get_chunk_data(lua::State* L) { - int x = (int)lua::tointeger(L, 1); - int y = (int)lua::tointeger(L, 2); + int x = static_cast(lua::tointeger(L, 1)); + int y = static_cast(lua::tointeger(L, 2)); const auto& chunk = level->chunks->getChunk(x, y); if (chunk == nullptr) { lua::pushnil(L); return 0; } - bool compress = false; + bool compress = true; if (lua::gettop(L) >= 3) { compress = lua::toboolean(L, 3); } std::vector chunk_data; if (compress) { - size_t rle_compressed_size; - size_t gzip_compressed_size; + // 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); + } + const auto& data_ptr = chunk->encode(); ubyte* data = data_ptr.get(); - const auto& rle_compressed_data_ptr = compression::compress( - data, - CHUNK_DATA_LEN, - rle_compressed_size, - compression::Method::EXTRLE16 - ); - const auto& gzip_compressed_data = compression::compress( - rle_compressed_data_ptr.get(), - rle_compressed_size, - gzip_compressed_size, - compression::Method::GZIP + + size_t rle_compressed_size = + extrle::encode16(data, CHUNK_DATA_LEN, rlebuffer.data()); + + const auto gzip_compressed_data = gzip::compress( + rlebuffer.data(), rle_compressed_size ); auto tmp = dataio::h2le(rle_compressed_size); - chunk_data.reserve(gzip_compressed_size + sizeof(tmp)); + chunk_data.reserve(gzip_compressed_data.size() + sizeof(tmp)); chunk_data.insert( chunk_data.begin() + 0, (char*)&tmp, ((char*)&tmp) + sizeof(tmp) ); chunk_data.insert( chunk_data.begin() + sizeof(tmp), - gzip_compressed_data.get(), - gzip_compressed_data.get() + gzip_compressed_size + gzip_compressed_data.data(), + gzip_compressed_data.data() + gzip_compressed_data.size() ); } else { const auto& data = chunk->encode(); @@ -174,10 +174,10 @@ static int l_get_chunk_data(lua::State* L) { } static int l_set_chunk_data(lua::State* L) { - int x = (int)lua::tointeger(L, 1); - int y = (int)lua::tointeger(L, 2); + int x = static_cast(lua::tointeger(L, 1)); + int y = static_cast(lua::tointeger(L, 2)); auto buffer = lua::touserdata(L, 3); - bool is_compressed = false; + bool is_compressed = true; if (lua::gettop(L) >= 4) { is_compressed = lua::toboolean(L, 4); } @@ -207,38 +207,32 @@ static int l_set_chunk_data(lua::State* L) { } auto chunksController = controller->getChunksController(); - if (chunksController == nullptr) { - return 1; + if (chunksController->lighting == nullptr) { + return lua::pushboolean(L, true); } Lighting& lighting = *chunksController->lighting; chunk->updateHeights(); - lighting.buildSkyLight(x, y); - chunk->flags.modified = true; + chunk->flags.loadedLights = false; + chunk->flags.lighted = false; + chunk->setModifiedAndUnsaved(); + Lighting::prebuildSkyLight(*chunk, *indices); lighting.onChunkLoaded(x, y, true); - chunk = level->chunks->getChunk(x - 1, y); - if (chunk != nullptr) { - chunk->flags.modified = true; - lighting.onChunkLoaded(x - 1, y, true); - } - chunk = level->chunks->getChunk(x + 1, y); - if (chunk != nullptr) { - chunk->flags.modified = true; - lighting.onChunkLoaded(x + 1, y, true); - } - chunk = level->chunks->getChunk(x, y - 1); - if (chunk != nullptr) { - chunk->flags.modified = true; - lighting.onChunkLoaded(x, y - 1, true); - } - chunk = level->chunks->getChunk(x, y + 1); - if (chunk != nullptr) { - chunk->flags.modified = true; - lighting.onChunkLoaded(x, y + 1, true); + for (int lz = -1; lz <= 1; lz++) { + for (int lx = -1; lx <= 1; lx++) { + if (std::abs(lx) + std::abs(lz) != 1) { + continue; + } + chunk = level->chunks->getChunk(x + lx, y + lz); + if (chunk != nullptr) { + chunk->setModifiedAndUnsaved(); + lighting.onChunkLoaded(x - 1, y, true); + } + } } - return 1; + return lua::pushboolean(L, true); } static int l_count_chunks(lua::State* L) {