]> git.lizzy.rs Git - minetest.git/blobdiff - builtin/game/item.lua
Add buttons to ContentDB in game bar and configure world (#9944)
[minetest.git] / builtin / game / item.lua
index 5e5696ff5fdb644865bde851afaaf63f6b59eeec..f680ce0d4bd9eb1e13be985665ffb709d670b122 100644 (file)
@@ -33,7 +33,7 @@ function core.get_pointed_thing_position(pointed_thing, above)
                -- The position where a node would be dug
                return pointed_thing.under
        elseif pointed_thing.type == "object" then
-               return pointed_thing.ref and pointed_thing.ref:getpos()
+               return pointed_thing.ref and pointed_thing.ref:get_pos()
        end
 end
 
@@ -197,7 +197,7 @@ function core.get_node_drops(node, toolname)
                return {nodename}
        elseif type(drop) == "string" then
                -- itemstring drop
-               return {drop}
+               return drop ~= "" and {drop} or {}
        elseif drop.items == nil then
                -- drop = {} to disable default drop
                return {}
@@ -206,7 +206,6 @@ function core.get_node_drops(node, toolname)
        -- Extended drop table
        local got_items = {}
        local got_count = 0
-       local _, item, tool
        for _, item in ipairs(drop.items) do
                local good_rarity = true
                local good_tool = true
@@ -251,20 +250,16 @@ local function user_name(user)
        return user and user:get_player_name() or ""
 end
 
-local function is_protected(pos, name)
-       return core.is_protected(pos, name) and
-               not minetest.check_player_privs(name, "protection_bypass")
-end
-
 -- Returns a logging function. For empty names, does not log.
 local function make_log(name)
        return name ~= "" and core.log or function() end
 end
 
-function core.item_place_node(itemstack, placer, pointed_thing, param2)
+function core.item_place_node(itemstack, placer, pointed_thing, param2,
+               prevent_after_place)
        local def = itemstack:get_definition()
        if def.type ~= "node" or pointed_thing.type ~= "node" then
-               return itemstack, false
+               return itemstack, nil
        end
 
        local under = pointed_thing.under
@@ -277,7 +272,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
        if not oldnode_under or not oldnode_above then
                log("info", playername .. " tried to place"
                        .. " node in unloaded position " .. core.pos_to_string(above))
-               return itemstack, false
+               return itemstack, nil
        end
 
        local olddef_under = core.registered_nodes[oldnode_under.name]
@@ -289,7 +284,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
                log("info", playername .. " tried to place"
                        .. " node in invalid position " .. core.pos_to_string(above)
                        .. ", replacing " .. oldnode_above.name)
-               return itemstack, false
+               return itemstack, nil
        end
 
        -- Place above pointed node
@@ -301,18 +296,15 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
                place_to = {x = under.x, y = under.y, z = under.z}
        end
 
-       if is_protected(place_to, playername) then
+       if core.is_protected(place_to, playername) then
                log("action", playername
                                .. " tried to place " .. def.name
                                .. " at protected position "
                                .. core.pos_to_string(place_to))
                core.record_protection_violation(place_to, playername)
-               return itemstack
+               return itemstack, nil
        end
 
-       log("action", playername .. " places node "
-               .. def.name .. " at " .. core.pos_to_string(place_to))
-
        local oldnode = core.get_node(place_to)
        local newnode = {name = def.name, param1 = 0, param2 = param2 or 0}
 
@@ -330,7 +322,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
        -- Calculate the direction for furnaces and chests and stuff
        elseif (def.paramtype2 == "facedir" or
                        def.paramtype2 == "colorfacedir") and not param2 then
-               local placer_pos = placer and placer:getpos()
+               local placer_pos = placer and placer:get_pos()
                if placer_pos then
                        local dir = {
                                x = above.x - placer_pos.x,
@@ -338,7 +330,7 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
                                z = above.z - placer_pos.z
                        }
                        newnode.param2 = core.dir_to_facedir(dir)
-                       log("action", "facedir: " .. newnode.param2)
+                       log("info", "facedir: " .. newnode.param2)
                end
        end
 
@@ -366,16 +358,27 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
                not builtin_shared.check_attached_node(place_to, newnode) then
                log("action", "attached node " .. def.name ..
                        " can not be placed at " .. core.pos_to_string(place_to))
-               return itemstack, false
+               return itemstack, nil
        end
 
+       log("action", playername .. " places node "
+               .. def.name .. " at " .. core.pos_to_string(place_to))
+
        -- Add node and update
        core.add_node(place_to, newnode)
 
+       -- Play sound if it was done by a player
+       if playername ~= "" and def.sounds and def.sounds.place then
+               core.sound_play(def.sounds.place, {
+                       pos = place_to,
+                       exclude_player = playername,
+               }, true)
+       end
+
        local take_item = true
 
        -- Run callback
-       if def.after_place_node then
+       if def.after_place_node and not prevent_after_place then
                -- Deepcopy place_to and pointed_thing because callback can modify it
                local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
                local pointed_thing_copy = copy_pointed_thing(pointed_thing)
@@ -400,9 +403,10 @@ function core.item_place_node(itemstack, placer, pointed_thing, param2)
        if take_item then
                itemstack:take_item()
        end
-       return itemstack, true
+       return itemstack, place_to
 end
 
+-- deprecated, item_place does not call this
 function core.item_place_object(itemstack, placer, pointed_thing)
        local pos = core.get_pointed_thing_position(pointed_thing, true)
        if pos ~= nil then
@@ -420,14 +424,15 @@ function core.item_place(itemstack, placer, pointed_thing, param2)
                local nn = n.name
                if core.registered_nodes[nn] and core.registered_nodes[nn].on_rightclick then
                        return core.registered_nodes[nn].on_rightclick(pointed_thing.under, n,
-                                       placer, itemstack, pointed_thing) or itemstack, false
+                                       placer, itemstack, pointed_thing) or itemstack, nil
                end
        end
 
