diff --git a/builtin/falling.lua b/builtin/falling.lua index 3912727c3..903c5dfd0 100644 --- a/builtin/falling.lua +++ b/builtin/falling.lua @@ -91,6 +91,48 @@ function spawn_falling_node(p, nodename) obj:get_luaentity():set_node(nodename) end +function drop_attached_node(p) + local nn = minetest.env:get_node(p).name + minetest.env:remove_node(p) + for _,item in ipairs(minetest.get_node_drops(nn, "")) do + local pos = { + x = p.x + math.random(60)/60-0.3, + y = p.y + math.random(60)/60-0.3, + z = p.z + math.random(60)/60-0.3, + } + minetest.env:add_item(pos, item) + end +end + +function check_attached_node(p, n) + local def = minetest.registered_nodes[n.name] + local d = {x=0, y=0, z=0} + if def.paramtype2 == "wallmounted" then + if n.param2 == 0 then + d.y = 1 + elseif n.param2 == 1 then + d.y = -1 + elseif n.param2 == 2 then + d.x = 1 + elseif n.param2 == 3 then + d.x = -1 + elseif n.param2 == 4 then + d.z = 1 + elseif n.param2 == 5 then + d.z = -1 + end + else + d.y = -1 + end + local p2 = {x=p.x+d.x, y=p.y+d.y, z=p.z+d.z} + local nn = minetest.env:get_node(p2).name + local def2 = minetest.registered_nodes[nn] + if def2 and not def2.walkable then + return false + end + return true +end + -- -- Some common functions -- @@ -108,6 +150,13 @@ function nodeupdate_single(p) nodeupdate(p) end end + + if minetest.get_node_group(n.name, "attached_node") ~= 0 then + if not check_attached_node(p, n) then + drop_attached_node(p) + nodeupdate(p) + end + end end function nodeupdate(p) diff --git a/builtin/item.lua b/builtin/item.lua index 0f8dcff1f..9352a43fc 100644 --- a/builtin/item.lua +++ b/builtin/item.lua @@ -181,6 +181,13 @@ function minetest.item_place_node(itemstack, placer, pointed_thing) end end + -- Check if the node is attached and if it can be placed there + if not check_attached_node(place_to, newnode) then + minetest.log("action", "attached node " .. def.name .. + " can not be placed at " .. minetest.pos_to_string(place_to)) + return + end + -- Add node and update minetest.env:add_node(place_to, newnode) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index e32efc6df..08619b72a 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -457,6 +457,9 @@ Special groups - fall_damage_add_percent: damage speed = speed * (1 + value/100) - bouncy: value is bounce speed in percent - falling_node: if there is no walkable block under the node it will fall +- attached_node: if the node under it is not a walkable block the node will be + dropped as an item. If the node is wallmounted the + wallmounted direction is checked. Known damage and digging time defining groups ---------------------------------------------- diff --git a/games/minimal/mods/default/init.lua b/games/minimal/mods/default/init.lua index 5f4d8e063..9900b98a5 100644 --- a/games/minimal/mods/default/init.lua +++ b/games/minimal/mods/default/init.lua @@ -837,7 +837,7 @@ minetest.register_node("default:junglegrass", { wield_image = "default_junglegrass.png", paramtype = "light", walkable = false, - groups = {snappy=3}, + groups = {snappy=3,attached_node=1}, sounds = default.node_sound_leaves_defaults(), }) @@ -1106,7 +1106,7 @@ minetest.register_node("default:torch", { wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1}, wall_side = {-0.5, -0.3, -0.1, -0.5+0.3, 0.3, 0.1}, }, - groups = {choppy=2,dig_immediate=3}, + groups = {choppy=2,dig_immediate=3,attached_node=1}, legacy_wallmounted = true, sounds = default.node_sound_defaults(), }) @@ -1127,7 +1127,7 @@ minetest.register_node("default:sign_wall", { --wall_bottom = --wall_side = }, - groups = {choppy=2,dig_immediate=2}, + groups = {choppy=2,dig_immediate=2,attached_node=1}, legacy_wallmounted = true, sounds = default.node_sound_defaults(), on_construct = function(pos) @@ -1495,7 +1495,7 @@ minetest.register_node("default:sapling", { wield_image = "default_sapling.png", paramtype = "light", walkable = false, - groups = {snappy=2,dig_immediate=3}, + groups = {snappy=2,dig_immediate=3,attached_node=1}, sounds = default.node_sound_defaults(), })