Implement locked chest; add after_place_node and after_dig_node node callbacks
[oweals/minetest.git] / builtin / item.lua
index 3abf30a6d2ab2b626328afdf16919bdecac2c7ea..c4bd24204864f1f9277ecb38159b865ae1de6259 100644 (file)
@@ -158,12 +158,12 @@ function minetest.item_place_node(itemstack, placer, pointed_thing)
                -- Add node and update
                minetest.env:add_node(pos, newnode)
 
-               -- Set metadata owner
-               if def.metadata_name ~= "" then
-                       minetest.env:get_meta(pos):set_owner(placer:get_player_name())
+               -- Run callback
+               if def.after_place_node then
+                       def.after_place_node(pos, placer)
                end
 
-               -- Run script hook
+               -- Run script hook (deprecated)
                local _, callback
                for _, callback in ipairs(minetest.registered_on_placenodes) do
                        callback(pos, newnode, placer)
@@ -192,7 +192,17 @@ function minetest.item_place(itemstack, placer, pointed_thing)
 end
 
 function minetest.item_drop(itemstack, dropper, pos)
-       minetest.env:add_item(pos, itemstack)
+       if dropper.get_player_name then
+               local v = dropper:get_look_dir()
+               local p = {x=pos.x+v.x, y=pos.y+1.5+v.y, z=pos.z+v.z}
+               local obj = minetest.env:add_item(p, itemstack)
+               v.x = v.x*2
+               v.y = v.y*2 + 1
+               v.z = v.z*2
+               obj:setvelocity(v)
+       else
+               minetest.env:add_item(pos, itemstack)
+       end
        return ""
 end
 
@@ -227,15 +237,6 @@ function minetest.node_dig(pos, node, digger)
                return
        end
 
-       local meta = minetest.env:get_meta(pos)
-       if meta ~= nil and not meta:get_allow_removal() then
-               minetest.debug("dig prevented by metadata")
-               minetest.log("info", digger:get_player_name() .. " tried to dig "
-                       .. node.name .. ", but removal is disabled by metadata "
-                       .. minetest.pos_to_string(pos))
-               return
-       end
-
        minetest.log('action', digger:get_player_name() .. " digs "
                .. node.name .. " at " .. minetest.pos_to_string(pos))
 
@@ -255,17 +256,73 @@ function minetest.node_dig(pos, node, digger)
                        digger:get_inventory():add_item("main", dropped_item)
                end
        end
+       
+       local oldnode = nil
+       local oldmetadata = nil
+       if def.after_dig_node then
+               oldnode = node;
+               oldmetadata = minetest.env:get_meta(pos):to_table()
+       end
 
        -- Remove node and update
        minetest.env:remove_node(pos)
+       
+       -- Run callback
+       if def.after_dig_node then
+               def.after_dig_node(pos, oldnode, oldmetadata, digger)
+       end
 
-       -- Run script hook
+       -- Run script hook (deprecated)
        local _, callback
        for _, callback in ipairs(minetest.registered_on_dignodes) do
                callback(pos, node, digger)
        end
 end
 
+function minetest.node_metadata_inventory_move_allow_all(pos, from_list,
+               from_index, to_list, to_index, count, player)
+       minetest.log("verbose", "node_metadata_inventory_move_allow_all")
+       local meta = minetest.env:get_meta(pos)
+       local inv = meta:get_inventory()
+
+       local from_stack = inv:get_stack(from_list, from_index)
+       local taken_items = from_stack:take_item(count)
+       inv:set_stack(from_list, from_index, from_stack)
+
+       local to_stack = inv:get_stack(to_list, to_index)
+       to_stack:add_item(taken_items)
+       inv:set_stack(to_list, to_index, to_stack)
+end
+
+function minetest.node_metadata_inventory_offer_allow_all(pos, listname, index, stack, player)
+       minetest.log("verbose", "node_metadata_inventory_offer_allow_all")
+       local meta = minetest.env:get_meta(pos)
+       local inv = meta:get_inventory()
+       local the_stack = inv:get_stack(listname, index)
+       the_stack:add_item(stack)
+       inv:set_stack(listname, index, the_stack)
+       return ItemStack("")
+end
+
+function minetest.node_metadata_inventory_take_allow_all(pos, listname, index, count, player)
+       minetest.log("verbose", "node_metadata_inventory_take_allow_all")
+       local meta = minetest.env:get_meta(pos)
+       local inv = meta:get_inventory()
+       local the_stack = inv:get_stack(listname, index)
+       local taken_items = the_stack:take_item(count)
+       inv:set_stack(listname, index, the_stack)
+       return taken_items
+end
+
+-- This is used to allow mods to redefine minetest.item_place and so on
+-- NOTE: This is not the preferred way. Preferred way is to provide enough
+--       callbacks to not require redefining global functions. -celeron55
+local function redef_wrapper(table, name)
+       return function(...)
+               return table[name](...)
+       end
+end
+
 --
 -- Item definition defaults
 --
@@ -285,12 +342,18 @@ minetest.nodedef_default = {
        tool_capabilities = nil,
 
        -- Interaction callbacks
-       on_place = minetest.item_place,
-       on_drop = minetest.item_drop,
+       on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
+       on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
        on_use = nil,
 
-       on_punch = minetest.node_punch,
-       on_dig = minetest.node_dig,
+       on_punch = redef_wrapper(minetest, 'node_punch'), -- minetest.node_punch
+       on_dig = redef_wrapper(minetest, 'node_dig'), -- minetest.node_dig
+
+       on_receive_fields = nil,
+       
+       on_metadata_inventory_move = minetest.node_metadata_inventory_move_allow_all,
+       on_metadata_inventory_offer = minetest.node_metadata_inventory_offer_allow_all,
+       on_metadata_inventory_take = minetest.node_metadata_inventory_take_allow_all,
 
        -- Node properties
        drawtype = "normal",
@@ -311,7 +374,6 @@ minetest.nodedef_default = {
        diggable = true,
        climbable = false,
        buildable_to = false,
-       metadata_name = "",
        liquidtype = "none",
        liquid_alternative_flowing = "",
        liquid_alternative_source = "",
@@ -336,8 +398,8 @@ minetest.craftitemdef_default = {
        tool_capabilities = nil,
 
        -- Interaction callbacks
-       on_place = minetest.item_place,
-       on_drop = minetest.item_drop,
+       on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
+       on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
        on_use = nil,
 }
 
@@ -354,8 +416,8 @@ minetest.tooldef_default = {
        tool_capabilities = nil,
 
        -- Interaction callbacks
-       on_place = minetest.item_place,
-       on_drop = minetest.item_drop,
+       on_place = redef_wrapper(minetest, 'item_place'), -- minetest.item_place
+       on_drop = redef_wrapper(minetest, 'item_drop'), -- minetest.item_drop
        on_use = nil,
 }
 
@@ -377,4 +439,3 @@ minetest.noneitemdef_default = {  -- This is used for the hand and unknown items
        on_use = nil,
 }
 
-