blockgame/mods/bg_funnel/funnel.lua

83 lines
2.2 KiB
Lua

local modname = minetest.get_current_modname()
local api = load_file("api")
local function get_meta_table (pos)
return minetest.get_meta(pos):to_table()
end
local function set_meta (pos, meta_table)
local meta = minetest.get_meta(pos)
for key, value in pairs(meta_table) do
local fn = nil
if type(value) == "string" then fn = "set_string" end
if type(value) == "int" then fn = "set_int" end
if type(value) == "float" then fn = "set_float" end
if fn then
meta[fn](key, value)
end
end
end
local function attempt_input (pos)
-- TODO: add max limit for amount of nodes inside funnel inventory.
local above = pos + blockgame.vector.dirs.up
if minetest.get_node(above).name == "air" then return false end
local node = minetest.get_node(above)
local meta = get_meta_table(above)
local value = {
node = node,
meta = meta,
}
local success = api.push(pos, value)
if not success then return false end
minetest.remove_node(above)
return true
end
local function attempt_output (pos)
local below = pos + blockgame.vector.dirs.down
if minetest.get_node(below).name ~= "air" then return false end
local value = api.pop(pos)
if not value then return nil end
local node = value.node
local meta = value.meta
minetest.set_node(below, node)
set_meta(below, meta)
return true
end
blockgame.register_abm({
label = "funnel nodes",
nodenames = {modname .. ":funnel"},
interval = 1,
chance = 1,
catch_up = false,
action = function (pos)
-- NOTE: metadata storage might not work, and funnels might not be able to pick up other funnels successfully.
attempt_input(pos)
attempt_output(pos)
end,
})
-- NOTE: the documentation says `register_on_placenode` is "not recommended"; what else could be used for this?
minetest.register_on_placenode(function (pos)
local below = pos + blockgame.vector.dirs.down
if minetest.get_node(below).name ~= modname .. ":funnel" then return end
attempt_input(below)
end)
-- NOTE: the documentation says `register_on_dignode` is "not recommended"; what else could be used for this?
minetest.register_on_dignode(function (pos)
local above = pos + blockgame.vector.dirs.up
if minetest.get_node(above).name ~= modname .. ":funnel" then return end
attempt_output(above)
end)