+       -- Place if node, otherwise do nothing
        if itemstack:get_definition().type == "node" then
                return core.item_place_node(itemstack, placer, pointed_thing, param2)
        end
-       return itemstack
+       return itemstack, nil
 end
 
 function core.item_secondary_use(itemstack, placer)
@@ -465,9 +470,17 @@ function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed
                        return result
                end
        end
+       local def = itemstack:get_definition()
        if itemstack:take_item() ~= nil then
                user:set_hp(user:get_hp() + hp_change)
 
+               if def and def.sound and def.sound.eat then
+                       core.sound_play(def.sound.eat, {
+                               pos = user:get_pos(),
+                               max_hear_distance = 16
+                       }, true)
+               end
+
                if replace_with_item then
                        if itemstack:is_empty() then
                                itemstack:add_item(replace_with_item)
@@ -477,7 +490,7 @@ function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed
                                if inv and inv:room_for_item("main", {name=replace_with_item}) then
                                        inv:add_item("main", replace_with_item)
                                else
-                                       local pos = user:getpos()
+                                       local pos = user:get_pos()
                                        pos.y = math.floor(pos.y + 0.5)
                                        core.add_item(pos, replace_with_item)
                                end
@@ -546,7 +559,7 @@ function core.node_dig(pos, node, digger)
                return
        end
 
-       if is_protected(pos, diggername) then
+       if core.is_protected(pos, diggername) then
                log("action", diggername
                                .. " tried to dig " .. node.name
                                .. " at protected position "
@@ -569,16 +582,33 @@ function core.node_dig(pos, node, digger)
                        wielded = wdef.after_use(wielded, digger, node, dp) or wielded
                else
                        -- Wear out tool
-                       if not core.settings:get_bool("creative_mode") then
+                       if not core.is_creative_enabled(diggername) then
                                wielded:add_wear(dp.wear)
                                if wielded:get_count() == 0 and wdef.sound and wdef.sound.breaks then
-                                       core.sound_play(wdef.sound.breaks, {pos = pos, gain = 0.5})
+                                       core.sound_play(wdef.sound.breaks, {
+                                               pos = pos,
+                                               gain = 0.5
+                                       }, true)
                                end
                        end
                end
                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)
 
@@ -590,6 +620,14 @@ function core.node_dig(pos, node, digger)
        -- Remove node and update
        core.remove_node(pos)
 
+       -- Play sound if it was done by a player
+       if diggername ~= "" and def and def.sounds and def.sounds.dug then
+               core.sound_play(def.sounds.dug, {
+                       pos = pos,
+                       exclude_player = diggername,
+               }, true)
+       end
+
        -- Run callback
        if def and def.after_dig_node then
                -- Copy pos and node because callback can modify them
@@ -599,15 +637,10 @@ function core.node_dig(pos, node, digger)
        end
 
        -- Run script hook
-       local _, callback
        for _, callback in ipairs(core.registered_on_dignodes) do
                local origin = core.callback_origins[callback]
                if origin then
                        core.set_last_run_mod(origin.mod)
-                       --print("Running " .. tostring(callback) ..
-                       --      " (a " .. origin.name .. " callback in " .. origin.mod .. ")")
-               else
-                       --print("No data associated with callback")
                end
 
                -- Copy pos and node because callback can modify them
@@ -642,6 +675,8 @@ end
 -- Item definition defaults
 --
 
+local default_stack_max = tonumber(minetest.settings:get("default_stack_max")) or 99
+
 core.nodedef_default = {
        -- Item properties
        type="node",
@@ -651,7 +686,7 @@ core.nodedef_default = {
        inventory_image = "",
        wield_image = "",
        wield_scale = {x=1,y=1,z=1},
-       stack_max = 99,
+       stack_max = default_stack_max,
        usable = false,
        liquids_pointable = false,
        tool_capabilities = nil,
@@ -715,7 +750,7 @@ core.craftitemdef_default = {
        inventory_image = "",
        wield_image = "",
        wield_scale = {x=1,y=1,z=1},
-       stack_max = 99,
+       stack_max = default_stack_max,
        liquids_pointable = false,
        tool_capabilities = nil,
 
@@ -753,7 +788,7 @@ core.noneitemdef_default = {  -- This is used for the hand and unknown items
        inventory_image = "",
        wield_image = "",
        wield_scale = {x=1,y=1,z=1},
-       stack_max = 99,
+       stack_max = default_stack_max,
        liquids_pointable = false,
        tool_capabilities = nil,