Preserve all node meta in displacement

Don't just preserve the stack, but assume that
any node with any meta could be displaced.
This commit is contained in:
Aaron Suen 2021-06-26 09:10:35 -04:00
parent dac2de09ac
commit 10a29b067b
4 changed files with 26 additions and 21 deletions

View File

@ -518,3 +518,20 @@ function nodecore.protection_test(pos, player)
return true
end
end
function nodecore.meta_serializable(meta)
local mt = type(meta)
if mt == "table" or mt == "userdata" then
if type(meta.to_table) == "function" then
meta = meta:to_table()
end
for _, list in pairs(meta.inventory or {}) do
for i, stack in pairs(list) do
if type(stack) == "userdata" then
list[i] = stack:to_string()
end
end
end
end
return meta
end

View File

@ -1,6 +1,6 @@
-- LUALOCALS < ---------------------------------------------------------
local ipairs, minetest, nodecore, pairs, type, vector
= ipairs, minetest, nodecore, pairs, type, vector
local ipairs, minetest, nodecore, pairs, vector
= ipairs, minetest, nodecore, pairs, vector
-- LUALOCALS > ---------------------------------------------------------
nodecore.register_falling_node_step,
@ -68,18 +68,7 @@ minetest.register_entity(":__builtin:falling_node", {
textures = {def and def.falling_visual or node.name},
})
meta = meta or {}
if type(meta.to_table) == "function" then
meta = meta:to_table()
end
for _, list in pairs(meta.inventory or {}) do
for i, stack in pairs(list) do
if type(stack) == "userdata" then
list[i] = stack:to_string()
end
end
end
self.meta = meta
self.meta = nodecore.meta_serializable(meta)
for _, func in ipairs(nodecore.registered_falling_node_on_setnodes) do
if func(self, node, meta) == true then return end

View File

@ -35,14 +35,13 @@ function minetest.node_dig(pos, node, digger, ...)
local mock = ItemStack(node.name)
mock:set_count(def.stack_max or 99)
local stack = nodecore.stack_get(pos)
nodecore.stack_set(pos, "")
local dmeta = minetest.serialize(
nodecore.meta_serializable(minetest.get_meta(pos)))
minetest.set_node(pos, {name = nodename})
nodecore.stack_set(pos, mock)
local meta = minetest.get_meta(pos)
meta:set_string("dstack", stack:to_string())
meta:set_string("dmeta", dmeta)
meta:set_string("dnode", minetest.serialize(node))
return nodecore.scaling_particles(pos, {
@ -69,8 +68,8 @@ nodecore.register_limited_abm({
if not (node and node.name) then
return minetest.remove_node(pos)
end
local stack = meta:get_string("dstack") or ""
local dmeta = minetest.deserialize(meta:get_string("dmeta"))
minetest.set_node(pos, node)
nodecore.stack_set(pos, stack)
if dmeta then minetest.get_meta(pos):from_table(dmeta) end
end
})

View File

@ -32,7 +32,7 @@ local function totedug(pos, _, _, digger)
local d = minetest.registered_items[n.name] or {}
if d and d.groups and d.groups.totable
and not protected(p, digger) then
local m = minetest.get_meta(p):to_table()
local m = nodecore.meta_serializable(minetest.get_meta(p))
for _, v1 in pairs(m.inventory or {}) do
for k2, v2 in pairs(v1) do
if type(v2) == "userdata" then