working get/set node

This commit is contained in:
BuckarooBanzay 2020-06-15 08:38:49 +02:00
parent 3715a74169
commit 0f035ddf92
5 changed files with 240 additions and 19 deletions

@ -1,5 +1,15 @@
digibuilder.digiline_effector = function(pos, _, channel, msg)
-- 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)
local msgt = type(msg)
if msgt ~= "table" then
@ -9,25 +19,121 @@ digibuilder.digiline_effector = function(pos, _, channel, msg)
local meta = minetest.get_meta(pos)
local set_channel = meta:get_string("channel")
if set_channel == "" then
-- backward compatibility with old static channel
set_channel = "jumpdrive"
end
if channel ~= set_channel then
return
end
-- validate position
local owner = meta:get_string("owner")
if not digibuilder.digiline_validate_pos(pos, owner, set_channel, msg) then
return
end
if msg.command == "getnode" then
-- calculate absoulte position
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_items[node.name]
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
-- calculate absoulte position
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_items[node.name]
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
-- 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
-- check if node is in inventory
local inv = meta:get_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
-- get and validate place node definition
local place_node_def = minetest.registered_items[msg.name]
if not place_node_def then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
pos = msg.pos,
error = true,
message = "place node is unknown: '" .. msg.name .. "'"
})
return
end
-- remove item
inv:remove_item("main", msg.name)
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
minetest.place_node(absolute_pos, place_node)
if enable_param2 then
-- add param2 info
minetest.swap_node(absolute_pos, place_node)
end
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
pos = msg.pos,
name = place_node.name,
param2 = place_node.param2,
success = true,
})
end
end
digibuilder.digiline_rules = {
-- digilines.rules.default
{x= 1,y= 0,z= 0},{x=-1,y= 0,z= 0}, -- along x beside
{x= 0,y= 0,z= 1},{x= 0,y= 0,z=-1}, -- along z beside
{x= 1,y= 1,z= 0},{x=-1,y= 1,z= 0}, -- 1 node above along x diagonal
{x= 0,y= 1,z= 1},{x= 0,y= 1,z=-1}, -- 1 node above along z diagonal
{x= 1,y=-1,z= 0},{x=-1,y=-1,z= 0}, -- 1 node below along x diagonal
{x= 0,y=-1,z= 1},{x= 0,y=-1,z=-1}, -- 1 node below along z diagonal
{x= 0,y= 1,z= 0},{x= 0,y=-1,z= 0}, -- along y above and below
}

11
digiline_rules.lua Normal file

@ -0,0 +1,11 @@
digibuilder.digiline_rules = {
-- digilines.rules.default
{x= 1,y= 0,z= 0},{x=-1,y= 0,z= 0}, -- along x beside
{x= 0,y= 0,z= 1},{x= 0,y= 0,z=-1}, -- along z beside
{x= 1,y= 1,z= 0},{x=-1,y= 1,z= 0}, -- 1 node above along x diagonal
{x= 0,y= 1,z= 1},{x= 0,y= 1,z=-1}, -- 1 node above along z diagonal
{x= 1,y=-1,z= 0},{x=-1,y=-1,z= 0}, -- 1 node below along x diagonal
{x= 0,y=-1,z= 1},{x= 0,y=-1,z=-1}, -- 1 node below along z diagonal
{x= 0,y= 1,z= 0},{x= 0,y=-1,z= 0}, -- along y above and below
}

66
digiline_validate_pos.lua Normal file

@ -0,0 +1,66 @@
function digibuilder.digiline_validate_pos(pos, owner, set_channel, msg)
if not msg.pos then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
error = true,
message = "'pos' is not set!"
})
return
end
local x = tonumber(msg.pos.x)
local y = tonumber(msg.pos.y)
local z = tonumber(msg.pos.z)
if not x or not y or not z then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
error = true,
message = "'pos' is has invalid x/y/z fields!"
})
return false
end
if math.abs(x) > digibuilder.max_radius then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
error = true,
message = "'pos.x' is out of the area!"
})
return false
end
if math.abs(y) > digibuilder.max_radius then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
error = true,
message = "'pos.y' is out of the area!"
})
return false
end
if math.abs(z) > digibuilder.max_radius then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
error = true,
message = "'pos.z' is out of the area!"
})
return false
end
if x == 0 and y == 0 and z == 0 then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
error = true,
message = "can't work on myself!"
})
return false
end
if minetest.is_protected(pos, owner) then
digilines.receptor_send(pos, digibuilder.digiline_rules, set_channel, {
pos = msg.pos,
error = true,
message = "position is protected!"
})
return false
end
return true
end

@ -1,10 +1,14 @@
digibuilder = {}
digibuilder = {
max_radius = tonumber(minetest.settings:get("digibuilder.max_radius")) or 15,
}
local MP = minetest.get_modpath("digibuilder")
-- common functions
dofile(MP.."/common.lua")
dofile(MP.."/formspec.lua")
dofile(MP.."/digiline_rules.lua")
dofile(MP.."/digiline_validate_pos.lua")
dofile(MP.."/digiline.lua")
dofile(MP.."/node.lua")

@ -5,3 +5,37 @@ Minetest digibuilder
State: **WIP**
# Commands
## Get node
```lua
digiline_send("digibuilder", {
command = "getnode",
pos = { x=1, y=0, z=0 }
})
if event.type == "digiline" and event.channel == "digibuilder" then
-- { error = true, message = "..." }
-- { pos = { x=1, y=0, z=0 }, name = "default:stone" }
-- { pos = { x=1, y=0, z=0 }, name = "stairs:stair_stone", param2 = 3 }
end
```
## Set node
```lua
digiline_send("digibuilder", {
command = "setnode",
pos = { x=1, y=0, z=0 },
param2 = 3,
name = "stairs:stair_stone"
})
if event.type == "digiline" and event.channel == "digibuilder" then
-- { error = true, message = "..." }
-- { pos = { x=1, y=0, z=0 }, success = true, name = "default:stone" }
-- { pos = { x=1, y=0, z=0 }, success = true, name = "stairs:stair_stone", param2 = 3 }
end
```