mirror of
https://github.com/joe7575/techpack.git
synced 2024-12-25 15:14:31 +01:00
New commands implemented
Controller restructured
This commit is contained in:
parent
f58bb6336a
commit
d40b9a54c5
@ -2,33 +2,7 @@
|
||||
|
||||
This tubelib extension provides small and smart sensors, actors and controllers.
|
||||
|
||||
The most important and smart node of SmartLine is the SmartLine Controller, a 'computer' to control and monitor Tubelib based machines.
|
||||
You don't need any programming skills, it is more like a configuration according to the "IF this THEN that" concept:
|
||||
|
||||
IF <cond1> OR <cond2> THEN <action>
|
||||
IF <cond1> AND <cond2> THEN <action>
|
||||
|
||||
Examples for conditions are:
|
||||
- the Player Detector detects a player
|
||||
- a button is pressed
|
||||
- a node state is fault, blocked, standby,...
|
||||
- a timer is expired
|
||||
|
||||
Examples for actions are:
|
||||
- switch on/off tubelib nodes, like lamps, door blocks, machines
|
||||
- send mail/chat messages to the owner
|
||||
- output a text message to the display
|
||||
- set timer variables
|
||||
- set/reset flag variables
|
||||
|
||||
The mod comes with several new nodes, all in a smart and small housing:
|
||||
- a Player Detector, sending on/off commands to connected nodes
|
||||
- a Smart Button, sending on/off commands to connected nodes
|
||||
- a Display for text outputs of the controller
|
||||
- a Signal Tower, with green, amber, red lights to signal error/fault states
|
||||
- a Timer (derived from Tubelib Addons2), for daytime based actions
|
||||
- a Sequencer (derived from Tubelib Addons2), for time triggered actions (time in seconds)
|
||||
|
||||
A Tutorial to this Mod is available as ![Wiki](https://github.com/joe7575/techpack/wiki)
|
||||
|
||||
API Reference: ![api.md](https://github.com/joe7575/techpack/blob/master/smartline/api.md)
|
||||
|
||||
|
@ -17,22 +17,28 @@
|
||||
smartline.register_condition("default", {
|
||||
title = "",
|
||||
formspec = {},
|
||||
on_execute = function(data, flags, timers, inputs, actions) end,
|
||||
on_execute = function(data, environ) end,
|
||||
button_label = function(data) return "" end,
|
||||
})
|
||||
|
||||
smartline.register_action("default", {
|
||||
title = "",
|
||||
formspec = {},
|
||||
on_execute = function(data, flags, timers, inputs) end,
|
||||
on_execute = function(data, environ, number) end,
|
||||
button_label = function(data) return "" end,
|
||||
})
|
||||
|
||||
|
||||
smartline.register_condition("true", {
|
||||
title = "true",
|
||||
formspec = {},
|
||||
on_execute = function(data, flags, timers, inputs, actions)
|
||||
formspec = {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: Condition is always true.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, environ)
|
||||
return true
|
||||
end,
|
||||
button_label = function(data)
|
||||
@ -42,8 +48,14 @@ smartline.register_condition("true", {
|
||||
|
||||
smartline.register_condition("false", {
|
||||
title = "false",
|
||||
formspec = {},
|
||||
on_execute = function(data, flags, timers, inputs, actions)
|
||||
formspec = {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: Condition is always false.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, environ)
|
||||
return false
|
||||
end,
|
||||
button_label = function(data)
|
||||
@ -51,8 +63,25 @@ smartline.register_condition("false", {
|
||||
end,
|
||||
})
|
||||
|
||||
smartline.register_condition("toggle", {
|
||||
title = "toggle flag",
|
||||
formspec = {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: This flag toggles (true/false) every second\nand can be used to trigger\nan action every two seconds.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, environ)
|
||||
return environ.toggle
|
||||
end,
|
||||
button_label = function(data)
|
||||
return "toggle"
|
||||
end,
|
||||
})
|
||||
|
||||
smartline.register_condition("flag", {
|
||||
title = "flag test",
|
||||
title = "flag",
|
||||
formspec = {
|
||||
{
|
||||
type = "textlist",
|
||||
@ -71,17 +100,43 @@ smartline.register_condition("flag", {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: Don't forget to reset the flag again.",
|
||||
label = "Hint: The flag will keep its state.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, inputs, actions)
|
||||
return flags[data.flag] == data.value_text
|
||||
on_execute = function(data, environ)
|
||||
return environ.flags[data.flag] == data.value_text
|
||||
end,
|
||||
button_label = function(data)
|
||||
return data.flag_text.."=="..data.value_text
|
||||
end,
|
||||
})
|
||||
|
||||
smartline.register_condition("flag_reset", {
|
||||
title = "flag test and clear",
|
||||
formspec = {
|
||||
{
|
||||
type = "textlist",
|
||||
name = "flag",
|
||||
label = "flag",
|
||||
choices = "f1,f2,f3,f4,f5,f6,f7,f8",
|
||||
default = 1,
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: The result is true, if the flag was true.\nAfter evaluation the flag is set to false.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, environ)
|
||||
local res = environ.flags[data.flag] == "true"
|
||||
environ.flags[data.flag] = "false"
|
||||
return res
|
||||
end,
|
||||
button_label = function(data)
|
||||
return "test_clear("..data.flag_text..")"
|
||||
end,
|
||||
})
|
||||
|
||||
smartline.register_action("flag", {
|
||||
title = "flag set",
|
||||
formspec = {
|
||||
@ -102,11 +157,11 @@ smartline.register_action("flag", {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: Flags are stored permanently and can be used by other rules.",
|
||||
label = "Hint: Flags are stored permanently and\ncan be used as condition by other rules.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
flags[data.flag] = data.value_text
|
||||
on_execute = function(data, environ, number)
|
||||
environ.flags[data.flag] = data.value_text
|
||||
end,
|
||||
button_label = function(data)
|
||||
return data.flag_text.."="..data.value_text
|
||||
@ -114,7 +169,7 @@ smartline.register_action("flag", {
|
||||
})
|
||||
|
||||
smartline.register_condition("input", {
|
||||
title = "check input",
|
||||
title = "inputs",
|
||||
formspec = {
|
||||
{
|
||||
type = "field",
|
||||
@ -126,17 +181,17 @@ smartline.register_condition("input", {
|
||||
type = "textlist",
|
||||
name = "value",
|
||||
label = "is",
|
||||
choices = "on,off",
|
||||
choices = "on,off,false",
|
||||
default = 1,
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: An input is only available,\nif the sending node is connected with the controller.",
|
||||
label = "Hint: An input is only available,\nif the sending node is connected\nwith the controller.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, inputs, actions)
|
||||
return inputs[data.number] == data.value_text
|
||||
on_execute = function(data, environ)
|
||||
return environ.inputs[data.number] == data.value_text
|
||||
end,
|
||||
button_label = function(data)
|
||||
return "i("..data.number..")=="..data.value_text
|
||||
@ -155,8 +210,8 @@ smartline.register_condition("timer", {
|
||||
default = 1,
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, inputs, actions)
|
||||
return timers[data.timer] == 0
|
||||
on_execute = function(data, environ)
|
||||
return environ.timers[data.timer] == 0
|
||||
end,
|
||||
button_label = function(data)
|
||||
return data.timer_text.." expired"
|
||||
@ -180,8 +235,8 @@ smartline.register_action("timer", {
|
||||
default = "",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
timers[data.timer] = tonumber(data.value) or 0
|
||||
on_execute = function(data, environ, number)
|
||||
environ.timers[data.timer] = tonumber(data.value) or 0
|
||||
end,
|
||||
button_label = function(data)
|
||||
return data.timer_text.."="..data.value
|
||||
@ -189,30 +244,31 @@ smartline.register_action("timer", {
|
||||
})
|
||||
|
||||
smartline.register_condition("pusher", {
|
||||
title = "Pusher state",
|
||||
title = "node state request",
|
||||
formspec = {
|
||||
{
|
||||
type = "field",
|
||||
name = "number",
|
||||
label = "state from Pusher with number",
|
||||
label = "state from node with number",
|
||||
default = "",
|
||||
},
|
||||
{
|
||||
type = "textlist",
|
||||
name = "value",
|
||||
label = "is",
|
||||
choices = "stopped,running,standby,blocked,fault",
|
||||
choices = "stopped,running,standby,blocked,fault,false",
|
||||
default = 1,
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint:\n - standby means 'nothing to do'\n - blocked means 'inventory is full'",
|
||||
label = "Hint: Read the state from another node.\nWorks for Pusher, Harvester, Quarry,\nFermenter, and Reformer",
|
||||
},
|
||||
},
|
||||
|
||||
on_execute = function(data, flags, timers, inputs, actions)
|
||||
return tubelib.send_request(data.number, "state", "") == data.value_text
|
||||
on_execute = function(data, environ)
|
||||
environ.state = tubelib.send_request(data.number, "state", "")
|
||||
return environ.state == data.value_text
|
||||
end,
|
||||
button_label = function(data)
|
||||
return "st("..data.number..")=="..string.sub(data.value_text or "???", 1, 4).."."
|
||||
@ -220,7 +276,7 @@ smartline.register_condition("pusher", {
|
||||
})
|
||||
|
||||
smartline.register_condition("fuel", {
|
||||
title = "fuel state",
|
||||
title = "fuel state request",
|
||||
formspec = {
|
||||
{
|
||||
type = "field",
|
||||
@ -232,12 +288,17 @@ smartline.register_condition("fuel", {
|
||||
type = "textlist",
|
||||
name = "value",
|
||||
label = "is",
|
||||
choices = "full,empty,not full,not empty",
|
||||
choices = "full,empty,not full,not empty,false",
|
||||
default = 1,
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: Read the fuel state from another node.\nWorks for Harvester and Quarry",
|
||||
},
|
||||
},
|
||||
|
||||
on_execute = function(data, flags, timers, inputs, actions)
|
||||
on_execute = function(data, environ)
|
||||
if data.value > 2 then
|
||||
return tubelib.send_request(data.number, "fuel", nil) ~= string.sub(data.value_text or "???", 5)
|
||||
else
|
||||
@ -254,7 +315,7 @@ smartline.register_condition("fuel", {
|
||||
})
|
||||
|
||||
smartline.register_condition("signaltower", {
|
||||
title = "Signal Tower state",
|
||||
title = "Signal Tower state request",
|
||||
formspec = {
|
||||
{
|
||||
type = "field",
|
||||
@ -266,17 +327,17 @@ smartline.register_condition("signaltower", {
|
||||
type = "textlist",
|
||||
name = "value",
|
||||
label = "is",
|
||||
choices = "off,green,amber,red,not off,not green,not amber,not red",
|
||||
choices = "off,green,amber,red,not off,not green,not amber,not red,false",
|
||||
default = 1,
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: Works also for Signal Towers in unloaded areas.",
|
||||
label = "Hint: Read the state from a Signal Tower.",
|
||||
},
|
||||
},
|
||||
|
||||
on_execute = function(data, flags, timers, inputs, actions)
|
||||
on_execute = function(data, environ)
|
||||
if data.value > 4 then
|
||||
return tubelib.send_request(data.number, "state", nil) ~= string.sub(data.value_text or "???", 5)
|
||||
else
|
||||
@ -308,8 +369,13 @@ smartline.register_action("signaltower", {
|
||||
choices = "off,green,amber,red",
|
||||
default = 1,
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: Turn on a lamp from a Signal Tower.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
on_execute = function(data, environ, number)
|
||||
tubelib.send_message(data.number, data.owner, nil, data.value_text, number)
|
||||
end,
|
||||
button_label = function(data)
|
||||
@ -318,7 +384,7 @@ smartline.register_action("signaltower", {
|
||||
})
|
||||
|
||||
smartline.register_action("switch", {
|
||||
title = "switch nodes on/off",
|
||||
title = "node on/off command",
|
||||
formspec = {
|
||||
{
|
||||
type = "field",
|
||||
@ -339,7 +405,7 @@ smartline.register_action("switch", {
|
||||
label = "Hint: Used for pushers, lamps, machines, gates,...",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
on_execute = function(data, environ, number)
|
||||
tubelib.send_message(data.number, data.owner, nil, data.value_text, number)
|
||||
end,
|
||||
button_label = function(data)
|
||||
@ -365,11 +431,12 @@ smartline.register_action("display1", {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: Works also for Displays in unloaded areas.",
|
||||
label = "Hint: Use a '*' character as reference to any\ncondition state",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
tubelib.send_message(data.number, data.owner, nil, "text", data.text)
|
||||
on_execute = function(data, environ, number)
|
||||
local text = string.gsub(data.text, "*", environ.state or "<unknown>")
|
||||
tubelib.send_message(data.number, data.owner, nil, "text", text)
|
||||
end,
|
||||
button_label = function(data)
|
||||
return "display("..data.number..")"
|
||||
@ -401,11 +468,12 @@ smartline.register_action("display2", {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: Works also for Displays in unloaded areas.",
|
||||
label = "Hint: Use a '*' character as reference to any\ncondition state",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
local payload = {row = data.row, str = data.text}
|
||||
on_execute = function(data, environ, number)
|
||||
local text = string.gsub(data.text, "*", environ.state or "<unknown>")
|
||||
local payload = {row = data.row, str = text}
|
||||
tubelib.send_message(data.number, data.owner, nil, "row", payload)
|
||||
end,
|
||||
button_label = function(data)
|
||||
@ -431,11 +499,11 @@ smartline.register_action("display3", {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: use a '*' character as reference to the player name",
|
||||
label = "Hint: Use a '*' character as reference to the\nplayer name",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
local text = string.gsub(data.text, "*", flags.name or "<unknown>")
|
||||
on_execute = function(data, environ, number)
|
||||
local text = string.gsub(data.text, "*", environ.name or "<unknown>")
|
||||
tubelib.send_message(data.number, data.owner, nil, "text", text)
|
||||
end,
|
||||
button_label = function(data)
|
||||
@ -453,7 +521,7 @@ smartline.register_action("display4", {
|
||||
default = "",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
on_execute = function(data, environ, number)
|
||||
tubelib.send_message(data.number, data.owner, nil, "clear", "")
|
||||
end,
|
||||
button_label = function(data)
|
||||
@ -463,7 +531,7 @@ smartline.register_action("display4", {
|
||||
|
||||
if minetest.get_modpath("mail") and mail ~= nil then
|
||||
smartline.register_action("mail", {
|
||||
title = "mail",
|
||||
title = "mail send",
|
||||
formspec = {
|
||||
{
|
||||
type = "field",
|
||||
@ -471,8 +539,13 @@ if minetest.get_modpath("mail") and mail ~= nil then
|
||||
label = "send the message",
|
||||
default = "",
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: The mail is send to the Controller owner, only.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
on_execute = function(data, environ, number)
|
||||
mail.send("Server", data.owner, "[SmartLine Controller]", data.text)
|
||||
end,
|
||||
button_label = function(data)
|
||||
@ -482,7 +555,7 @@ if minetest.get_modpath("mail") and mail ~= nil then
|
||||
end
|
||||
|
||||
smartline.register_action("chat", {
|
||||
title = "chat",
|
||||
title = "chat send",
|
||||
formspec = {
|
||||
{
|
||||
type = "field",
|
||||
@ -490,8 +563,13 @@ smartline.register_action("chat", {
|
||||
label = "send the message",
|
||||
default = "",
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: The chat message is send to the\nController owner, only.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
on_execute = function(data, environ, number)
|
||||
minetest.chat_send_player(data.owner, "[SmartLine Controller] "..data.text)
|
||||
end,
|
||||
button_label = function(data)
|
||||
@ -527,7 +605,7 @@ smartline.register_action("door", {
|
||||
},
|
||||
{
|
||||
type = "textlist",
|
||||
name = "state",
|
||||
name = "door_state",
|
||||
label = "set",
|
||||
choices = "open,close",
|
||||
default = 1,
|
||||
@ -535,24 +613,24 @@ smartline.register_action("door", {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl1",
|
||||
label = "For standard doors like the Steel Door",
|
||||
label = "For standard doors like the Steel Doors.",
|
||||
},
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl2",
|
||||
label = "Hint: use a marker stick to determine the door position",
|
||||
label = "Hint: Use the Tubelib Programmer to\ndetermine the door position.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, number)
|
||||
door_toggle(data.pos, data.owner, data.state_text)
|
||||
on_execute = function(data, environ, number)
|
||||
door_toggle(data.pos, data.owner, data.door_state_text)
|
||||
end,
|
||||
button_label = function(data)
|
||||
return "door("..data.state_text..")"
|
||||
return "door("..data.door_state_text..")"
|
||||
end,
|
||||
})
|
||||
|
||||
smartline.register_condition("playerdetector", {
|
||||
title = "detected player name",
|
||||
title = "Player Detector: name request",
|
||||
formspec = {
|
||||
{
|
||||
type = "field",
|
||||
@ -569,13 +647,13 @@ smartline.register_condition("playerdetector", {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: use a '*' character for all player names",
|
||||
label = "Hint: Read and check the name\nfrom a Player Detector.\n Use a '*' character for all player names.",
|
||||
},
|
||||
},
|
||||
|
||||
on_execute = function(data, flags, timers, inputs, actions)
|
||||
flags.name = tubelib.send_request(data.number, "name", nil)
|
||||
return (data.name == "*" and flags.name ~= "") or flags.name == data.name
|
||||
on_execute = function(data, environ)
|
||||
environ.name = tubelib.send_request(data.number, "name", nil)
|
||||
return (data.name == "*" and environ.name ~= "") or environ.name == data.name
|
||||
end,
|
||||
button_label = function(data)
|
||||
if string.len(data.name) > 6 then
|
||||
@ -586,7 +664,7 @@ smartline.register_condition("playerdetector", {
|
||||
})
|
||||
|
||||
smartline.register_condition("action", {
|
||||
title = "action",
|
||||
title = "actions",
|
||||
formspec = {
|
||||
{
|
||||
type = "textlist",
|
||||
@ -598,11 +676,11 @@ smartline.register_condition("action", {
|
||||
{
|
||||
type = "label",
|
||||
name = "lbl",
|
||||
label = "Hint: The corresponding flag is set for each\nexecute action. Useful to execute\nmore than one action with one condition.",
|
||||
label = "Hint: The corresponding flag is set for each\nexecuted action. Useful to execute\nmore than one action with one condition.",
|
||||
},
|
||||
},
|
||||
on_execute = function(data, flags, timers, inputs, actions)
|
||||
return actions[data.action] == true
|
||||
on_execute = function(data, environ)
|
||||
return environ.actions[data.action] == true
|
||||
end,
|
||||
button_label = function(data)
|
||||
return "action"..data.action
|
||||
|
@ -63,7 +63,7 @@ The colors show, if conditions are true or false and
|
||||
if actions were already executed or not.
|
||||
It has a 'update' button to update the view.
|
||||
|
||||
For more information, see: goo.gl/wZ5GUR
|
||||
For more information, see: goo.gl/fF5ap6
|
||||
]]
|
||||
|
||||
local sOUTPUT = "Press 'help' for edit commands"
|
||||
@ -109,12 +109,12 @@ local CondRunTimeHandlers = {}
|
||||
local ActnRunTimeHandlers = {}
|
||||
|
||||
|
||||
local function eval_cond(data, flags, timers, inputs, actions)
|
||||
return CondRunTimeHandlers[data.__idx__](data, flags, timers, inputs, actions) and 1 or 0
|
||||
local function eval_cond(data, environ)
|
||||
return CondRunTimeHandlers[data.__idx__](data, environ) and 1 or 0
|
||||
end
|
||||
|
||||
local function exec_action(data, flags, timers, number)
|
||||
ActnRunTimeHandlers[data.__idx__](data, flags, timers, number)
|
||||
local function exec_action(data, environ, number)
|
||||
ActnRunTimeHandlers[data.__idx__](data, environ, number)
|
||||
end
|
||||
|
||||
smartline = {}
|
||||
@ -255,20 +255,30 @@ local function runtime_data(postfix, type, fs_data)
|
||||
end
|
||||
|
||||
local function decrement_timers(timers)
|
||||
for idx,_ in ipairs(timers) do
|
||||
timers[idx] = tonumber(timers[idx])
|
||||
if timers[idx] >= 0 then
|
||||
timers[idx] = timers[idx] - 1
|
||||
if timers ~= nil then
|
||||
for idx,_ in pairs(timers) do
|
||||
timers[idx] = tonumber(timers[idx])
|
||||
if timers[idx] >= 0 then
|
||||
timers[idx] = timers[idx] - 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function toggle_flag(environ)
|
||||
if environ.toggle == true then
|
||||
environ.toggle = false
|
||||
else
|
||||
environ.toggle = true
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Condition formspec
|
||||
--
|
||||
local function formspec_cond(_postfix_, fs_data)
|
||||
local tbl = {"size[8.2,10]"..
|
||||
local tbl = {"size[8.2,9]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
@ -280,8 +290,8 @@ local function formspec_cond(_postfix_, fs_data)
|
||||
tbl[#tbl+1] = "label[0,0.1;Condition type:]"
|
||||
tbl[#tbl+1] = "textlist[0,0.6;8,1.4;cond;"..sConditions..";"..cond_idx.."]"
|
||||
tbl = add_controls_to_table(tbl, _postfix_, fs_data, fs_definition)
|
||||
tbl[#tbl+1] = "button[4,9.4;2,1;_cancel_;cancel]"
|
||||
tbl[#tbl+1] = "button[6,9.4;2,1;_exit_;ok]"
|
||||
tbl[#tbl+1] = "button[4,8.4;2,1;_cancel_;cancel]"
|
||||
tbl[#tbl+1] = "button[6,8.4;2,1;_exit_;ok]"
|
||||
return table.concat(tbl)
|
||||
end
|
||||
|
||||
@ -312,7 +322,7 @@ end
|
||||
-- Action formspec
|
||||
--
|
||||
local function formspec_actn(_postfix_, fs_data)
|
||||
local tbl = {"size[8.2,10]"..
|
||||
local tbl = {"size[8.2,9]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
@ -324,8 +334,8 @@ local function formspec_actn(_postfix_, fs_data)
|
||||
tbl[#tbl+1] = "label[0,0.1;Action type:]"
|
||||
tbl[#tbl+1] = "textlist[0,0.6;8,1.4;actn;"..sActions..";"..actn_idx.."]"
|
||||
tbl = add_controls_to_table(tbl, _postfix_, fs_data, fs_definition)
|
||||
tbl[#tbl+1] = "button[4,9.4;2,1;_cancel_;cancel]"
|
||||
tbl[#tbl+1] = "button[6,9.4;2,1;_exit_;ok]"
|
||||
tbl[#tbl+1] = "button[4,8.4;2,1;_cancel_;cancel]"
|
||||
tbl[#tbl+1] = "button[6,8.4;2,1;_exit_;ok]"
|
||||
return table.concat(tbl)
|
||||
end
|
||||
|
||||
@ -416,7 +426,7 @@ local function eval_formspec_oprnd(meta, fs_data, fields, readonly)
|
||||
end
|
||||
|
||||
local function formspec_main(state, fs_data, output)
|
||||
local tbl = {"size[15,10;true]"..
|
||||
local tbl = {"size[15,9;true]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
@ -424,7 +434,7 @@ local function formspec_main(state, fs_data, output)
|
||||
"label[0.8,0;label:]label[3.8,0;IF cond 1:]label[7,0;and/or]label[8.3,0;cond 2:]label[11.7,0;THEN action:]"}
|
||||
|
||||
for idx = 1,NUM_RULES do
|
||||
local ypos = idx * 0.8 - 0.4
|
||||
local ypos = idx * 0.75 - 0.4
|
||||
tbl[#tbl+1] = "label[0,"..(0.2+ypos)..";"..idx.."]"
|
||||
tbl[#tbl+1] = "button[0.4,"..ypos..";3,1;label"..idx..";"..(fs_data["label"..idx] or "...").."]"
|
||||
tbl[#tbl+1] = "button[3.5,"..ypos..";3.4,1;cond1"..idx..";"..(fs_data["cond1"..idx] or "...").."]"
|
||||
@ -432,12 +442,12 @@ local function formspec_main(state, fs_data, output)
|
||||
tbl[#tbl+1] = "button[8,".. ypos..";3.4,1;cond2"..idx..";"..(fs_data["cond2"..idx] or "...").."]"
|
||||
tbl[#tbl+1] = "button[11.5,".. ypos..";3.4,1;actna"..idx..";"..(fs_data["actna"..idx] or "...").."]"
|
||||
end
|
||||
tbl[#tbl+1] = "image_button[14,9;1,1;".. tubelib.state_button(state) ..";button;]"
|
||||
tbl[#tbl+1] = "button[10.6,9;1.5,1;state;state]"
|
||||
tbl[#tbl+1] = "button[12.2,9;1.5,1;help;help]"
|
||||
tbl[#tbl+1] = "label[0.2,8.8;"..output.."]"
|
||||
tbl[#tbl+1] = "field[0.4,9.6;4.8,1;cmnd;;<cmnd>]"
|
||||
tbl[#tbl+1] = "button[5,9.3;1,1;ok;OK]"
|
||||
tbl[#tbl+1] = "image_button[14,8.1;1,1;".. tubelib.state_button(state) ..";button;]"
|
||||
tbl[#tbl+1] = "button[10.6,8.2;1.5,1;state;state]"
|
||||
tbl[#tbl+1] = "button[12.2,8.2;1.5,1;help;help]"
|
||||
tbl[#tbl+1] = "label[0.2,8.4;"..output.."]"
|
||||
tbl[#tbl+1] = "field[6.5,8.5;3,1;cmnd;;<cmnd>]"
|
||||
tbl[#tbl+1] = "button[9.2,8.2;1,1;ok;OK]"
|
||||
return table.concat(tbl)
|
||||
end
|
||||
|
||||
@ -466,7 +476,7 @@ local function eval_formspec_main(meta, fs_data, fields, readonly)
|
||||
end
|
||||
|
||||
local function formspec_help(offs)
|
||||
return "size[15,10]"..
|
||||
return "size[15,9]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
@ -474,7 +484,7 @@ local function formspec_help(offs)
|
||||
"label[0,"..(-offs/50)..";"..sHELP.."]"..
|
||||
--"label[0.2,0;test]"..
|
||||
"scrollbar[13.5,1;0.5,7;vertical;sb_help;"..offs.."]"..
|
||||
"button[13.5,9;1.5,1;close;close]"
|
||||
"button[13.3,8.2;1.5,1;close;close]"
|
||||
end
|
||||
|
||||
local function background(xpos, ypos, val)
|
||||
@ -490,7 +500,7 @@ end
|
||||
local function formspec_state(meta, fs_data)
|
||||
local number = meta:get_string("number")
|
||||
local state = meta:get_int("state")
|
||||
local tbl = {"size[15,10;true]"..
|
||||
local tbl = {"size[15,9;true]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
@ -498,83 +508,79 @@ local function formspec_state(meta, fs_data)
|
||||
"label[0.8,0;label:]label[3.8,0;IF cond 1:]label[7,0;and/or]label[8.3,0;cond 2:]label[11.7,0;THEN action:]"}
|
||||
|
||||
if state == tubelib.RUNNING and number then
|
||||
local inputs = tubelib.get_data(number, "inputs") or {}
|
||||
local act_gate = tubelib.get_data(number, "act_gate") or {}
|
||||
local timers = tubelib.get_data(number, "timers") or {}
|
||||
local flags = tubelib.get_data(number, "flags") or {}
|
||||
local conds = tubelib.get_data(number, "conds") or {}
|
||||
local environ = tubelib.get_data(number, "environ")
|
||||
local act_gate = tubelib.get_data(number, "act_gate")
|
||||
local conds = tubelib.get_data(number, "conds")
|
||||
|
||||
for idx = 1,NUM_RULES do
|
||||
local ypos = idx * 0.6 + 0.2
|
||||
local s1 = fs_data["cond1"..idx] or " ... "
|
||||
local s2 = fs_data["cond2"..idx] or " ... "
|
||||
local sa = fs_data["actna"..idx] or " ... "
|
||||
if conds[idx] == nil then
|
||||
tbl[#tbl+1] = background(3.7, ypos, nil)
|
||||
tbl[#tbl+1] = background(8, ypos, nil)
|
||||
else
|
||||
tbl[#tbl+1] = background(3.7, ypos, conds[idx] == 1 or conds[idx] == 3)
|
||||
tbl[#tbl+1] = background(8, ypos, conds[idx] == 2 or conds[idx] == 3)
|
||||
if environ and act_gate and conds then
|
||||
for idx = 1,NUM_RULES do
|
||||
local ypos = idx * 0.6 + 0.2
|
||||
local s1 = fs_data["cond1"..idx] or " ... "
|
||||
local s2 = fs_data["cond2"..idx] or " ... "
|
||||
local sa = fs_data["actna"..idx] or " ... "
|
||||
if conds[idx] == nil then
|
||||
tbl[#tbl+1] = background(3.7, ypos, nil)
|
||||
tbl[#tbl+1] = background(8, ypos, nil)
|
||||
else
|
||||
tbl[#tbl+1] = background(3.7, ypos, conds[idx] == 1 or conds[idx] == 3)
|
||||
tbl[#tbl+1] = background(8, ypos, conds[idx] == 2 or conds[idx] == 3)
|
||||
end
|
||||
tbl[#tbl+1] = background(11.5, ypos, act_gate[idx])
|
||||
tbl[#tbl+1] = "label[0,".. ypos..";"..idx.."]"
|
||||
tbl[#tbl+1] = "label[0.5,"..ypos..";"..(fs_data["label"..idx] or " ... ").."]"
|
||||
tbl[#tbl+1] = "label[3.7,".. ypos..";"..s1.."]"
|
||||
tbl[#tbl+1] = "label[7.2,".. ypos..";"..(fs_data["oprnd"..idx] or "or").."]"
|
||||
tbl[#tbl+1] = "label[8,".. ypos..";"..s2.."]"
|
||||
tbl[#tbl+1] = "label[11.5,".. ypos..";"..sa.."]"
|
||||
if act_gate[idx] == true then
|
||||
act_gate[idx] = false
|
||||
end
|
||||
end
|
||||
tbl[#tbl+1] = background(11.5, ypos, act_gate[idx])
|
||||
tbl[#tbl+1] = "label[0,".. ypos..";"..idx.."]"
|
||||
tbl[#tbl+1] = "label[0.5,"..ypos..";"..(fs_data["label"..idx] or " ... ").."]"
|
||||
tbl[#tbl+1] = "label[3.7,".. ypos..";"..s1.."]"
|
||||
tbl[#tbl+1] = "label[7.2,".. ypos..";"..(fs_data["oprnd"..idx] or "or").."]"
|
||||
tbl[#tbl+1] = "label[8,".. ypos..";"..s2.."]"
|
||||
tbl[#tbl+1] = "label[11.5,".. ypos..";"..sa.."]"
|
||||
|
||||
tbl[#tbl+1] = "label[10,7; Seconds: "..(meta:get_int("runtime") or 1).."]"
|
||||
|
||||
tbl[#tbl+1] = "label[0,7;"..output("Inputs", "i(", ")", environ.inputs).."]"
|
||||
tbl[#tbl+1] = "label[0,7.6;"..output("Timers", "t", "", environ.timers).."]"
|
||||
tbl[#tbl+1] = "label[0,8.2;"..output("Flags", "f", "", environ.flags).."]"
|
||||
|
||||
tbl[#tbl+1] = "label[0,8.8;Hint:]"
|
||||
tbl[#tbl+1] = "box[1.3,8.8;6,0.4;#008000]"
|
||||
tbl[#tbl+1] = "label[1.4,8.8;condition true / action executed]"
|
||||
tbl[#tbl+1] = "box[7.9,8.8;6,0.4;#800000]"
|
||||
tbl[#tbl+1] = "label[8,8.8;condition false / action out-of-date]"
|
||||
end
|
||||
|
||||
tbl[#tbl+1] = "label[10,8.2; Seconds: "..(meta:get_int("runtime") or 1).."]"
|
||||
|
||||
tbl[#tbl+1] = "label[0,7;"..output("Inputs", "i(", ")", inputs).."]"
|
||||
tbl[#tbl+1] = "label[0,7.6;"..output("Timers", "t", "", timers).."]"
|
||||
tbl[#tbl+1] = "label[0,8.2;"..output("Flags", "f", "", flags).."]"
|
||||
|
||||
tbl[#tbl+1] = "label[0,9;Hint:]"
|
||||
tbl[#tbl+1] = "box[1.3,9;7,0.4;#008000]"
|
||||
tbl[#tbl+1] = "label[1.4,9;condition is true / action was executed]"
|
||||
tbl[#tbl+1] = "box[8.9,9;4,0.4;#800000]"
|
||||
tbl[#tbl+1] = "label[9,9;condition is false]"
|
||||
tbl[#tbl+1] = "box[1.3,9.6;7,0.4;#202020]"
|
||||
tbl[#tbl+1] = "label[1.4,9.6;action was not executed]"
|
||||
|
||||
end
|
||||
|
||||
tbl[#tbl+1] = "button[13.3,8;1.7,1;update;update]"
|
||||
tbl[#tbl+1] = "button[13.3,9;1.7,1;close;close]"
|
||||
tbl[#tbl+1] = "button[13.3,6.9;1.7,1;update;update]"
|
||||
tbl[#tbl+1] = "button[13.3,7.8;1.7,1;close;close]"
|
||||
return table.concat(tbl)
|
||||
end
|
||||
|
||||
local function execute(meta, number, debug)
|
||||
local rt_rules = tubelib.get_data(number, "rt_rules")
|
||||
local inputs = tubelib.get_data(number, "inputs") or {}
|
||||
local act_gate = tubelib.get_data(number, "act_gate") or {}
|
||||
local timers = tubelib.get_data(number, "timers") or {}
|
||||
local flags = tubelib.get_data(number, "flags") or {}
|
||||
local conds = tubelib.get_data(number, "conds") or {}
|
||||
local actions = {}
|
||||
decrement_timers(timers)
|
||||
for i,item in ipairs(rt_rules) do
|
||||
local c1 = eval_cond(item.cond1, flags, timers, inputs, actions)
|
||||
local c2 = eval_cond(item.cond2, flags, timers, inputs, actions)
|
||||
conds[i] = c1 + c2*2
|
||||
if c1 + c2 >= item.cond_cnt then
|
||||
if act_gate[i] == nil then
|
||||
-- execute action
|
||||
exec_action(item.actn, flags, timers, number)
|
||||
actions[i] = true
|
||||
local environ = tubelib.get_data(number, "environ")
|
||||
local act_gate = tubelib.get_data(number, "act_gate")
|
||||
local conds = tubelib.get_data(number, "conds")
|
||||
if rt_rules and environ and act_gate and conds then
|
||||
environ.actions = {}
|
||||
decrement_timers(environ.timers)
|
||||
toggle_flag(environ)
|
||||
for i,item in ipairs(rt_rules) do
|
||||
local c1 = eval_cond(item.cond1, environ)
|
||||
local c2 = eval_cond(item.cond2, environ)
|
||||
conds[i] = c1 + c2*2
|
||||
if c1 + c2 >= item.cond_cnt then
|
||||
if act_gate[i] == nil then
|
||||
-- execute action
|
||||
exec_action(item.actn, environ, number)
|
||||
environ.actions[i] = true
|
||||
act_gate[i] = true
|
||||
end
|
||||
else
|
||||
act_gate[i] = nil
|
||||
end
|
||||
act_gate[i] = true
|
||||
else
|
||||
act_gate[i] = nil
|
||||
end
|
||||
end
|
||||
tubelib.set_data(number, "inputs", inputs)
|
||||
tubelib.set_data(number, "act_gate", act_gate)
|
||||
tubelib.set_data(number, "timers", timers)
|
||||
tubelib.set_data(number, "flags", flags)
|
||||
tubelib.set_data(number, "conds", conds)
|
||||
end
|
||||
|
||||
local function check_rules(pos, elapsed)
|
||||
@ -605,11 +611,14 @@ local function switch_state(pos, state, fs_data)
|
||||
end
|
||||
|
||||
local function start_controller(pos, number, fs_data)
|
||||
tubelib.set_data(number, "timers", {}) -- local timers
|
||||
tubelib.set_data(number, "inputs", {}) -- for rx commands
|
||||
tubelib.set_data(number, "flags", {}) -- to store flags
|
||||
tubelib.set_data(number, "conds", {}) -- to store conditions
|
||||
tubelib.set_data(number, "act_gate", {}) -- for action states
|
||||
-- delete old data
|
||||
tubelib.set_data(number, "environ", {
|
||||
timers = {},
|
||||
flags = {},
|
||||
inputs = {}
|
||||
})
|
||||
tubelib.set_data(number, "conds", {})
|
||||
tubelib.set_data(number, "act_gate", {})
|
||||
switch_state(pos, tubelib.RUNNING, fs_data)
|
||||
end
|
||||
|
||||
@ -854,10 +863,10 @@ minetest.register_craft({
|
||||
local function set_input(meta, payload, val)
|
||||
if payload then
|
||||
local number = meta:get_string("number")
|
||||
local inputs = tubelib.get_data(number, "inputs")
|
||||
if inputs then
|
||||
inputs[payload] = val
|
||||
tubelib.set_data(number, "inputs", inputs)
|
||||
local environ = tubelib.get_data(number, "environ") or {}
|
||||
if environ.inputs then
|
||||
environ.inputs[payload] = val
|
||||
tubelib.set_data(number, "environ", environ)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -908,6 +917,25 @@ local function update_node_database(meta)
|
||||
return tOld2NewCond, tOld2NewActn
|
||||
end
|
||||
|
||||
local function maintain_dataset(number)
|
||||
local flags = tubelib.get_data(number, "flags")
|
||||
if flags ~= nil then
|
||||
local timers = tubelib.get_data(number, "timers") or {}
|
||||
local inputs = tubelib.get_data(number, "inputs") or {}
|
||||
|
||||
tubelib.set_data(number, "environ", {
|
||||
flags = flags,
|
||||
timers = timers,
|
||||
inputs = inputs,
|
||||
vars = {}
|
||||
})
|
||||
|
||||
tubelib.set_data(number, "inputs", nil)
|
||||
tubelib.set_data(number, "timers", nil)
|
||||
tubelib.set_data(number, "flags", nil)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "[SmartLine] Controller update",
|
||||
name = "smartline:update",
|
||||
@ -932,6 +960,8 @@ minetest.register_lbm({
|
||||
local number = meta:get_string("number")
|
||||
local owner = meta:get_string("owner")
|
||||
formspec2runtime_rule(number, owner, fs_data)
|
||||
|
||||
maintain_dataset(number)
|
||||
end
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user