mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-09-12 08:42:10 +02:00
* Add support for `group:supported_node` to CORE/mcl_attached. Supported nodes are nodes that can be placed on any node that does not have the `drawtype = "airlike"` attribute. * Copy the `drop_attached_node()` function from minetest/builtin, so that the override function provides the same behavior when nodes drop. * Add comments to CORE/mcl_attached and to the functions defined in it. * Add more local aliases for global minetest.* functions. * If the original function returns true, it is not necessary anymore to perform more tests and the override function can simply return true immediately.
94 lines
2.9 KiB
Lua
94 lines
2.9 KiB
Lua
-- Overrides the builtin minetest.check_single_for_falling.
|
|
-- We need to do this in order to handle nodes in mineclone specific groups
|
|
-- "supported_node" and "attached_node_facedir".
|
|
--
|
|
-- Nodes in group "supported_node" can be placed on any node that does not
|
|
-- have the "airlike" drawtype. Carpets are an example of this type.
|
|
|
|
local vector = vector
|
|
|
|
local facedir_to_dir = minetest.facedir_to_dir
|
|
local get_item_group = minetest.get_item_group
|
|
local remove_node = minetest.remove_node
|
|
local get_node = minetest.get_node
|
|
local get_meta = minetest.get_meta
|
|
local registered_nodes = minetest.registered_nodes
|
|
local get_node_drops = minetest.get_node_drops
|
|
local add_item = minetest.add_item
|
|
|
|
-- drop_attached_node(p)
|
|
--
|
|
-- This function is copied verbatim from minetest/builtin/game/falling.lua
|
|
-- We need this to do the exact same dropping node handling in our override
|
|
-- minetest.check_single_for_falling() function as in the builtin function.
|
|
--
|
|
local function drop_attached_node(p)
|
|
local n = get_node(p)
|
|
local drops = get_node_drops(n, "")
|
|
local def = registered_nodes[n.name]
|
|
if def and def.preserve_metadata then
|
|
local oldmeta = get_meta(p):to_table().fields
|
|
-- Copy pos and node because the callback can modify them.
|
|
local pos_copy = vector.new(p)
|
|
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
|
|
if def and def.sounds and def.sounds.fall then
|
|
core.sound_play(def.sounds.fall, {pos = p}, true)
|
|
end
|
|
remove_node(p)
|
|
for _, item in pairs(drops) do
|
|
local pos = {
|
|
x = p.x + math.random()/2 - 0.25,
|
|
y = p.y + math.random()/2 - 0.25,
|
|
z = p.z + math.random()/2 - 0.25,
|
|
}
|
|
add_item(pos, item)
|
|
end
|
|
end
|
|
|
|
-- minetest.check_single_for_falling(pos)
|
|
--
|
|
-- * causes an unsupported `group:falling_node` node to fall and causes an
|
|
-- unattached `group:attached_node` or `group:attached_node_facedir` node
|
|
-- or unsupported `group:supported_node` to drop.
|
|
-- * does not spread these updates to neighbours.
|
|
--
|
|
-- Returns true if the node at <pos> has spawned a falling node or has been
|
|
-- dropped as item(s).
|
|
--
|
|
local original_function = minetest.check_single_for_falling
|
|
|
|
function minetest.check_single_for_falling(pos)
|
|
if original_function(pos) then
|
|
return true
|
|
end
|
|
|
|
local node = get_node(pos)
|
|
if get_item_group(node.name, "attached_node_facedir") ~= 0 then
|
|
local dir = facedir_to_dir(node.param2)
|
|
if dir then
|
|
if get_item_group(get_node(vector.add(pos, dir)).name, "solid") == 0 then
|
|
drop_attached_node(pos)
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
if get_item_group(node.name, "supported_node") ~= 0 then
|
|
local def = registered_nodes[get_node(vector.offset(pos, 0, -1, 0)).name]
|
|
if def and def.drawtype == "airlike" then
|
|
drop_attached_node(pos)
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|