digibuilder/digiline.lua

186 lines
4.7 KiB
Lua
Raw Normal View History

2020-06-14 20:14:52 +02:00
2020-06-15 08:38:49 +02:00
-- returns a node and loads the area if needed
function digibuilder.get_node(pos)
local node = minetest.get_node_or_nil(pos)
if node == nil then
minetest.get_voxel_manip(pos, pos)
node = minetest.get_node_or_nil(pos)
end
return node
end
function digibuilder.digiline_effector(pos, _, channel, msg)
2020-06-14 20:14:52 +02:00
local msgt = type(msg)
if msgt ~= "table" then
return
end
local meta = minetest.get_meta(pos)
local set_channel = meta:get_string("channel")
2020-06-15 08:38:49 +02:00
if channel ~= set_channel then
return
2020-06-14 20:14:52 +02:00
end
2020-06-15 08:38:49 +02:00
-- validate position
local owner = meta:get_string("owner")
if not digibuilder.digiline_validate_pos(pos, owner, set_channel, msg) then
2020-06-14 20:14:52 +02:00
return
end
2020-06-15 08:38:49 +02:00
if msg.command == "getnode" then
2020-06-16 07:47:44 +02:00
-- calculate absolute position
2020-06-15 08:38:49 +02:00
local absolute_pos = vector.add(pos, msg.pos)
local node = digibuilder.get_node(absolute_pos)
-- get and validate node definition
local node_def = minetest.registered_nodes[node.name]
2020-06-15 08:38:49 +02:00
if not node_def then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
pos = msg.pos,
error = true,
message = "target node is unknown!"
})
return
end
-- assemble result
local result = {
pos = msg.pos,
name = node.name
}
if node_def.paramtype2 == "facedir" then
-- add param2 info
result.param2 = node.param2
end
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, result)
elseif msg.command == "setnode" then
2020-06-16 08:10:29 +02:00
-- set last call time of the command
local now = minetest.get_us_time()
local previous_time = meta:get_int("lastsetcommand")
local diff_micros = now - previous_time
if diff_micros < (digibuilder.setnode_delay * 1000 * 1000) then
-- less than half a second elapsed
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
pos = msg.pos,
error = true,
message = "setnode called too fast!"
})
return
end
-- set new lastcommand time
meta:set_int("lastsetcommand", now)
2020-06-16 07:47:44 +02:00
-- calculate absolute position
2020-06-15 08:38:49 +02:00
local absolute_pos = vector.add(pos, msg.pos)
local node = digibuilder.get_node(absolute_pos)
-- get and validate node definition
local node_def = minetest.registered_nodes[node.name]
2020-06-15 08:38:49 +02:00
if not node_def then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
pos = msg.pos,
error = true,
message = "target node is unknown!"
})
return
end
2020-06-14 20:14:52 +02:00
local is_creative = minetest.check_player_privs(owner, "creative")
2020-06-15 08:38:49 +02:00
local inv = meta:get_inventory()
2020-06-16 09:00:56 +02:00
2020-06-16 09:00:56 +02:00
if not is_creative then
-- check if node is buildable to
if not node_def.buildable_to then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
pos = msg.pos,
error = true,
message = "Can't build on that position!"
})
return
end
2020-06-16 09:00:56 +02:00
-- check if node is in inventory
if not inv:contains_item("main", msg.name) then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
pos = msg.pos,
error = true,
message = "Item not in inventory: " .. msg.name
})
return
end
2020-06-15 08:38:49 +02:00
end
-- get and validate place node definition
local place_node_def = minetest.registered_nodes[msg.name]
2020-06-15 08:38:49 +02:00
if not place_node_def then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
pos = msg.pos,
error = true,
2020-06-16 19:46:06 +02:00
message = "place node is unknown: '" .. (msg.name or "<empty>") .. "'"
2020-06-15 08:38:49 +02:00
})
return
end
2020-06-16 09:00:56 +02:00
if not is_creative then
-- remove item
inv:remove_item("main", msg.name)
end
2020-06-15 08:38:49 +02:00
-- only allow param2 setting for "facedir" types
2020-06-15 08:38:49 +02:00
local param2 = tonumber(msg.param2)
local enable_param2 = place_node_def.paramtype2 == "facedir" and param2 and param2 > 0 and param2 <= 255
local place_node = {
name = msg.name
}
if enable_param2 then
-- place with param2 info
place_node.param2 = param2
end
-- place node inworld
2020-06-16 19:46:06 +02:00
minetest.log("action", "[digibuilder] " .. owner .. " places node '" ..
place_node.name .. "' at " ..
minetest.pos_to_string(absolute_pos)
)
2020-06-15 08:38:49 +02:00
2020-06-16 19:46:06 +02:00
minetest.set_node(absolute_pos, place_node)
2020-06-15 08:38:49 +02:00
-- check if "after_place_node" is defined
if place_node_def.after_place_node then
local player = digibuilder.create_fake_player({
name = owner
})
local pointed_thing = {}
pointed_thing.type = "node"
pointed_thing.above = {x=absolute_pos.x, y=absolute_pos.y, z=absolute_pos.z}
pointed_thing.under = {x=absolute_pos.x, y=absolute_pos.y - 1, z=absolute_pos.z}
local itemstack = ItemStack()
place_node_def.after_place_node(absolute_pos, player, itemstack, pointed_thing)
end
-- check if the node is falling
if place_node_def.groups.falling_node then
minetest.check_for_falling(absolute_pos)
end
2020-06-15 08:38:49 +02:00
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
pos = msg.pos,
name = place_node.name,
param2 = place_node.param2,
success = true,
})
end
end