mirror of
https://github.com/joe7575/techpack.git
synced 2024-11-30 02:54:12 +01:00
361 lines
12 KiB
Lua
361 lines
12 KiB
Lua
|
--[[
|
||
|
|
||
|
SmartLine
|
||
|
=========
|
||
|
|
||
|
Part of the SmartLine mod
|
||
|
|
||
|
Copyright (C) 2018 Joachim Stolberg
|
||
|
|
||
|
LGPLv2.1+
|
||
|
See LICENSE.txt for more information
|
||
|
|
||
|
formspec.lua:
|
||
|
|
||
|
controller formspecs
|
||
|
]]--
|
||
|
|
||
|
smartline.NUM_RULES = 8
|
||
|
|
||
|
local SIZE = "size[13,8]"
|
||
|
|
||
|
local sHELP = [[SmartLine Controller Help
|
||
|
|
||
|
Control other nodes by means of rules like:
|
||
|
IF <condition> THEN <action>
|
||
|
|
||
|
These rules allow to execute actions based on conditions.
|
||
|
Examples for conditions are:
|
||
|
- the Player Detector detects a player
|
||
|
- a button is pressed
|
||
|
- a node state is fault, blocked, standby,...
|
||
|
|
||
|
Actions are:
|
||
|
- switch on/off tubelib nodes, like lamps, machines
|
||
|
- send chat messages to the owner
|
||
|
- output a text message to the display
|
||
|
|
||
|
The controller executes all rules cyclically.
|
||
|
The cycle time for each rule is configurable
|
||
|
(1..1000 sec).
|
||
|
0 means, the rule will only be called, when
|
||
|
the controller received a command from
|
||
|
another node, like buttons.
|
||
|
|
||
|
Actions can be deleyed. Therefore, the
|
||
|
after value can be set (0..1000 sec).
|
||
|
|
||
|
Edit command examples:
|
||
|
- 'x 1 8' exchange rows 1 with row 8
|
||
|
- 'c 1 2' copy row 1 to 2
|
||
|
- 'd 3' delete row 3
|
||
|
|
||
|
The 'outp' tab is for debugging outputs via 'print'
|
||
|
The 'notes' tab for your notes.
|
||
|
|
||
|
The controller needs battery power to work.
|
||
|
The battery pack has to be placed near the
|
||
|
controller (1 node distance).
|
||
|
The needed battery power is directly dependent
|
||
|
on the CPU time the controller consumes.
|
||
|
|
||
|
For more information, see: goo.gl/fF5ap6
|
||
|
]]
|
||
|
|
||
|
-- to simplify the search for a pressed main form button (condition/action)
|
||
|
local lButtonKeys = {}
|
||
|
|
||
|
for idx = 1,smartline.NUM_RULES do
|
||
|
lButtonKeys[#lButtonKeys+1] = "cond"..idx
|
||
|
lButtonKeys[#lButtonKeys+1] = "actn"..idx
|
||
|
end
|
||
|
|
||
|
local function buttons(s)
|
||
|
return "button_exit[7.4,7.5;1.8,1;cancel;Cancel]"..
|
||
|
"button[9.3,7.5;1.8,1;save;Save]"..
|
||
|
"button[11.2,7.5;1.8,1;"..s.."]"
|
||
|
end
|
||
|
|
||
|
function smartline.formspecError(meta)
|
||
|
local running = meta:get_int("state") == tubelib.RUNNING
|
||
|
local cmnd = running and "stop;Stop" or "start;Start"
|
||
|
local init = meta:get_string("init")
|
||
|
init = minetest.formspec_escape(init)
|
||
|
return "size[4,3]"..
|
||
|
default.gui_bg..
|
||
|
default.gui_bg_img..
|
||
|
default.gui_slots..
|
||
|
"label[0,0;No Battery?]"..
|
||
|
"button[1,2;1.8,1;start;Start]"
|
||
|
end
|
||
|
|
||
|
local function button(data)
|
||
|
if data then
|
||
|
return data.button
|
||
|
else
|
||
|
return "..."
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function formspec_rules(fs_data)
|
||
|
local tbl = {"field[0,0;0,0;_type_;;main]"..
|
||
|
"label[0.8,0;Cycle/s:]label[2.8,0;IF cond:]label[7,0;THEN action:]label[11.4,0;after/s:]"}
|
||
|
|
||
|
for idx = 1,smartline.NUM_RULES do
|
||
|
local ypos = idx * 0.75 - 0.4
|
||
|
tbl[#tbl+1] = "label[0,"..(0.2+ypos)..";"..idx.."]"
|
||
|
tbl[#tbl+1] = "field[0.9,"..(0.3+ypos)..";1.8,1;cycle"..idx..";;"..(fs_data[idx].cycle or "").."]"
|
||
|
tbl[#tbl+1] = "button[2.5,"..ypos..";4.3,1;cond"..idx..";"..button(fs_data[idx].cond).."]"
|
||
|
tbl[#tbl+1] = "button[6.8,"..ypos..";4.3,1;actn"..idx..";"..button(fs_data[idx].actn).."]"
|
||
|
tbl[#tbl+1] = "field[11.4,"..(0.3+ypos)..";1.8,1;after"..idx..";;"..(fs_data[idx].after or "").."]"
|
||
|
end
|
||
|
return table.concat(tbl)
|
||
|
end
|
||
|
|
||
|
function smartline.store_main_form_data(meta, fields)
|
||
|
local fs_data = minetest.deserialize(meta:get_string("fs_data"))
|
||
|
for idx = 1,smartline.NUM_RULES do
|
||
|
fs_data[idx].cycle = fields["cycle"..idx] or ""
|
||
|
fs_data[idx].after = fields["after"..idx] or "0"
|
||
|
end
|
||
|
meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
end
|
||
|
|
||
|
function smartline.main_form_button_pressed(fields)
|
||
|
for _,key in ipairs(lButtonKeys) do
|
||
|
if fields[key] then
|
||
|
return key
|
||
|
end
|
||
|
end
|
||
|
return nil
|
||
|
end
|
||
|
|
||
|
function smartline.formspecSubMenu(meta, key)
|
||
|
local fs_data = minetest.deserialize(meta:get_string("fs_data"))
|
||
|
if key:sub(1,4) == "cond" then
|
||
|
local row = tonumber(key:sub(5,5))
|
||
|
return smartline.cond_formspec(row, fs_data[row].cond)
|
||
|
else
|
||
|
local row = tonumber(key:sub(5,5))
|
||
|
return smartline.actn_formspec(row, fs_data[row].actn)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function smartline.formspec_button_update(meta, fields)
|
||
|
local fs_data = minetest.deserialize(meta:get_string("fs_data"))
|
||
|
local row = tonumber(fields._row_ or 1)
|
||
|
print("row", row)
|
||
|
if fields._col_ == "cond" then
|
||
|
fs_data[row].cond = smartline.cond_eval_input(fs_data[row].cond, fields)
|
||
|
elseif fields._col_ == "actn" then
|
||
|
fs_data[row].actn = smartline.actn_eval_input(fs_data[row].actn, fields)
|
||
|
end
|
||
|
meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
end
|
||
|
|
||
|
function smartline.cond_formspec_update(meta, fields)
|
||
|
local fs_data = minetest.deserialize(meta:get_string("fs_data"))
|
||
|
local row = tonumber(fields._row_ or 1)
|
||
|
fs_data[row].cond = smartline.cond_eval_input(fs_data[row].cond, fields)
|
||
|
meta:set_string("formspec", smartline.cond_formspec(row, fs_data[row].cond))
|
||
|
meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
end
|
||
|
|
||
|
function smartline.actn_formspec_update(meta, fields)
|
||
|
local fs_data = minetest.deserialize(meta:get_string("fs_data"))
|
||
|
local row = tonumber(fields._row_ or 1)
|
||
|
fs_data[row].actn = smartline.actn_eval_input(fs_data[row].actn, fields)
|
||
|
meta:set_string("formspec", smartline.actn_formspec(row, fs_data[row].actn))
|
||
|
meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
end
|
||
|
|
||
|
|
||
|
function smartline.formspecRules(meta, fs_data, output)
|
||
|
local running = meta:get_int("state") == tubelib.RUNNING
|
||
|
local cmnd = running and "stop;Stop" or "start;Start"
|
||
|
local init = meta:get_string("init")
|
||
|
init = minetest.formspec_escape(init)
|
||
|
return SIZE..
|
||
|
default.gui_bg..
|
||
|
default.gui_bg_img..
|
||
|
default.gui_slots..
|
||
|
"tabheader[0,0;tab;rules,outp,notes,help;1;;true]"..
|
||
|
formspec_rules(fs_data)..
|
||
|
"label[0.2,7.0;"..output.."]"..
|
||
|
"field[0.3,7.8;4,1;cmnd;;<cmnd>]"..
|
||
|
"button[4.0,7.5;1.5,1;go;GO]"..
|
||
|
buttons(cmnd)
|
||
|
end
|
||
|
|
||
|
function smartline.formspecOutput(meta)
|
||
|
local running = meta:get_int("state") == tubelib.RUNNING
|
||
|
local cmnd = running and "stop;Stop" or "start;Start"
|
||
|
local output = meta:get_string("output")
|
||
|
output = minetest.formspec_escape(output)
|
||
|
return SIZE..
|
||
|
default.gui_bg..
|
||
|
default.gui_bg_img..
|
||
|
default.gui_slots..
|
||
|
"tabheader[0,0;tab;rules,outp,notes,help;2;;true]"..
|
||
|
"textarea[0.3,0.2;13,8.3;output;Output:;"..output.."]"..
|
||
|
"button[7.4,7.5;1.8,1;clear;Clear]"..
|
||
|
"button[9.3,7.5;1.8,1;update;Update]"..
|
||
|
"button[11.2,7.5;1.8,1;"..cmnd.."]"
|
||
|
end
|
||
|
|
||
|
function smartline.formspecNotes(meta)
|
||
|
local running = meta:get_int("state") == tubelib.RUNNING
|
||
|
local cmnd = running and "stop;Stop" or "start;Start"
|
||
|
local notes = meta:get_string("notes")
|
||
|
if notes == "" then notes = "<space for your notes>" end
|
||
|
notes = minetest.formspec_escape(notes)
|
||
|
return SIZE..
|
||
|
default.gui_bg..
|
||
|
default.gui_bg_img..
|
||
|
default.gui_slots..
|
||
|
"tabheader[0,0;tab;rules,outp,notes,help;3;;true]"..
|
||
|
"textarea[0.3,0.2;13,8.3;notes;Notepad:;"..notes.."]"..
|
||
|
buttons(cmnd)
|
||
|
end
|
||
|
|
||
|
function smartline.formspecHelp(offs)
|
||
|
return SIZE..
|
||
|
default.gui_bg..
|
||
|
default.gui_bg_img..
|
||
|
default.gui_slots..
|
||
|
"tabheader[0,0;tab;rules,outp,notes,help;4;;true]"..
|
||
|
"field[0,0;0,0;_type_;;help]"..
|
||
|
"label[0,"..(-offs/50)..";"..sHELP.."]"..
|
||
|
--"label[0.2,0;test]"..
|
||
|
"scrollbar[12,1;0.5,7;vertical;sb_help;"..offs.."]"
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
--local function my_on_receive_fields(pos, formname, fields, player)
|
||
|
-- local meta = minetest.get_meta(pos)
|
||
|
-- local owner = meta:get_string("owner")
|
||
|
-- local state = meta:get_int("state")
|
||
|
-- if not player or not player:is_player() then
|
||
|
-- return
|
||
|
-- end
|
||
|
-- local fs_data = minetest.deserialize(meta:get_string("fs_data")) or {}
|
||
|
-- local output = ""
|
||
|
-- local readonly = player:get_player_name() ~= owner
|
||
|
|
||
|
-- print("fields", dump(fields))
|
||
|
|
||
|
-- -- FIRST: test if command entered?
|
||
|
-- if fields.ok then
|
||
|
-- if not readonly then
|
||
|
-- output = edit_command(fs_data, fields.cmnd)
|
||
|
-- smartline.stop_controller(pos, fs_data)
|
||
|
-- meta:set_string("formspec", formspec_main(tubelib.STOPPED, fs_data, output))
|
||
|
-- meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
-- end
|
||
|
-- -- SECOND: eval none edit events (events based in __type__)?
|
||
|
-- elseif fields.help then
|
||
|
-- meta:set_string("formspec", formspec_help(1))
|
||
|
---- elseif fields.state then
|
||
|
---- meta:set_string("formspec", formspec_state(meta, fs_data))
|
||
|
---- elseif fields.update then
|
||
|
---- meta:set_string("formspec", formspec_state(meta, fs_data))
|
||
|
-- elseif fields._cancel_ then
|
||
|
-- fs_data = minetest.deserialize(meta:get_string("fs_old"))
|
||
|
-- meta:set_string("formspec", formspec_main(state, fs_data, sOUTPUT))
|
||
|
-- elseif fields.close then
|
||
|
-- meta:set_string("formspec", formspec_main(state, fs_data, sOUTPUT))
|
||
|
---- elseif fields.sb_help then
|
||
|
---- local evt = minetest.explode_scrollbar_event(fields.sb_help)
|
||
|
---- if evt.type == "CHG" then
|
||
|
---- meta:set_string("formspec", formspec_help(evt.value))
|
||
|
---- end
|
||
|
---- elseif fields.button then
|
||
|
---- if not readonly then
|
||
|
---- local number = meta:get_string("number")
|
||
|
---- local state = meta:get_int("state")
|
||
|
---- if state == tubelib.RUNNING then
|
||
|
---- smartline.stop_controller(pos, fs_data)
|
||
|
---- meta:set_string("formspec", formspec_main(tubelib.STOPPED, fs_data, sOUTPUT))
|
||
|
---- else
|
||
|
---- formspec2runtime_rule(number, owner, fs_data)
|
||
|
---- start_controller(pos, number, fs_data)
|
||
|
---- meta:set_string("formspec", formspec_main(tubelib.RUNNING, fs_data, sOUTPUT))
|
||
|
---- end
|
||
|
---- end
|
||
|
---- -- THIRD: evaluate edit events from sub-menus
|
||
|
-- elseif fields._col_ == "cond" then
|
||
|
-- local row = tonumber(fields._row_ or 1)
|
||
|
-- fs_data["cond"..row] = smartline.cond_eval_input(fs_data["cond"..row], fields)
|
||
|
-- meta:set_string("formspec", smartline.cond_formspec(row, fs_data["cond"..row]))
|
||
|
-- meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
-- elseif fields._type_ == "main" then
|
||
|
-- fs_data = eval_formspec_main(meta, fs_data, fields, readonly)
|
||
|
-- meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
---- elseif fields._type_ == "label" then
|
||
|
---- fs_data = eval_formspec_label(meta, fs_data, fields, readonly)
|
||
|
---- meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
---- elseif fields._type_ == "cond" then
|
||
|
---- fs_data = eval_formspec_cond(meta, fs_data, fields, readonly)
|
||
|
---- meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
---- elseif fields._type_ == "oprnd" then
|
||
|
---- fs_data = eval_formspec_oprnd(meta, fs_data, fields, readonly)
|
||
|
---- meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
---- elseif fields._type_ == "actn" then
|
||
|
---- fs_data = eval_formspec_actn(meta, fs_data, fields, readonly)
|
||
|
---- meta:set_string("fs_data", minetest.serialize(fs_data))
|
||
|
---- elseif fields._type_ == "help" then
|
||
|
---- meta:set_string("formspec", formspec_main(state, fs_data, sOUTPUT))
|
||
|
---- elseif fields._type_ == "state" then
|
||
|
---- meta:set_string("formspec", formspec_main(state, fs_data, sOUTPUT))
|
||
|
-- end
|
||
|
-- -- FOURTH: back to main menu
|
||
|
-- if fields._exit_ then
|
||
|
-- meta:set_string("formspec", formspec_main(state, fs_data, sOUTPUT))
|
||
|
-- end
|
||
|
--end
|
||
|
|
||
|
--function smartline.on_receive_fields(pos, formname, fields, player)
|
||
|
-- local meta = minetest.get_meta(pos)
|
||
|
-- local owner = meta:get_string("owner")
|
||
|
-- if not player or not player:is_player() then
|
||
|
-- return
|
||
|
-- end
|
||
|
-- local readonly = player:get_player_name() ~= owner
|
||
|
|
||
|
-- print("fields", dump(fields))
|
||
|
|
||
|
-- if fields.cancel == nil then
|
||
|
-- if fields.rules then
|
||
|
-- --meta:set_string("rules", fields.rules)
|
||
|
-- meta:set_string("formspec", smartline.formspecRules(meta))
|
||
|
-- elseif fields.notes then
|
||
|
-- meta:set_string("notes", fields.notes)
|
||
|
-- meta:set_string("formspec", formspecNotes(meta))
|
||
|
-- end
|
||
|
-- end
|
||
|
|
||
|
-- if fields.update then
|
||
|
-- meta:set_string("formspec", formspecOutput(meta))
|
||
|
-- elseif fields.clear then
|
||
|
-- meta:set_string("output", "<press update>")
|
||
|
-- meta:set_string("formspec", formspecOutput(meta))
|
||
|
-- elseif fields.tab == "1" then
|
||
|
-- meta:set_string("formspec", smartline.formspecRules(meta))
|
||
|
-- elseif fields.tab == "2" then
|
||
|
-- meta:set_string("formspec", formspecOutput(meta))
|
||
|
-- elseif fields.tab == "3" then
|
||
|
-- meta:set_string("formspec", formspecNotes(meta))
|
||
|
-- elseif fields.tab == "4" then
|
||
|
-- meta:set_string("formspec", formspecHelp(1))
|
||
|
-- elseif fields.start == "Start" then
|
||
|
-- start_controller(pos)
|
||
|
-- minetest.log("action", player:get_player_name() ..
|
||
|
-- " starts the sl_controller at ".. minetest.pos_to_string(pos))
|
||
|
-- elseif fields.stop == "Stop" then
|
||
|
-- stop_controller(pos)
|
||
|
-- end
|
||
|
--end
|
||
|
|
||
|
|