techage/icta_controller/commands.lua
Michal Cieslakiewicz 336fef53af Allow read of Distributor slot status
Add support for reading distributor slot status. This action
is complementary to already present filter setting function.
'port' distributor message is modified to accept filter color
only (without '=on/off'), device returns selected filter state.
A wrapper function ($get_filter(...)) for Lua Controller and
condition selector for ICTA Controller are implemented as well.

Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
2021-01-31 19:10:14 +01:00

796 lines
17 KiB
Lua

--[[
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
ICTA Controller - Register all controller commands
]]--
-- for lazy programmers
local M = minetest.get_meta
local S = techage.S
local logic = techage.logic
function techage.compare(op1, op2, method)
if method == "is" then
return op1 == op2
elseif method == "is not" then
return op1 ~= op2
elseif method == "greater" then
return op1 > op2
elseif method == "less" then
return op1 < op2
end
end
function techage.fmt_number(num)
local mtch = num:match('^(%d+).*')
if mtch and num ~= mtch then
return mtch.."..."
end
return num
end
techage.icta_register_condition("initial", {
title = "initial",
formspec = {
{
type = "label",
name = "lbl",
label = "Condition is true only after\ncontroller start.",
},
},
-- Return two chunks of executable Lua code for the controller, according:
-- return <read condition>, <expected result>
code = function(data, environ)
local condition = function(env, idx)
return env.ticks
end
local result = function(val)
return val == 1
end
return condition, result
end,
button = function(data, environ) return "Initial after start" end,
})
techage.icta_register_condition("true", {
title = "true",
formspec = {
{
type = "label",
name = "lbl",
label = "Condition is always true.",
},
},
code = function(data, environ)
local condition = function(env, idx)
return true
end
local result = function(val)
return val == true
end
return condition, result
end,
button = function(data, environ) return "true" end,
})
techage.icta_register_condition("condition", {
title = "condition",
formspec = {
{
type = "textlist",
name = "condition",
label = "condition row number",
choices = "1,2,3,4,5,6,7,8",
default = "",
},
{
type = "textlist",
name = "operand",
label = "condition",
choices = "was true, was not true",
default = "was true",
},
{
type = "label",
name = "lbl",
label = "Used to execute two or more\nactions based on one condition.",
},
},
code = function(data, environ)
local condition = function(env, idx)
local index = data.condition:byte(-1) - 0x30
return env.condition[index]
end
local result = function(val)
return val == (data.operand == "was true")
end
return condition, result
end,
button = function(data, environ) return "cond("..data.condition:sub(-1,-1)..","..data.operand..")" end,
})
techage.icta_register_condition("input", {
title = "inputs",
formspec = {
{
type = "digits",
name = "number",
label = "block number",
default = "",
},
{
type = "textlist",
name = "operand",
choices = "is,is not",
default = "is",
},
{
type = "textlist",
name = "value",
choices = "on,off,invalid",
default = "on",
},
{
type = "label",
name = "lbl",
label = "An input is only available,\nif a block sends on/off\ncommands to the controller.",
},
},
button = function(data, environ) -- default button label
return 'inp('..techage.fmt_number(data.number)..','..data.operand.." "..data.value..')'
end,
code = function(data, environ)
local condition = function(env, idx)
return env.input[data.number]
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
end
return condition, result
end,
})
techage.icta_register_condition("state", {
title = "read block state",
formspec = {
{
type = "number",
name = "number",
label = "block number",
default = "",
},
{
type = "textlist",
name = "operand",
label = "",
choices = "is,is not",
default = "is",
},
{
type = "textlist",
name = "value",
label = "",
choices = "stopped,running,standby,blocked,nopower,fault,unloaded,invalid,on,off",
default = "stopped",
},
{
type = "label",
name = "lbl",
label = "Read the state of a TA3/TA4 machine.\n",
},
},
button = function(data, environ) -- default button label
return 'sts('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
end,
code = function(data, environ)
local condition = function(env, idx)
return techage.send_single(environ.number, data.number, "state")
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
end
return condition, result
end,
})
techage.icta_register_condition("fuel", {
title = "read amount of fuel",
formspec = {
{
type = "number",
name = "number",
label = "block number",
default = "",
},
{
type = "textlist",
name = "operand",
label = "",
choices = "greater,less",
default = "greater",
},
{
type = "digits",
name = "value",
label = "than",
default = ""
},
{
type = "label",
name = "lbl",
label = "Read and evaluate the fuel value\nof a fuel consuming block.",
},
},
button = function(data, environ)
return 'fuel('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
end,
code = function(data, environ)
local condition = function(env, idx)
return techage.send_single(environ.number, data.number, "fuel")
end
local result = function(val)
return techage.compare(val, tonumber(data.value), data.operand)
end
return condition, result
end,
})
techage.icta_register_condition("load", {
title = "read power/liquid load",
formspec = {
{
type = "number",
name = "number",
label = "block number",
default = "",
},
{
type = "textlist",
name = "operand",
label = "",
choices = "greater,less",
default = "greater",
},
{
type = "digits",
name = "value",
label = "than",
default = ""
},
{
type = "label",
name = "lbl",
label = "Read and evaluate the load (0..100)\nof a tank/storage block.",
},
},
button = function(data, environ)
return 'load('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
end,
code = function(data, environ)
local condition = function(env, idx)
return techage.send_single(environ.number, data.number, "load")
end
local result = function(val)
return techage.compare(val, tonumber(data.value), data.operand)
end
return condition, result
end,
})
techage.icta_register_condition("depth", {
title = "read quarry depth",
formspec = {
{
type = "number",
name = "number",
label = "quarry number",
default = "",
},
{
type = "textlist",
name = "operand",
label = "",
choices = "greater,less",
default = "greater",
},
{
type = "digits",
name = "value",
label = "than",
default = ""
},
{
type = "label",
name = "lbl",
label = "Read and evaluate the current\ndepth of a quarry block.",
},
},
button = function(data, environ)
return 'depth('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
end,
code = function(data, environ)
local condition = function(env, idx)
return techage.send_single(environ.number, data.number, "depth")
end
local result = function(val)
return techage.compare(val, tonumber(data.value), data.operand)
end
return condition, result
end,
})
techage.icta_register_condition("delivered", {
title = "read delivered power",
formspec = {
{
type = "number",
name = "number",
label = "block number",
default = "",
},
{
type = "textlist",
name = "operand",
label = "",
choices = "greater,less",
default = "greater",
},
{
type = "digits",
name = "value",
label = "than",
default = ""
},
{
type = "label",
name = "lbl",
label = "Read and evaluate the delivered\npower of a generator block.\nPower consuming blocks like accus\ncould also provide a negative value.",
},
},
button = function(data, environ)
return 'deliv('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
end,
code = function(data, environ)
local condition = function(env, idx)
return techage.send_single(environ.number, data.number, "delivered")
end
local result = function(val)
return techage.compare(val, tonumber(data.value), data.operand)
end
return condition, result
end,
})
techage.icta_register_condition("chest", {
title = "read chest state",
formspec = {
{
type = "number",
name = "number",
label = "chest number",
default = "",
},
{
type = "textlist",
name = "operand",
label = "",
choices = "is,is not",
default = "is",
},
{
type = "textlist",
name = "value",
label = "",
choices = "empty,loaded,full,invalid",
default = "empty",
},
{
type = "label",
name = "lbl",
label = "Read the state from a Techage chest\n"..
"and other similar blocks.",
},
},
button = function(data, environ) -- default button label
return 'chest('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
end,
code = function(data, environ)
local condition = function(env, idx)
return techage.send_single(environ.number, data.number, "state")
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
end
return condition, result
end,
})
techage.icta_register_condition("signaltower", {
title = "read Signal Tower state",
formspec = {
{
type = "number",
name = "number",
label = "Signal Tower number",
default = "",
},
{
type = "textlist",
name = "operand",
choices = "is,is not",
default = "is",
},
{
type = "textlist",
name = "value",
choices = "off,green,amber,red,invalid",
default = "off",
},
{
type = "label",
name = "lbl",
label = "Read the color state\nof a Signal Tower.",
},
},
button = function(data, environ) -- default button label
return 'tower('..techage.fmt_number(data.number)..","..data.operand..' '..data.value..')'
end,
code = function(data, environ)
local condition = function(env, idx)
return techage.send_single(environ.number, data.number, "state")
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
end
return condition, result
end,
})
techage.icta_register_action("signaltower", {
title = "send Signal Tower command",
formspec = {
{
type = "numbers",
name = "number",
label = "Signal Tower number",
default = "",
},
{
type = "textlist",
name = "value",
label = "lamp color",
choices = "off,green,amber,red",
default = "red",
},
{
type = "label",
name = "lbl",
label = "Turn on/off a Signal Tower lamp.",
},
},
button = function(data, environ)
return 'tower('..techage.fmt_number(data.number)..","..data.value..')'
end,
code = function(data, environ)
return function(env, output, idx)
techage.send_multi(environ.number, data.number, data.value)
end
end,
})
techage.icta_register_action("switch", {
title = "turn block on/off",
formspec = {
{
type = "numbers",
name = "number",
label = "block number(s)",
default = "",
},
{
type = "textlist",
name = "value",
label = "state",
choices = "on,off",
default = "on",
},
{
type = "label",
name = "lbl",
label = "Used for lamps, machines, gates,...",
},
},
button = function(data, environ)
return 'turn('..techage.fmt_number(data.number)..","..data.value..')'
end,
code = function(data, environ)
return function(env, output, idx)
techage.send_multi(environ.number, data.number, data.value)
end
end,
})
techage.icta_register_action("display", {
title = "Display: overwrite one line",
formspec = {
{
type = "numbers",
name = "number",
label = "Display number",
default = "",
},
{
type = "textlist",
name = "row",
label = "Display line",
choices = "1,2,3,4,5",
default = "1",
},
{
type = "ascii",
name = "text",
label = "text",
default = "",
},
{
type = "label",
name = "lbl",
label = "Use a '*' character as reference\nto any condition result",
},
},
code = function(data, environ)
return function(env, output, idx)
local text = string.gsub(data.text, "*", tostring(env.result[idx]))
local payload = safer_lua.Store()
payload.set("row", data.row)
payload.set("str", text)
techage.send_multi(environ.number, data.number, "set", payload)
end
end,
button = function(data, environ)
return "lcd("..techage.fmt_number(data.number)..","..data.row..',"'..data.text..'")'
end,
})
techage.icta_register_action("cleardisplay", {
title = "Display: Clear screen",
formspec = {
{
type = "number",
name = "number",
label = "Display number",
default = "",
},
},
code = function(data, environ)
return function(env, output, idx)
techage.send_multi(environ.number, data.number, "clear")
end
end,
button = function(data, environ)
return "clear lcd("..techage.fmt_number(data.number)..")"
end,
})
techage.icta_register_action("chat", {
title = "send chat message",
formspec = {
{
type = "ascii",
name = "text",
label = "message",
default = "",
},
{
type = "label",
name = "lbl",
label = "The chat message is send to the\nController owner, only.",
},
},
code = function(data, environ)
return function(env, output, idx)
minetest.chat_send_player(environ.owner, "[TA4 ICTA Controller] "..data.text)
end
end,
button = function(data, environ)
return 'chat("'..data.text:sub(1,12)..'")'
end,
})
function techage.icta_door_toggle(pos, owner, state)
pos = minetest.string_to_pos("("..pos..")")
if pos then
local door = doors.get(pos)
if door then
local player = {
get_player_name = function() return owner end,
is_player = function() return true end,
}
if state == "open" then
door:open(player)
elseif state == "close" then
door:close(player)
end
end
end
end
techage.icta_register_action("door", {
title = "open/close door",
formspec = {
{
type = "digits",
name = "pos",
label = "door position like: 123,7,-1200",
default = "",
},
{
type = "textlist",
name = "door_state",
label = "door state",
choices = "open,close",
default = "open",
},
{
type = "label",
name = "lbl",
label = "For standard doors like the Steel Doors.\n"..
"Use the Techage Info Tool to\neasily determine a door position.",
},
},
code = function(data, environ)
return function(env, output, idx)
techage.icta_door_toggle(data.pos, environ.owner, data.door_state)
end
end,
button = function(data, environ)
return 'door("'..data.pos..'",'..data.door_state..")"
end,
})
function techage.icta_player_detect(own_num, number, name)
local state = techage.send_single(own_num, number, "name", nil)
if state ~= "" then
if name == "*" or string.find(name, state) then
return state
end
elseif name == "-" then
return state
end
return nil
end
techage.icta_register_condition("playerdetector", {
title = "read Player Detector",
formspec = {
{
type = "number",
name = "number",
label = "Player Detector number",
default = "",
},
{
type = "ascii",
name = "name",
label = "player name(s) or * for all",
default = "",
},
{
type = "label",
name = "lbl",
label = "Read and check the name\nof a Player Detector.\nUse a '*' character for all player names.\n Use a '-' character for no player.",
},
},
code = function(data, environ)
local condition = function(env, idx)
return techage.icta_player_detect(environ.number, data.number, data.name)
end
local result = function(val)
return val ~= nil
end
return condition, result
end,
button = function(data, environ)
return "detector("..techage.fmt_number(data.number)..","..data.name:sub(1,8)..")"
end,
})
techage.icta_register_action("set_filter", {
title = "turn Distributor filter on/off",
formspec = {
{
type = "number",
name = "number",
label = "distri number",
default = "",
},
{
type = "textlist",
name = "color",
label = "filter port",
choices = "red,green,blue,yellow",
default = "red",
},
{
type = "textlist",
name = "value",
label = "state",
choices = "on,off",
default = "on",
},
{
type = "label",
name = "lbl",
label = "turn Distributor filter port on/off\n",
},
},
button = function(data, environ)
return 'turn('..techage.fmt_number(data.number)..","..data.color..","..data.value..')'
end,
code = function(data, environ)
return function(env, output, idx)
local payload = data.color.."="..data.value
techage.send_single(environ.number, data.number, "port", payload)
end
end,
})
techage.icta_register_condition("get_filter", {
title = "read state of a Distributor filter slot",
formspec = {
{
type = "number",
name = "number",
label = "distri number",
default = "",
},
{
type = "textlist",
name = "color",
label = "filter port",
choices = "red,green,blue,yellow",
default = "red",
},
{
type = "textlist",
name = "operand",
choices = "is,is not",
default = "is",
},
{
type = "textlist",
name = "value",
label = "state",
choices = "on,off",
default = "off",
},
{
type = "label",
name = "lbl",
label = "Read state of a Distributor filter slot.\n",
},
},
button = function(data, environ) -- default button label
return 'fltr('..techage.fmt_number(data.number)..","..data.color..' '..data.operand..' '..data.value..')'
end,
code = function(data, environ)
local condition = function(env, idx)
return techage.send_single(environ.number, data.number, "port", data.color)
end
local result = function(val)
return techage.compare(val, data.value, data.operand)
end
return condition, result
end,
})