Add callback to preserve node metadata as item metadata
authorashtrayoz <33517241+ashtrayoz@users.noreply.github.com>
Thu, 9 Nov 2017 12:29:04 +0000 (23:29 +1100)
committerparamat <mat.gregory@virginmedia.com>
Thu, 14 Dec 2017 20:54:04 +0000 (20:54 +0000)
builtin/game/falling.lua
builtin/game/item.lua
doc/lua_api.txt

index 1876cf2a89c49af3cc71183b65bb03c5eaa8257f..436350fa1931e6c7e67e76f206ad9de23cdc947c 100644 (file)
@@ -150,8 +150,22 @@ end
 
 local function drop_attached_node(p)
        local n = core.get_node(p)
+       local drops = core.get_node_drops(n, "")
+       local def = core.registered_items[n.name]
+       if def and def.preserve_metadata then
+               local oldmeta = core.get_meta(p):to_table().fields
+               -- Copy pos and node because the callback can modify them.
+               local pos_copy = {x=p.x, y=p.y, z=p.z}
+               local node_copy = {name=n.name, param1=n.param1, param2=n.param2}
+               local drop_stacks = {}
+               for k, v in pairs(drops) do
+                       drop_stacks[k] = ItemStack(v)
+               end
+               drops = drop_stacks
+               def.preserve_metadata(pos_copy, node_copy, oldmeta, drops)
+       end
        core.remove_node(p)
-       for _, item in pairs(core.get_node_drops(n, "")) do
+       for _, item in pairs(drops) do
                local pos = {
                        x = p.x + math.random()/2 - 0.25,
                        y = p.y + math.random()/2 - 0.25,
index 5e5696ff5fdb644865bde851afaaf63f6b59eeec..a7176711f952da0f25c9b52497e0a11b85c04416 100644 (file)
@@ -579,6 +579,20 @@ function core.node_dig(pos, node, digger)
                digger:set_wielded_item(wielded)
        end
 
+       -- Check to see if metadata should be preserved.
+       if def and def.preserve_metadata then
+               local oldmeta = core.get_meta(pos):to_table().fields
+               -- Copy pos and node because the callback can modify them.
+               local pos_copy = {x=pos.x, y=pos.y, z=pos.z}
+               local node_copy = {name=node.name, param1=node.param1, param2=node.param2}
+               local drop_stacks = {}
+               for k, v in pairs(drops) do
+                       drop_stacks[k] = ItemStack(v)
+               end
+               drops = drop_stacks
+               def.preserve_metadata(pos_copy, node_copy, oldmeta, drops)
+       end
+
        -- Handle drops
        core.handle_node_drops(pos, drops, digger)
 
index d3b493fc3f6aa6bafeb85d601906f8f1af6a68d3..7ffd17a42b05d615db810cdbe926bc978ae9c980 100644 (file)
@@ -4710,6 +4710,13 @@ Definition tables
         ^ interval. Default: nil.
         ^ Warning: making a liquid node 'floodable' does not work and may cause problems. ]]
 
+       preserve_metadata = func(pos, oldnode, oldmeta, drops) --[[
+       ^ Called when oldnode is about be converted to an item, but before the
+         node is deleted from the world or the drops are added.  This is generally
+         the result of either the node being dug or an attached node becoming detached.
+       ^ drops is a table of ItemStacks, so any metadata to be preserved can be
+         added directly to one or more of the dropped items.  See "ItemStackMetaRef".
+       ^ default: nil ]]
         after_place_node = func(pos, placer, itemstack, pointed_thing) --[[
         ^ Called after constructing node when node was placed using
           minetest.item_place_node / minetest.place_node