X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=builtin%2Fgame%2Fitem.lua;h=f680ce0d4bd9eb1e13be985665ffb709d670b122;hb=850af80089b3415265c4b4b744448509f776a52d;hp=5e5696ff5fdb644865bde851afaaf63f6b59eeec;hpb=b19241b9bc43e2d9721927ab32e5e56345721652;p=minetest.git diff --git a/builtin/game/item.lua b/builtin/game/item.lua index 5e5696ff5..f680ce0d4 100644 --- a/builtin/game/item.lua +++ b/builtin/game/item.lua @@ -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,