signs_bot-cd2025/basis.lua

364 lines
9.7 KiB
Lua
Raw Normal View History

2019-03-23 21:15:13 +01:00
--[[
Signs Bot
=========
Copyright (C) 2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
Signs Bot: Robot basis block
]]--
-- 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 CYCLE_TIME = 1
2019-06-20 16:22:01 +02:00
signs_bot.MAX_CAPA = 600
2019-03-23 21:15:13 +01:00
local function formspec(pos, mem)
2019-03-23 21:15:13 +01:00
mem.running = mem.running or false
local cmnd = mem.running and "stop;"..I("Off") or "start;"..I("On")
local bot = not mem.running and "image[0.6,1;1,1;signs_bot_bot_inv.png]" or ""
2019-06-20 16:22:01 +02:00
local current_capa = mem.capa or (signs_bot.MAX_CAPA * 0.9)
2019-04-12 22:32:40 +02:00
return "size[9,7.6]"..
2019-03-23 21:15:13 +01:00
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
2019-04-12 22:32:40 +02:00
"label[2.1,0;"..I("Signs").."]label[5.3,0;"..I("Other items").."]"..
"image[0.6,1;1,1;signs_bot_form_mask.png]"..
2019-04-09 21:09:33 +02:00
bot..
2019-06-20 16:22:01 +02:00
signs_bot.formspec_battery_capa(signs_bot.MAX_CAPA, current_capa)..
2019-04-12 22:32:40 +02:00
"label[2.1,0.5;1]label[3.1,0.5;2]label[4.1,0.5;3]"..
"list[context;sign;1.8,1;3,2;]"..
"label[2.1,3;4]label[3.1,3;5]label[4.1,3;6]"..
"label[5.3,0.5;1]label[6.3,0.5;2]label[7.3,0.5;3]label[8.3,0.5;4]"..
"list[context;main;5,1;4,2;]"..
"label[5.3,3;5]label[6.3,3;6]label[7.3,3;7]label[8.3,3;8]"..
"button[0.2,2;1.5,1;"..cmnd.."]"..
"list[current_player;main;0.5,3.8;8,4;]"..
2019-03-23 21:15:13 +01:00
"listring[context;main]"..
"listring[current_player;main]"
end
function signs_bot.infotext(pos, state)
2019-04-14 19:38:25 +02:00
local meta = M(pos)
local number = meta:get_string("number")
state = state or "<unknown>"
meta:set_string("infotext", I("Robot Box ")..number..": "..state)
2019-03-23 21:15:13 +01:00
end
local function reset_robot(pos, mem)
mem.robot_param2 = (minetest.get_node(pos).param2 + 1) % 4
mem.robot_pos = lib.next_pos(pos, mem.robot_param2, 1)
2019-04-06 01:09:52 +02:00
mem.steps = nil
2019-03-23 21:15:13 +01:00
local pos_below = {x=mem.robot_pos.x, y=mem.robot_pos.y-1, z=mem.robot_pos.z}
signs_bot.place_robot(mem.robot_pos, pos_below, mem.robot_param2)
end
local function start_robot(base_pos)
local mem = tubelib2.get_mem(base_pos)
2019-04-14 19:38:25 +02:00
local meta = M(base_pos)
2019-04-07 16:47:00 +02:00
mem.lCmnd1 = {}
mem.lCmnd2 = {}
2019-03-23 21:15:13 +01:00
mem.running = true
2019-06-28 23:49:01 +02:00
mem.error = false
mem.stored_node = nil
2019-06-20 16:22:01 +02:00
if minetest.global_exists("techage") then
mem.capa = mem.capa or 0 -- enable power consumption
else
mem.capa = nil
end
meta:set_string("formspec", formspec(base_pos, mem))
signs_bot.infotext(base_pos, I("running"))
reset_robot(base_pos, mem)
minetest.get_node_timer(base_pos):start(CYCLE_TIME)
2019-03-23 21:15:13 +01:00
return true
end
2019-03-24 19:03:12 +01:00
function signs_bot.stop_robot(base_pos, mem)
2019-04-14 19:38:25 +02:00
local meta = M(base_pos)
if mem.signal_request ~= true then
mem.running = false
minetest.get_node_timer(base_pos):stop()
signs_bot.infotext(base_pos, I("stopped"))
meta:set_string("formspec", formspec(base_pos, mem))
signs_bot.remove_robot(mem)
else
mem.signal_request = false
start_robot(base_pos)
end
2019-03-23 21:15:13 +01:00
end
-- Used by the pairing tool
local function signs_bot_get_signal(pos, node)
local mem = tubelib2.get_mem(pos)
if mem.running then
return "on"
else
return "off"
end
end
-- To be called from sensors
local function signs_bot_on_signal(pos, node, signal)
local mem = tubelib2.get_mem(pos)
if signal == "on" and not mem.running then
start_robot(pos)
elseif signal == "off" and mem.running then
signs_bot.stop_robot(pos, mem)
2019-05-25 20:16:11 +02:00
-- else
-- mem.signal_request = (signal == "on")
end
end
2019-03-23 21:15:13 +01:00
local function node_timer(pos, elapsed)
local mem = tubelib2.get_mem(pos)
2019-04-14 19:38:25 +02:00
local res = false
2019-03-25 22:19:42 +01:00
--local t = minetest.get_us_time()
if mem.running then
res = signs_bot.run_next_command(pos, mem)
end
2019-03-25 22:19:42 +01:00
--t = minetest.get_us_time() - t
--print("node_timer", t)
return res and mem.running
2019-03-23 21:15:13 +01:00
end
local function on_receive_fields(pos, formname, fields, player)
if minetest.is_protected(pos, player:get_player_name()) then
return
end
local mem = tubelib2.get_mem(pos)
local meta = minetest.get_meta(pos)
if fields.update then
meta:set_string("formspec", formspec(pos, mem))
elseif fields.start then
2019-03-23 21:15:13 +01:00
start_robot(pos)
elseif fields.stop then
2019-03-24 19:03:12 +01:00
signs_bot.stop_robot(pos, mem)
2019-03-23 21:15:13 +01:00
end
end
2019-06-20 16:22:01 +02:00
local function on_rightclick(pos)
local mem = tubelib2.get_mem(pos)
M(pos):set_string("formspec", formspec(pos, mem))
end
2019-03-29 20:20:51 +01:00
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
2019-03-23 21:15:13 +01:00
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
2019-03-29 20:20:51 +01:00
local mem = tubelib2.get_mem(pos)
if mem.running then
return 0
end
local name = stack:get_name()
if listname == "sign" and minetest.get_item_group(name, "sign_bot_sign") ~= 1 then
2019-03-29 20:20:51 +01:00
return 0
end
2019-03-23 21:15:13 +01:00
return stack:get_count()
end
2019-03-29 20:20:51 +01:00
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local mem = tubelib2.get_mem(pos)
if mem.running then
return 0
end
return stack:get_count()
end
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
local mem = tubelib2.get_mem(pos)
if mem.running then
return 0
end
if from_list ~= to_list then
return 0
end
return count
end
2019-03-23 21:15:13 +01:00
minetest.register_node("signs_bot:box", {
description = I("Signs Bot Box"),
stack_max = 1,
tiles = {
-- up, down, right, left, back, front
'signs_bot_base_top.png',
'signs_bot_base_top.png',
'signs_bot_base_right.png',
'signs_bot_base_left.png',
'signs_bot_base_front.png',
'signs_bot_base_front.png',
},
on_construct = function(pos)
2019-04-14 19:38:25 +02:00
local meta = M(pos)
2019-03-23 21:15:13 +01:00
local inv = meta:get_inventory()
inv:set_size('main', 8)
inv:set_size('sign', 6)
2019-03-23 21:15:13 +01:00
end,
after_place_node = function(pos, placer)
local mem = tubelib2.init_mem(pos)
mem.running = false
2019-06-28 23:49:01 +02:00
mem.error = false
2019-04-14 19:38:25 +02:00
local meta = M(pos)
2019-06-28 23:49:01 +02:00
local number = ""
if minetest.global_exists("techage") then
number = techage.add_node(pos, "signs_bot:box")
end
2019-03-23 21:15:13 +01:00
meta:set_string("owner", placer:get_player_name())
meta:set_string("number", number)
meta:set_string("formspec", formspec(pos, mem))
2019-03-23 21:15:13 +01:00
meta:set_string("signs_bot_cmnd", "turn_off")
meta:set_int("err_code", 0)
signs_bot.infotext(pos, I("stopped"))
2019-03-23 21:15:13 +01:00
end,
signs_bot_get_signal = signs_bot_get_signal,
signs_bot_on_signal = signs_bot_on_signal,
2019-03-23 21:15:13 +01:00
on_receive_fields = on_receive_fields,
2019-06-20 16:22:01 +02:00
on_rightclick = on_rightclick,
2019-03-29 20:20:51 +01:00
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
allow_metadata_inventory_move = allow_metadata_inventory_move,
2019-03-23 21:15:13 +01:00
can_dig = function(pos, player)
if minetest.is_protected(pos, player:get_player_name()) then
2019-03-23 21:15:13 +01:00
return
end
2019-06-28 23:49:01 +02:00
local mem = tubelib2.get_mem(pos)
2019-03-23 21:15:13 +01:00
if mem.running then
return
end
local inv = M(pos):get_inventory()
return inv:is_empty("main") and inv:is_empty("sign")
end,
on_dig = function(pos, node, puncher, pointed_thing)
2019-03-23 21:15:13 +01:00
minetest.node_dig(pos, node, puncher, pointed_thing)
end,
on_timer = node_timer,
on_rotate = screwdriver.disallow,
2019-03-23 21:15:13 +01:00
paramtype2 = "facedir",
is_ground_content = false,
groups = {cracky = 1},
sounds = default.node_sound_metal_defaults(),
})
if minetest.global_exists("techage") then
minetest.register_craft({
output = "signs_bot:box",
recipe = {
{"default:steel_ingot", "group:wood", "default:steel_ingot"},
{"basic_materials:motor", "techage:ta4_wlanchip", "basic_materials:gear_steel"},
{"default:tin_ingot", "", "default:tin_ingot"}
}
})
else
minetest.register_craft({
output = "signs_bot:box",
recipe = {
{"default:steel_ingot", "group:wood", "default:steel_ingot"},
{"basic_materials:motor", "default:mese_crystal", "basic_materials:gear_steel"},
{"default:tin_ingot", "", "default:tin_ingot"}
}
})
end
2019-03-23 21:15:13 +01:00
if minetest.global_exists("techage") then
2019-06-11 22:52:53 +02:00
techage.register_node({"signs_bot:box"}, {
on_pull_item = function(pos, in_dir, num)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return techage.get_items(inv, "main", num)
end,
on_push_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return techage.put_items(inv, "main", stack)
end,
on_unpull_item = function(pos, in_dir, stack)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return techage.put_items(inv, "main", stack)
end,
on_recv_message = function(pos, topic, payload)
2019-06-28 23:49:01 +02:00
local mem = tubelib2.get_mem(pos)
if topic == "state" then
2019-06-28 23:49:01 +02:00
if mem.error then
return "fault"
elseif mem.running then
if mem.curr_cmnd == "stop" then
return "standby"
elseif mem.blocked then
return "blocked"
else
return "running"
end
elseif mem.capa then
if mem.capa <= 0 then
return "nopower"
elseif mem.capa >= signs_bot.MAX_CAPA then
return "stopped"
else
return "loading"
end
else
return "stopped"
end
elseif topic == "fuel" then
return signs_bot.percent_value(signs_bot.MAX_CAPA, mem.capa)
else
return "unsupported"
end
end,
})
end
if minetest.get_modpath("doc") then
doc.add_entry("signs_bot", "box", {
name = I("Signs Bot Box"),
data = {
item = "signs_bot:box",
text = table.concat({
I("The Box is the housing of the bot."),
I("Place the box and start the bot by means of the 'On' button."),
I("If the mod techage is installed, the bot needs electrical power."),
"",
I("The bot leaves the box on the right side."),
I("It will not start, if this position is blocked."),
"",
I("To stop and remove the bot, press the 'Off' button."),
"",
I("The box inventory simulates the inventory of the bot."),
I("You will not be able to access the inventory, if the bot is running."),
I("The bot can carry up to 8 stacks and 6 signs with it."),
}, "\n")
},
})
end