sensor and sign changer added.

connector tool added.
master
Joachim Stolberg 2019-03-26 22:40:04 +01:00
parent 32d3968f74
commit bae12e4b6d
17 changed files with 275 additions and 57 deletions

View File

@ -5,7 +5,10 @@ Signs Bot [signs_bot]
A robot controlled by signs.
tbd.
The robot can be controlled by means of text commands written on (street) signs.
The mod provides already programmed signs like "move" or "turn_left", but also a generic "command" sign to be programmed by the player.
If the robot finds a sign on its path, it executes all sign commands.
### License

View File

@ -206,6 +206,7 @@ minetest.register_node("signs_bot:box", {
on_timer = node_timer,
on_rotate = screwdriver.disallow,
paramtype2 = "facedir",
is_ground_content = false,
groups = {cracky = 1},

View File

@ -55,21 +55,41 @@ local function check_cmnd_block(pos, mem, meta)
return false
end
local function trigger_sensor(pos, node)
print("trigger_sensor")
local meta = M(pos)
local dest_pos = meta:get_string("dest_pos")
local dest_idx = meta:get_int("dest_idx")
if dest_pos ~= "" and dest_idx ~= 0 then
minetest.registered_nodes[node.name].switch_sign_changer(minetest.string_to_pos(dest_pos), dest_idx)
end
end
local function no_cmnd_block(mem)
local pos1 = lib.next_pos(mem.robot_pos, mem.robot_param2)
local meta = M(pos1)
if check_cmnd_block(pos1, mem, meta) then
return false
else
local pos2 = {x=pos1.x, y=pos1.y+1, z=pos1.z}
meta = M(pos2)
if check_cmnd_block(pos2, mem, meta) then
return false
local pos = minetest.find_node_near(mem.robot_pos, 1, {"signs_bot:bot_sensor", "group:sign_bot_sign"})
if pos then
local dis = vector.distance(mem.robot_pos, pos)
local node = lib.get_node_lvm(pos)
if dis == 1 and node.name == "signs_bot:bot_sensor" then
trigger_sensor(pos, node)
else
local pos1 = lib.next_pos(mem.robot_pos, mem.robot_param2)
local meta = M(pos1)
if check_cmnd_block(pos1, mem, meta) then
return false
else
local pos2 = {x=pos1.x, y=pos1.y+1, z=pos1.z}
meta = M(pos2)
if check_cmnd_block(pos2, mem, meta) then
return false
end
end
end
end
return true
end
--
-- Command register API function
--
@ -86,7 +106,6 @@ function signs_bot.register_botcommand(name, def)
SortedKeys[#SortedKeys+1] = name
end
signs_bot.register_botcommand("move", {
params = "<steps>",
description = I("Move the robot 1..9 steps forward.\nDefault value: 1"),

View File

@ -25,3 +25,4 @@ dofile(MP.."/sign_func.lua")
dofile(MP.."/commands.lua")
dofile(MP.."/basis.lua")
dofile(MP.."/duplicator.lua")
dofile(MP.."/logic.lua")

View File

@ -67,6 +67,7 @@ end
function signs_bot.robot_take(base_pos, robot_pos, param2, num, slot)
local pos1 = lib.next_pos(robot_pos, param2)
if lib.not_protected(base_pos, pos1) then
--minetest.global_exists("node_io")
local src_inv, src_list = get_other_inv(pos1)
local dst_inv, dst_list = get_own_inv(base_pos)
local taken, rest, src_slot = lib.get_inv_items(src_inv, src_list, slot, num)

33
lib.lua
View File

@ -159,3 +159,36 @@ end
function signs_bot.lib.release_inv_items(src_inv, src_list, slot, stack)
src_inv:set_stack(src_list, slot, stack)
end
--
-- Place/dig signs
--
function signs_bot.lib.place_sign(pos, sign, param2)
minetest.set_node(pos, {name=sign:get_name(), param2=param2})
minetest.registered_nodes[sign:get_name()].after_place_node(pos, nil, sign)
end
function signs_bot.lib.dig_sign(pos, node)
node = node or get_node_lvm(pos)
local nmeta = minetest.get_meta(pos)
local cmnd = nmeta:get_string("signs_bot_cmnd")
local sign
if cmnd ~= "" then
if node.name == "signs_bot:sign_cmnd" then
local err_code = nmeta:get_int("err_code")
local err_msg = nmeta:get_string("err_msg")
local name = nmeta:get_string("sign_name")
sign = ItemStack("signs_bot:sign_cmnd")
local smeta = sign:get_meta()
smeta:set_string("cmnd", cmnd)
smeta:set_int("err_code", err_code)
smeta:set_string("err_msg", err_msg)
smeta:set_string("description", name)
else
sign = ItemStack(node.name)
end
minetest.remove_node(pos)
return sign
end
end

196
logic.lua Normal file
View File

@ -0,0 +1,196 @@
--[[
Signs Bot
=========
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Signs Bot: Logic Nodes
]]--
-- for lazy programmers
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local P = minetest.string_to_pos
local M = minetest.get_meta
-- Load support for intllib.
local MP = minetest.get_modpath("signs_bot")
local I,_ = dofile(MP.."/intllib.lua")
local lib = signs_bot.lib
local formspec = "size[8,7]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"label[1,1.3;"..I("Signs:").."]"..
"label[2.6,0.7;1]label[5.1,0.7;2]"..
"list[context;sign;3,0.5;2,2;]"..
"label[2.6,1.7;3]label[5.1,1.7;4]"..
"list[current_player;main;0,3;8,4;]"..
"listring[context;main]"..
"listring[current_player;main]"
-- Get one sign from the robot signs inventory
local function get_inv_sign(pos, slot)
local inv = minetest.get_inventory({type="node", pos=pos})
local stack = inv:get_stack("sign", slot)
local taken = stack:take_item(1)
inv:set_stack("sign", slot, stack)
return taken
end
local function put_inv_sign(pos, slot, sign)
local inv = minetest.get_inventory({type="node", pos=pos})
inv:set_stack("sign", slot, sign)
end
local function switch_sign_changer(pos, new_idx)
-- swap changer
local node = lib.get_node_lvm(pos)
local pos1 = lib.next_pos(pos, (node.param2 + 1) % 4)
local old_idx = tonumber(string.sub(node.name, 18))
node.name = "signs_bot:changer"..new_idx
minetest.swap_node(pos, node)
-- swap sign
local param2 = minetest.get_node(pos).param2
local sign = lib.dig_sign(pos1)
if sign then
M(pos):set_int("sign_param2", param2)
put_inv_sign(pos, old_idx, sign)
end
print(S(pos), new_idx)
sign = get_inv_sign(pos, new_idx)
if sign:get_count() == 1 then
lib.place_sign(pos1, sign, M(pos):get_int("sign_param2"))
end
end
local function swap_node(pos, node)
local slot = tonumber(string.sub(node.name, 18))
local new_idx = (slot % 4) + 1
switch_sign_changer(pos, new_idx)
end
local function allow_metadata_inventory()
return 0
end
for idx = 1,4 do
local not_in_inv = idx == 1 and 0 or 1
minetest.register_node("signs_bot:changer"..idx, {
description = "Sign Changer",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{ -11/32, -1/2, -11/32, 11/32, -5/16, 11/32},
},
},
tiles = {
-- up, down, right, left, back, front
"signs_bot_changer.png^signs_bot_changer"..idx..".png",
"signs_bot_changer.png^signs_bot_changer"..idx..".png",
"signs_bot_changer.png^signs_bot_changer"..idx..".png^[transformFXR90",
"signs_bot_changer.png^signs_bot_changer"..idx..".png",
"signs_bot_changer.png^signs_bot_changer"..idx..".png",
"signs_bot_changer.png^signs_bot_changer"..idx..".png",
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size('sign', 4)
end,
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", formspec)
end,
allow_metadata_inventory_put = allow_metadata_inventory,
allow_metadata_inventory_take = allow_metadata_inventory,
on_punch = swap_node,
on_rotate = screwdriver.disallow,
paramtype2 = "facedir",
is_ground_content = false,
groups = {cracky = 1, not_in_creative_inventory = not_in_inv},
sounds = default.node_sound_metal_defaults(),
})
end
minetest.register_node("signs_bot:bot_sensor", {
description = "Bot Sensor",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{ -11/32, -1/2, -11/32, 11/32, -5/16, 11/32},
},
},
tiles = {
-- up, down, right, left, back, front
"signs_bot_changer.png^signs_bot_sensor.png",
"signs_bot_changer.png^signs_bot_sensor.png",
"signs_bot_changer.png^signs_bot_sensor.png^[transformFXR90",
"signs_bot_changer.png^signs_bot_sensor.png",
"signs_bot_changer.png^signs_bot_sensor.png",
"signs_bot_changer.png^signs_bot_sensor.png",
},
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", "Bot Sensor: Not connected")
end,
switch_sign_changer = switch_sign_changer,
on_rotate = screwdriver.disallow,
paramtype2 = "facedir",
is_ground_content = false,
groups = {cracky = 1},
sounds = default.node_sound_metal_defaults(),
})
local function pairing(itemstack, placer, pointed_thing)
if pointed_thing.type == "node" then
local pos = pointed_thing.under
local node = minetest.get_node(pos)
if string.sub(node.name, 1, 17) == "signs_bot:changer" then
minetest.sound_play('signs_bot_ping', {to_player = placer:get_player_name()})
placer:set_attribute("signs_bot_changer_pos", minetest.pos_to_string(pos))
placer:set_attribute("signs_bot_changer_idx", string.sub(node.name, 18) )
elseif node.name == "signs_bot:bot_sensor"
and placer:get_attribute("signs_bot_changer_pos") ~= "" then
local dest_pos = placer:get_attribute("signs_bot_changer_pos")
local dest_idx = placer:get_attribute("signs_bot_changer_idx")
local meta = M(pos)
meta:set_string("dest_pos", dest_pos)
meta:set_int("dest_idx", tonumber(dest_idx))
meta:set_string("infotext", "Bot Sensor: Connected with "..dest_pos.." / "..dest_idx)
print(dest_pos, dest_idx)
minetest.sound_play('signs_bot_pong', {to_player = placer:get_player_name()})
else
minetest.sound_play('signs_bot_error', {to_player = placer:get_player_name()})
end
end
end
minetest.register_node("signs_bot:connector", {
description = "Sensor Connector Tool",
inventory_image = "signs_bot_tool.png",
wield_image = "signs_bot_tool.png",
groups = {cracky=1, book=1},
on_use = pairing,
on_place = pairing,
node_placement_prediction = "",
stack_max = 1,
})

View File

@ -164,20 +164,11 @@ minetest.register_node("signs_bot:sign_cmnd", {
on_dig = function(pos, node, digger)
if not minetest.is_protected(pos, digger:get_player_name()) then
local nmeta = minetest.get_meta(pos)
local cmnd = nmeta:get_string("signs_bot_cmnd")
local err_code = nmeta:get_int("err_code")
local err_msg = nmeta:get_string("err_msg")
local name = nmeta:get_string("sign_name")
local sign = ItemStack("signs_bot:sign_cmnd")
local smeta = sign:get_meta()
smeta:set_string("cmnd", cmnd)
smeta:set_int("err_code", err_code)
smeta:set_string("err_msg", err_msg)
smeta:set_string("description", name)
minetest.remove_node(pos)
local inv = minetest.get_inventory({type="player", name=digger:get_player_name()})
inv:add_item("main", sign)
local sign = lib.dig_sign(pos, node)
if sign then
local inv = minetest.get_inventory({type="player", name=digger:get_player_name()})
inv:add_item("main", sign)
end
end
end,
@ -185,7 +176,7 @@ minetest.register_node("signs_bot:sign_cmnd", {
sunlight_propagates = true,
is_ground_content = false,
drop = "",
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1},
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1, sign_bot_sign = 1},
sounds = default.node_sound_wood_defaults(),
})
@ -221,21 +212,7 @@ function signs_bot.place_sign(base_pos, robot_pos, param2, slot)
if lib.is_air_like(pos1) then
local sign = get_inv_sign(base_pos, slot)
if sign then
local meta = sign:get_meta()
local cmnd = meta:get_string("cmnd")
local err_code = meta:get_int("err_code")
local err_msg = meta:get_string("err_msg")
local name = meta:get_string("description")
minetest.set_node(pos1, {name=sign:get_name(), param2=param2})
local under = {x=pos1.x, y=pos1.y-1, z=pos1.z}
local pointed_thing = {type="node", under=under, above=pos1}
minetest.registered_nodes[sign:get_name()].after_place_node(pos1, nil, sign, pointed_thing)
--pcall(minetest.after_place_node, pos1, nil, sign, pointed_thing)
meta = M(pos1)
meta:set_string("signs_bot_cmnd", cmnd)
meta:set_int("err_code", err_code)
meta:set_string("err_msg", err_msg)
meta:set_string("sign_name", name)
lib.place_sign(pos1, sign, param2)
return true
else
signs_bot.output(base_pos, I("Error: Signs inventory empty"))
@ -252,21 +229,7 @@ function signs_bot.place_sign_behind(base_pos, robot_pos, param2, slot)
if lib.is_air_like(pos1) then
local sign = get_inv_sign(base_pos, slot)
if sign then
local meta = sign:get_meta()
local cmnd = meta:get_string("cmnd")
local err_code = meta:get_int("err_code")
local err_msg = meta:get_string("err_msg")
local name = meta:get_string("description")
minetest.set_node(pos1, {name=sign:get_name(), param2=param2})
local under = {x=pos1.x, y=pos1.y-1, z=pos1.z}
local pointed_thing = {type="node", under=under, above=pos1}
minetest.registered_nodes[sign:get_name()].after_place_node(pos1, nil, sign, pointed_thing)
--pcall(minetest.after_place_node, pos1, nil, sign, pointed_thing)
meta = M(pos1)
meta:set_string("signs_bot_cmnd", cmnd)
meta:set_int("err_code", err_code)
meta:set_string("err_msg", err_msg)
meta:set_string("sign_name", name)
lib.place_sign(pos1, sign, param2)
return true
else
signs_bot.output(base_pos, I("Error: Signs inventory empty"))

View File

@ -57,10 +57,11 @@ local function register_sign(def)
meta:set_string("signs_bot_cmnd", def.commands)
meta:set_string("formspec", formspec(def.commands))
end,
on_rotate = screwdriver.disallow,
paramtype = "light",
sunlight_propagates = true,
is_ground_content = false,
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1},
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1, sign_bot_sign = 1},
sounds = default.node_sound_wood_defaults(),
})
end

BIN
sounds/signs_bot_ping.ogg Normal file

Binary file not shown.

BIN
sounds/signs_bot_pong.ogg Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

BIN
textures/signs_bot_tool.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 B