From 6cae75e02f78e24a951ba7e4b74dd25bb3cc3885 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 20 Aug 2025 23:49:18 +0300 Subject: [PATCH 1/6] fix extended blocks destruction particles spawn spread, offset --- res/content/base/scripts/world.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/res/content/base/scripts/world.lua b/res/content/base/scripts/world.lua index 4b78a3f1..7f468c29 100644 --- a/res/content/base/scripts/world.lua +++ b/res/content/base/scripts/world.lua @@ -1,6 +1,11 @@ function on_block_broken(id, x, y, z, playerid) if gfx then - gfx.particles.emit({x+0.5, y+0.5, z+0.5}, 64, { + local size = {block.get_size(id)} + gfx.particles.emit({ + x + size[1] * 0.5, + y + size[1] * 0.5, + z + size[1] * 0.5 + }, 64, { lifetime=1.0, spawn_interval=0.0001, explosion={4, 4, 4}, @@ -8,7 +13,7 @@ function on_block_broken(id, x, y, z, playerid) random_sub_uv=0.1, size={0.1, 0.1, 0.1}, spawn_shape="box", - spawn_spread={0.4, 0.4, 0.4} + spawn_spread=vec3.mul(size, 0.4) }) end From a9d40c312c1a5176f8878ac1804ee70e27ce8d4d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 20 Aug 2025 23:52:41 +0300 Subject: [PATCH 2/6] extract one texture from custom model if not assigned --- src/graphics/render/ModelsGenerator.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/graphics/render/ModelsGenerator.cpp b/src/graphics/render/ModelsGenerator.cpp index a5782f95..b4f42348 100644 --- a/src/graphics/render/ModelsGenerator.cpp +++ b/src/graphics/render/ModelsGenerator.cpp @@ -6,6 +6,7 @@ #include "voxels/Block.hpp" #include "content/Content.hpp" #include "debug/Logger.hpp" +#include "core_defs.hpp" static debug::Logger logger("models-generator"); @@ -67,11 +68,18 @@ void ModelsGenerator::prepareModel( } else { auto srcModel = assets.get(blockModel.name); if (srcModel) { + bool defaultAssigned = variant.textureFaces[0] != TEXTURE_NOTFOUND; auto model = std::make_unique(*srcModel); for (auto& mesh : model->meshes) { if (mesh.texture.length() && mesh.texture[0] == '$') { int index = std::stoll(mesh.texture.substr(1)); mesh.texture = "blocks:" + variant.textureFaces[index]; + } else if (!defaultAssigned && !mesh.texture.empty()) { + size_t sepPos = mesh.texture.find(':'); + if (sepPos == std::string::npos) + continue; + variant.textureFaces[0] = mesh.texture.substr(sepPos + 1); + defaultAssigned = true; } } blockModel.name = modelName; From a46aafa562d22740948beba23b582850587ee4a2 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 22 Aug 2025 22:26:43 +0300 Subject: [PATCH 3/6] fix fragment:place rotation (#593) * fix fragment:place rotation --- .../scripting/lua/libs/libgeneration.cpp | 20 ++++++++++++++++--- src/logic/scripting/lua/lua_custom_types.hpp | 11 ++++++---- .../lua/usertypes/lua_type_voxelfragment.cpp | 19 +++++++++++------- src/world/generator/VoxelFragment.cpp | 2 +- src/world/generator/VoxelFragment.hpp | 3 +-- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/logic/scripting/lua/libs/libgeneration.cpp b/src/logic/scripting/lua/libs/libgeneration.cpp index 291b847f..f0cbb2f8 100644 --- a/src/logic/scripting/lua/libs/libgeneration.cpp +++ b/src/logic/scripting/lua/libs/libgeneration.cpp @@ -16,7 +16,7 @@ using namespace scripting; static int l_save_fragment(lua::State* L) { auto fragment = lua::touserdata(L, 1); auto file = lua::require_string(L, 2); - auto map = fragment->getFragment()->serialize(); + auto map = fragment->getFragment(0)->serialize(); auto bytes = json::to_binary(map, true); io::write_bytes(file, bytes.data(), bytes.size()); return 0; @@ -30,8 +30,14 @@ static int l_create_fragment(lua::State* L) { auto fragment = VoxelFragment::create(*level, pointA, pointB, crop, saveEntities); + std::array, 4> fragmentVariants { + std::move(fragment) + }; + for (size_t i = 1; i < 4; i++) { + fragmentVariants[i] = fragmentVariants[i - 1]->rotated(*content); + } return lua::newuserdata( - L, std::shared_ptr(std::move(fragment)) + L, std::move(fragmentVariants) ); } @@ -45,7 +51,15 @@ static int l_load_fragment(lua::State* L) { auto fragment = std::make_shared(); fragment->deserialize(map); fragment->prepare(*content); - return lua::newuserdata(L, std::move(fragment)); + std::array, 4> fragmentVariants { + std::move(fragment) + }; + for (size_t i = 1; i < 4; i++) { + fragmentVariants[i] = fragmentVariants[i - 1]->rotated(*content); + } + return lua::newuserdata( + L, std::move(fragmentVariants) + ); } /// @brief Get a list of all world generators diff --git a/src/logic/scripting/lua/lua_custom_types.hpp b/src/logic/scripting/lua/lua_custom_types.hpp index 1185ecbe..87080274 100644 --- a/src/logic/scripting/lua/lua_custom_types.hpp +++ b/src/logic/scripting/lua/lua_custom_types.hpp @@ -2,6 +2,7 @@ #include #include +#include #include "lua_commons.hpp" @@ -55,14 +56,16 @@ namespace lua { static_assert(!std::is_abstract()); class LuaVoxelFragment : public Userdata { - std::shared_ptr fragment; + std::array, 4> fragmentVariants; public: - LuaVoxelFragment(std::shared_ptr fragment); + LuaVoxelFragment( + std::array, 4> fragmentVariants + ); virtual ~LuaVoxelFragment(); - std::shared_ptr getFragment() const { - return fragment; + std::shared_ptr getFragment(size_t rotation) const { + return fragmentVariants.at(rotation & 0b11); } const std::string& getTypeName() const override { diff --git a/src/logic/scripting/lua/usertypes/lua_type_voxelfragment.cpp b/src/logic/scripting/lua/usertypes/lua_type_voxelfragment.cpp index f123be6f..271a2a5a 100644 --- a/src/logic/scripting/lua/usertypes/lua_type_voxelfragment.cpp +++ b/src/logic/scripting/lua/usertypes/lua_type_voxelfragment.cpp @@ -8,15 +8,20 @@ using namespace lua; -LuaVoxelFragment::LuaVoxelFragment(std::shared_ptr fragment) - : fragment(std::move(fragment)) {} +LuaVoxelFragment::LuaVoxelFragment( + std::array, 4> fragmentVariants +) + : fragmentVariants(std::move(fragmentVariants)) { +} LuaVoxelFragment::~LuaVoxelFragment() { } static int l_crop(lua::State* L) { if (auto fragment = touserdata(L, 1)) { - fragment->getFragment()->crop(); + for (size_t i = 0; i < 4; i++) { + fragment->getFragment(i)->crop(); + } } return 0; } @@ -24,9 +29,9 @@ static int l_crop(lua::State* L) { static int l_place(lua::State* L) { if (auto fragment = touserdata(L, 1)) { auto offset = tovec3(L, 2); - int rotation = tointeger(L, 3) & 0b11; - fragment->getFragment()->place( - *scripting::level->chunks, offset, rotation + int rotation = tointeger(L, 3); + fragment->getFragment(rotation)->place( + *scripting::level->chunks, offset ); } return 0; @@ -50,7 +55,7 @@ static int l_meta_index(lua::State* L) { if (isstring(L, 2)) { auto fieldname = tostring(L, 2); if (!std::strcmp(fieldname, "size")) { - return pushivec(L, fragment->getFragment()->getSize()); + return pushivec(L, fragment->getFragment(0)->getSize()); } else { auto found = methods.find(tostring(L, 2)); if (found != methods.end()) { diff --git a/src/world/generator/VoxelFragment.cpp b/src/world/generator/VoxelFragment.cpp index 344f0450..8e86c1a7 100644 --- a/src/world/generator/VoxelFragment.cpp +++ b/src/world/generator/VoxelFragment.cpp @@ -171,7 +171,7 @@ void VoxelFragment::prepare(const Content& content) { } void VoxelFragment::place( - GlobalChunks& chunks, const glm::ivec3& offset, ubyte rotation + GlobalChunks& chunks, const glm::ivec3& offset ) { auto& structVoxels = getRuntimeVoxels(); for (int y = 0; y < size.y; y++) { diff --git a/src/world/generator/VoxelFragment.hpp b/src/world/generator/VoxelFragment.hpp index 81944900..8b49110e 100644 --- a/src/world/generator/VoxelFragment.hpp +++ b/src/world/generator/VoxelFragment.hpp @@ -45,8 +45,7 @@ public: /// @brief Place fragment to the world /// @param offset target location - /// @param rotation rotation index - void place(GlobalChunks& chunks, const glm::ivec3& offset, ubyte rotation); + void place(GlobalChunks& chunks, const glm::ivec3& offset); /// @brief Create structure copy rotated 90 deg. clockwise std::unique_ptr rotated(const Content& content) const; From 25f4c7fbdd693cfd280064c827ab85746be0ef96 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 23 Aug 2025 11:47:35 +0300 Subject: [PATCH 4/6] fix bytearray:insert (#594) --- dev/tests/bytearray.lua | 6 ++++++ res/modules/internal/bytearray.lua | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dev/tests/bytearray.lua b/dev/tests/bytearray.lua index 432dfbf5..415768c6 100644 --- a/dev/tests/bytearray.lua +++ b/dev/tests/bytearray.lua @@ -28,3 +28,9 @@ assert(#arr == arr:get_capacity()) arr = Bytearray({0, 2, 7, 1, 16, 75, 25}) assert(arr[6] == 75) + +arr:insert(2, {5, 6}) + +assert(arr[#arr] == 25) +assert(arr[2] == 5) +assert(arr[3] == 6) diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index 457587d5..56795499 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -71,7 +71,7 @@ local function insert(self, index, b) if self.size + elems > self.capacity then grow_buffer(self, elems) end - for i=self.size, index - 1, -1 do + for i = self.size - 1, index - 1, -1 do self.bytes[i + elems] = self.bytes[i] end if _type(b) == "number" then From 8593250f65adaf28b1c7f2ca16e1efebfd5fb408 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 23 Aug 2025 18:52:55 +0300 Subject: [PATCH 5/6] fix generation.create_fragment (#596) --- src/logic/scripting/lua/libs/libgeneration.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/logic/scripting/lua/libs/libgeneration.cpp b/src/logic/scripting/lua/libs/libgeneration.cpp index f0cbb2f8..b0b86a2a 100644 --- a/src/logic/scripting/lua/libs/libgeneration.cpp +++ b/src/logic/scripting/lua/libs/libgeneration.cpp @@ -30,6 +30,7 @@ static int l_create_fragment(lua::State* L) { auto fragment = VoxelFragment::create(*level, pointA, pointB, crop, saveEntities); + fragment->prepare(*content); std::array, 4> fragmentVariants { std::move(fragment) }; From 8c7409eed15a35629e9ae764b217bba4936c97e4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sat, 23 Aug 2025 19:46:07 +0300 Subject: [PATCH 6/6] add bytearray option for generation.load_fragment (#597) --- src/logic/scripting/lua/libs/libgeneration.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/logic/scripting/lua/libs/libgeneration.cpp b/src/logic/scripting/lua/libs/libgeneration.cpp index 291b847f..2dd5746b 100644 --- a/src/logic/scripting/lua/libs/libgeneration.cpp +++ b/src/logic/scripting/lua/libs/libgeneration.cpp @@ -36,11 +36,19 @@ static int l_create_fragment(lua::State* L) { } static int l_load_fragment(lua::State* L) { - io::path path = lua::require_string(L, 1); - if (!io::exists(path)) { - throw std::runtime_error("file "+path.string()+" does not exist"); + dv::value map; + if (!lua::isstring(L, 1)) { + io::path path = lua::require_string(L, 1); + if (!io::exists(path)) { + throw std::runtime_error("file "+path.string()+" does not exist"); + } + map = io::read_binary_json(path); + } else { + auto bytearray = lua::bytearray_as_string(L, 1); + map = json::from_binary( + reinterpret_cast(bytearray.data()), bytearray.size() + ); } - auto map = io::read_binary_json(path); auto fragment = std::make_shared(); fragment->deserialize(map);