diff --git a/doc/en/scripting/builtins/libinventory.md b/doc/en/scripting/builtins/libinventory.md index 8cf2d7c3e..172ec63e6 100644 --- a/doc/en/scripting/builtins/libinventory.md +++ b/doc/en/scripting/builtins/libinventory.md @@ -162,7 +162,19 @@ inventory.get_all_data( invid: int, -- slot index slot: int, -) -> table +) -> table | nil + +-- Sets the values ​​of all local item properties. +inventory.set_all_data( + -- inventory id + invid: int, + -- slot index + slot: int, + -- property:value table + fields: table, + -- clear other property values + [optional] clear: boolean = false +) ``` ```lua diff --git a/doc/ru/scripting/builtins/libinventory.md b/doc/ru/scripting/builtins/libinventory.md index 50ed8dccb..4a836f83b 100644 --- a/doc/ru/scripting/builtins/libinventory.md +++ b/doc/ru/scripting/builtins/libinventory.md @@ -170,7 +170,19 @@ inventory.get_all_data( invid: int, -- индекс слота slot: int, -) -> table +) -> table | nil + +-- Устанавливает значения локальных cвойств предмета. +inventory.set_all_data( + -- id инвентаря + invid: int, + -- индекс слота + slot: int, + -- таблица cвойство:значение + fields: table, + -- удалить остальные значения свойств + [опционально] clear: boolean = false +) ``` ```lua @@ -222,4 +234,4 @@ inventory.use( -- индекс слота slot: int ) -``` \ No newline at end of file +``` diff --git a/res/modules/internal/bytearray.lua b/res/modules/internal/bytearray.lua index 739bb7cea..58b33a520 100644 --- a/res/modules/internal/bytearray.lua +++ b/res/modules/internal/bytearray.lua @@ -12,11 +12,30 @@ FFI.cdef[[ } bytearray_t; ]] -local malloc = FFI.C.malloc local free = FFI.C.free + local FFIBytearray local bytearray_type +local allocated_bytes = 0 +local GC_THRESHOLD = 50 * 1024 * 1024 + +local function malloc(size) + local raw = FFI.C.malloc(size) + if raw == nil then + return nil + end + + allocated_bytes = allocated_bytes + size + + if allocated_bytes >= GC_THRESHOLD then + collectgarbage("step", 200) + allocated_bytes = 0 + end + + return raw +end + local function grow_buffer(self, elems) local new_capacity = math.ceil(self.capacity / 0.75 + elems) local prev = self.bytes diff --git a/src/items/ItemStack.hpp b/src/items/ItemStack.hpp index 91f2d3e74..4896bc39e 100644 --- a/src/items/ItemStack.hpp +++ b/src/items/ItemStack.hpp @@ -55,6 +55,16 @@ public: return fields; } + void setFields(dv::value&& table, bool clear) { + if (clear) { + fields = std::move(table); + return; + } + for (auto&& [key, value] : table.asObject()) { + fields[std::move(key)] = std::move(value); + } + } + bool hasFields() const { return fields != nullptr; } diff --git a/src/logic/scripting/lua/libs/libinventory.cpp b/src/logic/scripting/lua/libs/libinventory.cpp index 3ec9d2ca3..2aea52394 100644 --- a/src/logic/scripting/lua/libs/libinventory.cpp +++ b/src/logic/scripting/lua/libs/libinventory.cpp @@ -237,6 +237,14 @@ static int l_get_all_data(lua::State* L, ItemStack& stack) { return lua::pushvalue(L, stack.getFields()); } +static int l_set_all_data(lua::State* L, ItemStack& stack) { + if (!lua::istable(L, 3)) { + throw std::runtime_error("table expected as argument 1"); + } + stack.setFields(lua::tovalue(L, 3), lua::toboolean(L, 4)); + return 0; +} + static int l_has_data(lua::State* L, ItemStack& stack) { auto key = lua::tostring(L, 3); if (key == nullptr) { @@ -267,6 +275,7 @@ const luaL_Reg inventorylib[] = { {"get_data", lua::wrap>}, {"set_data", lua::wrap>}, {"get_all_data", lua::wrap>}, + {"set_all_data", lua::wrap>}, {"has_data", lua::wrap>}, {"create", lua::wrap}, {"remove", lua::wrap}, diff --git a/src/objects/rigging.cpp b/src/objects/rigging.cpp index f686bfbcf..f47f7c733 100644 --- a/src/objects/rigging.cpp +++ b/src/objects/rigging.cpp @@ -88,12 +88,22 @@ void Skeleton::deserialize(const dv::value& root) { void Skeleton::setConfig(std::shared_ptr rigConfig) { config = std::move(rigConfig); + + const auto& bones = config->getBones(); + pose.matrices.resize( - config->getBones().size(), glm::mat4(1.0f) + bones.size(), glm::mat4(1.0f) ); calculated.matrices.resize( - config->getBones().size(), glm::mat4(1.0f) + bones.size(), glm::mat4(1.0f) ); + + modelOverrides.resize(bones.size()); + flags.resize(bones.size()); + + for (size_t i = 0; i < bones.size(); i++) { + flags[i].visible = true; + } } static void get_all_nodes(std::vector& nodes, Bone* node) { diff --git a/src/voxels/blocks_agent.cpp b/src/voxels/blocks_agent.cpp index 9d1f0cc17..d72ddcceb 100644 --- a/src/voxels/blocks_agent.cpp +++ b/src/voxels/blocks_agent.cpp @@ -309,7 +309,9 @@ static inline voxel* raycast_blocks( } else { iend = {ix, iy, iz}; norm = {0, 0, 0}; - norm[steppedIndex] = -step[steppedIndex]; + if (steppedIndex != -1) { + norm[steppedIndex] = -step[steppedIndex]; + } return voxel; } }