luacontroller added
This commit is contained in:
parent
f20a3952ab
commit
7e752815ef
1
init.lua
1
init.lua
@ -227,6 +227,7 @@ else
|
||||
-- dofile(MP.."/lua_controller/controller.lua")
|
||||
-- dofile(MP.."/lua_controller/commands.lua")
|
||||
-- dofile(MP.."/lua_controller/server.lua")
|
||||
-- dofile(MP.."/lua_controller/sensorchest.lua")
|
||||
|
||||
-- Items
|
||||
dofile(MP.."/items/barrel.lua")
|
||||
|
235
lua_controller/commands.lua
Normal file
235
lua_controller/commands.lua
Normal file
@ -0,0 +1,235 @@
|
||||
--[[
|
||||
|
||||
sl_controller
|
||||
=============
|
||||
|
||||
Copyright (C) 2018 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
commands.lua:
|
||||
|
||||
Register all basic controller commands
|
||||
|
||||
]]--
|
||||
|
||||
-- store protection data locally
|
||||
local LocalRef = {}
|
||||
local function not_protected(owner, numbers)
|
||||
LocalRef[owner] = LocalRef[owner] or {}
|
||||
if LocalRef[owner][numbers] == nil then
|
||||
LocalRef[owner][numbers] = techage.check_numbers(numbers, owner)
|
||||
end
|
||||
return LocalRef[owner][numbers]
|
||||
end
|
||||
|
||||
techage.lua_ctlr.register_function("get_input", {
|
||||
cmnd = function(self, num)
|
||||
num = tostring(num or "")
|
||||
return techage.lua_ctlr.get_input(self.meta.number, num)
|
||||
end,
|
||||
help = ' $get_input(num) --> "on", "off", or nil\n'..
|
||||
' Read local input value from device with number "num".\n'..
|
||||
' example: inp = $get_input("1234")\n'..
|
||||
" The device has to be connected with the controller."
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_function("get_status", {
|
||||
cmnd = function(self, num)
|
||||
num = tostring(num or "")
|
||||
return techage.send_single(self.meta.number, num, "state", nil)
|
||||
end,
|
||||
help = " $get_status(num) ,\n"..
|
||||
" Read status string from a remote device.\n"..
|
||||
' example: sts = $get_status("1234")'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_function("get_player_action", {
|
||||
cmnd = function(self, num)
|
||||
num = tostring(num or "")
|
||||
return unpack(techage.send_single(self.meta.number, num, "player_action", nil) or {"","",""})
|
||||
end,
|
||||
help = " $get_player_action(num) ,\n"..
|
||||
" Read player action status from a Sensor Chest.\n"..
|
||||
' example: player, action, item = $get_player_action("1234")'
|
||||
})
|
||||
|
||||
--techage.lua_ctlr.register_function("get_counter", {
|
||||
-- cmnd = function(self, num)
|
||||
-- num = tostring(num or "")
|
||||
-- return techage.send_single(self.meta.number, num, "counter", nil)
|
||||
-- end,
|
||||
-- help = " $get_counter(num)\n"..
|
||||
-- " Read number of pushed items from a\n"..
|
||||
-- " Pusher/Distributor node.\n"..
|
||||
-- " The Pusher returns a single value (number)\n"..
|
||||
-- " The Distributor returns a list with 4 values\n"..
|
||||
-- " like: {red=1, green=0, blue=8, yellow=0}\n"..
|
||||
-- ' example: cnt = $get_counter("1234")\n'
|
||||
--})
|
||||
|
||||
--techage.lua_ctlr.register_function("clear_counter", {
|
||||
-- cmnd = function(self, num)
|
||||
-- num = tostring(num or "")
|
||||
-- return techage.send_single(self.meta.number, num, "clear_counter", nil)
|
||||
-- end,
|
||||
-- help = " $clear_counter(num)\n"..
|
||||
-- " Set counter(s) from Pusher/Distributor to zero.\n"..
|
||||
-- ' example: $clear_counter("1234")'
|
||||
--})
|
||||
|
||||
techage.lua_ctlr.register_function("get_fuel_value", {
|
||||
cmnd = function(self, num)
|
||||
num = tostring(num or "")
|
||||
return techage.send_single(self.meta.number, num, "fuel", nil)
|
||||
end,
|
||||
help = " $get_fuel_value(num)\n"..
|
||||
" Read fuel value from fuel consuming blocks.\n"..
|
||||
' example: val = $get_fuel_value("1234")'
|
||||
})
|
||||
|
||||
--techage.lua_ctlr.register_function("get_num_items", {
|
||||
-- cmnd = function(self, num, idx)
|
||||
-- num = tostring(num or "")
|
||||
-- idx = tonumber(idx)
|
||||
-- return techage.send_single(self.meta.number, num, "num_items", idx)
|
||||
-- end,
|
||||
-- help = " $get_num_items(num)\n"..
|
||||
-- " Read number of stored items in one\n"..
|
||||
-- " storage (1..8) from a Warehouse Box.\n"..
|
||||
-- ' example: cnt = $get_num_items("1234", 4)\n'
|
||||
--})
|
||||
|
||||
techage.lua_ctlr.register_function("time_as_str", {
|
||||
cmnd = function(self)
|
||||
local t = minetest.get_timeofday()
|
||||
local h = math.floor(t*24) % 24
|
||||
local m = math.floor(t*1440) % 60
|
||||
return string.format("%02d:%02d", h, m)
|
||||
end,
|
||||
help = " $time_as_str() --> e.g. '18:45'\n"..
|
||||
" Read time of day as string (24h).\n"..
|
||||
' example: time = $time_as_str()'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_function("time_as_num", {
|
||||
cmnd = function(self, num)
|
||||
local t = minetest.get_timeofday()
|
||||
local h = math.floor(t*24) % 24
|
||||
local m = math.floor(t*1440) % 60
|
||||
return h * 100 + m
|
||||
end,
|
||||
help = " $time_as_num() --> e.g.: 1845\n"..
|
||||
" Read time of day as number (24h).\n"..
|
||||
' example: time = $time_as_num()'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_function("playerdetector", {
|
||||
cmnd = function(self, num)
|
||||
num = tostring(num or "")
|
||||
if not_protected(self.meta.owner, num) then
|
||||
return techage.send_single(self.meta.number, num, "name", nil)
|
||||
end
|
||||
end,
|
||||
help = ' $playerdetector(num) --> e.g. "Joe"\n'..
|
||||
' "" is returned if no player is nearby.\n'..
|
||||
' example: name = $playerdetector("1234")'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_action("send_cmnd", {
|
||||
cmnd = function(self, num, text)
|
||||
num = tostring(num or "")
|
||||
text = tostring(text or "")
|
||||
if not_protected(self.meta.owner, num) then
|
||||
techage.send_single(self.meta.number, num, text, nil)
|
||||
end
|
||||
end,
|
||||
help = " $send_cmnd(num, text)\n"..
|
||||
' Send a command to the device with number "num".\n'..
|
||||
' example: $send_cmnd("1234", "on")'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_action("set_filter", {
|
||||
cmnd = function(self, num, slot, val)
|
||||
num = tostring(num or "")
|
||||
slot = tostring(slot or "red")
|
||||
val = tostring(val or "on")
|
||||
if not_protected(self.meta.owner, num) then
|
||||
techage.send_single(self.meta.number, num, "filter", {slot=slot, val=val})
|
||||
end
|
||||
end,
|
||||
help = " $set_filter(num, slot, val)\n"..
|
||||
' Turn on/off a Distributor filter slot.\n'..
|
||||
' example: $set_filter("1234", "red", "off")'
|
||||
})
|
||||
|
||||
|
||||
techage.lua_ctlr.register_action("display", {
|
||||
cmnd = function(self, num, row, text1, text2, text3)
|
||||
num = tostring(num or "")
|
||||
text1 = tostring(text1 or "")
|
||||
text2 = tostring(text2 or "")
|
||||
text3 = tostring(text3 or "")
|
||||
if not_protected(self.meta.owner, num) then
|
||||
techage.send_single(self.meta.number, num, "set", {row = row, str = text1..text2..text3})
|
||||
end
|
||||
end,
|
||||
help = " $display(num, row, text,...)\n"..
|
||||
' Send a text line to the display with number "num".\n'..
|
||||
" 'row' is a value from 1..5\n"..
|
||||
" The function accepts up to 3 text parameters\n"..
|
||||
' example: $display("0123", 1, "Hello ", name, " !")'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_action("clear_screen", {
|
||||
cmnd = function(self, num)
|
||||
num = tostring(num or "")
|
||||
if not_protected(self.meta.owner, num) then
|
||||
techage.send_single(self.meta.number, num, "clear", nil)
|
||||
end
|
||||
end,
|
||||
help = " $clear_screen(num)\n"..
|
||||
' Clear the screen of the display\n'..
|
||||
' with number "num".\n'..
|
||||
' example: $clear_screen("1234")'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_action("chat", {
|
||||
cmnd = function(self, text1, text2, text3)
|
||||
text1 = tostring(text1 or "")
|
||||
text2 = tostring(text2 or "")
|
||||
text3 = tostring(text3 or "")
|
||||
minetest.chat_send_player(self.meta.owner, "[TA4 Lua Controller] "..text1..text2..text3)
|
||||
end,
|
||||
help = " $chat(text,...)\n"..
|
||||
" Send yourself a chat message.\n"..
|
||||
" The function accepts up to 3 text parameters\n"..
|
||||
' example: $chat("Hello ", name)'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_action("door", {
|
||||
cmnd = function(self, pos, text)
|
||||
pos = tostring(pos or "")
|
||||
text = tostring(text or "")
|
||||
pos = minetest.string_to_pos("("..pos..")")
|
||||
if pos then
|
||||
local door = doors.get(pos)
|
||||
if door then
|
||||
local player = {
|
||||
get_player_name = function() return self.meta.owner end,
|
||||
is_player = function() return true end,
|
||||
}
|
||||
if text == "open" then
|
||||
door:open(player)
|
||||
elseif text == "close" then
|
||||
door:close(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
help = " $door(pos, text)\n"..
|
||||
' Open/Close a door at position "pos"\n'..
|
||||
' example: $door("123,7,-1200", "close")\n'..
|
||||
" Hint: Use the Techage Programmer to\ndetermine the door position."
|
||||
})
|
617
lua_controller/controller.lua
Normal file
617
lua_controller/controller.lua
Normal file
@ -0,0 +1,617 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Lua Controller
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local M = minetest.get_meta
|
||||
|
||||
local sHELP = [[TA4 Lua Controller
|
||||
|
||||
This controller is used to control and monitor
|
||||
TechAge machines.
|
||||
This controller can be programmed in Lua.
|
||||
|
||||
See on GitHub for more help: goo.gl/Et8D6n
|
||||
|
||||
The controller only runs, if a battery is
|
||||
placed nearby.
|
||||
|
||||
]]
|
||||
|
||||
techage.lua_ctlr = {}
|
||||
|
||||
local BATTERY_CAPA = 5000000
|
||||
|
||||
local Cache = {}
|
||||
|
||||
local STATE_STOPPED = 0
|
||||
local STATE_RUNNING = 1
|
||||
|
||||
local tCommands = {}
|
||||
local tFunctions = {" Overview", " Data structures"}
|
||||
local tHelpTexts = {[" Overview"] = sHELP, [" Data structures"] = safer_lua.DataStructHelp}
|
||||
local sFunctionList = ""
|
||||
local tFunctionIndex = {}
|
||||
|
||||
minetest.after(2, function()
|
||||
sFunctionList = table.concat(tFunctions, ",")
|
||||
for idx,key in ipairs(tFunctions) do
|
||||
tFunctionIndex[key] = idx
|
||||
end
|
||||
end)
|
||||
|
||||
local function output(pos, text)
|
||||
local meta = minetest.get_meta(pos)
|
||||
text = meta:get_string("output") .. "\n" .. (text or "")
|
||||
text = text:sub(-500,-1)
|
||||
meta:set_string("output", text)
|
||||
end
|
||||
|
||||
--
|
||||
-- API functions for function/action registrations
|
||||
--
|
||||
function techage.lua_ctlr.register_function(key, attr)
|
||||
tCommands[key] = attr.cmnd
|
||||
table.insert(tFunctions, " $"..key)
|
||||
tHelpTexts[" $"..key] = attr.help
|
||||
end
|
||||
|
||||
function techage.lua_ctlr.register_action(key, attr)
|
||||
tCommands[key] = attr.cmnd
|
||||
table.insert(tFunctions, " $"..key)
|
||||
tHelpTexts[" $"..key] = attr.help
|
||||
end
|
||||
|
||||
local function merge(dest, keys, values)
|
||||
for idx,key in ipairs(keys) do
|
||||
dest.env[key] = values[idx]
|
||||
end
|
||||
return dest
|
||||
end
|
||||
|
||||
techage.lua_ctlr.register_action("print", {
|
||||
cmnd = function(self, text1, text2, text3)
|
||||
local pos = self.meta.pos
|
||||
text1 = tostring(text1 or "")
|
||||
text2 = tostring(text2 or "")
|
||||
text3 = tostring(text3 or "")
|
||||
output(pos, text1..text2..text3)
|
||||
end,
|
||||
help = " $print(text,...)\n"..
|
||||
" Send a text line to the output window.\n"..
|
||||
" The function accepts up to 3 text strings\n"..
|
||||
' e.g. $print("Hello ", name, " !")'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_action("loopcycle", {
|
||||
cmnd = function(self, cycletime)
|
||||
cycletime = math.floor(tonumber(cycletime) or 0)
|
||||
local meta = minetest.get_meta(self.meta.pos)
|
||||
meta:set_int("cycletime", cycletime)
|
||||
meta:set_int("cyclecount", 0)
|
||||
end,
|
||||
help = "$loopcycle(seconds)\n"..
|
||||
" This function allows to change the\n"..
|
||||
" call frequency of the loop() function.\n"..
|
||||
" value is in seconds, 0 = disable\n"..
|
||||
' e.g. $loopcycle(10)'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_action("events", {
|
||||
cmnd = function(self, event)
|
||||
self.meta.events = event or false
|
||||
end,
|
||||
help = "$events(true/false)\n"..
|
||||
" Enable/disable event handling.\n"..
|
||||
' e.g. $events(true) -- enable events'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_function("get_ms_time", {
|
||||
cmnd = function(self)
|
||||
return math.floor(minetest.get_us_time() / 1000)
|
||||
end,
|
||||
help = "$get_ms_time()\n"..
|
||||
" returns time with millisecond precision."
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_function("position", {
|
||||
cmnd = function(self, number)
|
||||
local info = techage.get_node_info(number)
|
||||
if info then
|
||||
return S(info.pos)
|
||||
end
|
||||
return "(-,-,-)"
|
||||
end,
|
||||
help = "$position(number)\n"..
|
||||
" returns the position '(x,y,z)' of the device\n with given number."
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_action("battery", {
|
||||
cmnd = function(self)
|
||||
local meta = minetest.get_meta(self.meta.pos)
|
||||
local batpos = minetest.string_to_pos(meta:get_string("battery"))
|
||||
local batmeta = minetest.get_meta(batpos)
|
||||
local val = (BATTERY_CAPA - math.min(batmeta:get_int("content") or 0, BATTERY_CAPA))
|
||||
return 100 - math.floor((val * 100.0 / BATTERY_CAPA))
|
||||
end,
|
||||
help = " $battery()\n"..
|
||||
" Get charge level of battery connected to Controller.\n"..
|
||||
" Function returns percent number (0-100) where 100 means full.\n"..
|
||||
" example: battery_percent = $battery()"
|
||||
})
|
||||
|
||||
|
||||
local function formspec0(meta)
|
||||
local state = meta:get_int("state") == techage.RUNNING
|
||||
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 formspec1(meta)
|
||||
local state = meta:get_int("state") == techage.RUNNING
|
||||
local cmnd = state and "stop;Stop" or "start;Start"
|
||||
local init = meta:get_string("init")
|
||||
init = minetest.formspec_escape(init)
|
||||
return "size[10,8]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"tabheader[0,0;tab;init,func,loop,outp,notes,help;1;;true]"..
|
||||
"textarea[0.3,0.2;10,8.3;init;function init();"..init.."]"..
|
||||
"label[0,7.3;end]"..
|
||||
"button_exit[4.4,7.5;1.8,1;cancel;Cancel]"..
|
||||
"button[6.3,7.5;1.8,1;save;Save]"..
|
||||
"button[8.2,7.5;1.8,1;"..cmnd.."]"
|
||||
end
|
||||
|
||||
local function formspec2(meta)
|
||||
local state = meta:get_int("state") == techage.RUNNING
|
||||
local cmnd = state and "stop;Stop" or "start;Start"
|
||||
local func = meta:get_string("func")
|
||||
func = minetest.formspec_escape(func)
|
||||
return "size[10,8]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"tabheader[0,0;tab;init,func,loop,outp,notes,help;2;;true]"..
|
||||
"textarea[0.3,0.2;10,8.3;func;functions:;"..func.."]"..
|
||||
"button_exit[4.4,7.5;1.8,1;cancel;Cancel]"..
|
||||
"button[6.3,7.5;1.8,1;save;Save]"..
|
||||
"button[8.2,7.5;1.8,1;"..cmnd.."]"
|
||||
end
|
||||
|
||||
local function formspec3(meta)
|
||||
local state = meta:get_int("state") == techage.RUNNING
|
||||
local cmnd = state and "stop;Stop" or "start;Start"
|
||||
local loop = meta:get_string("loop")
|
||||
loop = minetest.formspec_escape(loop)
|
||||
return "size[10,8]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"tabheader[0,0;tab;init,func,loop,outp,notes,help;3;;true]"..
|
||||
"textarea[0.3,0.2;10,8.3;loop;function loop(ticks, elapsed);"..loop.."]"..
|
||||
"label[0,7.3;end]"..
|
||||
"button_exit[4.4,7.5;1.8,1;cancel;Cancel]"..
|
||||
"button[6.3,7.5;1.8,1;save;Save]"..
|
||||
"button[8.2,7.5;1.8,1;"..cmnd.."]"
|
||||
end
|
||||
|
||||
local function formspec4(meta)
|
||||
local state = meta:get_int("state") == techage.RUNNING
|
||||
local cmnd = state and "stop;Stop" or "start;Start"
|
||||
local output = meta:get_string("output")
|
||||
output = minetest.formspec_escape(output)
|
||||
output = output:gsub("\n", ",")
|
||||
return "size[10,8]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"tabheader[0,0;tab;init,func,loop,outp,notes,help;4;;true]"..
|
||||
"table[0.2,0.2;9.5,7;output;"..output..";200]"..
|
||||
"button[4.4,7.5;1.8,1;clear;Clear]"..
|
||||
"button[6.3,7.5;1.8,1;update;Update]"..
|
||||
"button[8.2,7.5;1.8,1;"..cmnd.."]"
|
||||
end
|
||||
|
||||
local function formspec5(meta)
|
||||
local notes = meta:get_string("notes")
|
||||
notes = minetest.formspec_escape(notes)
|
||||
return "size[10,8]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"tabheader[0,0;tab;init,func,loop,outp,notes,help;5;;true]"..
|
||||
"textarea[0.3,0.2;10,8.3;notes;Notepad:;"..notes.."]"..
|
||||
"button_exit[6.3,7.5;1.8,1;cancel;Cancel]"..
|
||||
"button[8.2,7.5;1.8,1;save;Save]"
|
||||
end
|
||||
|
||||
local function formspec6(items, pos, text)
|
||||
text = minetest.formspec_escape(text)
|
||||
return "size[10,8]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"tabheader[0,0;tab;init,func,loop,outp,notes,help;6;;true]"..
|
||||
"label[0,-0.2;Functions:]"..
|
||||
"dropdown[0.3,0.2;10,8.3;functions;"..items..";"..pos.."]"..
|
||||
"textarea[0.3,1.3;10,8;help;Help:;"..text.."]"
|
||||
end
|
||||
|
||||
local function patch_error_string(err, line_offs)
|
||||
local tbl = {}
|
||||
for s in err:gmatch("[^\r\n]+") do
|
||||
if s:find("loop:(%d+):") then
|
||||
local prefix, line, err = s:match("(.-)loop:(%d+):(.+)")
|
||||
if prefix and line and err then
|
||||
if tonumber(line) < line_offs then
|
||||
table.insert(tbl, prefix.."func:"..line..":"..err)
|
||||
else
|
||||
line = tonumber(line) - line_offs
|
||||
table.insert(tbl, prefix.."loop:"..line..":"..err)
|
||||
end
|
||||
end
|
||||
else
|
||||
table.insert(tbl, s)
|
||||
end
|
||||
end
|
||||
return table.concat(tbl, "\n")
|
||||
end
|
||||
|
||||
local function error(pos, err)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local func = meta:get_string("func")
|
||||
local _,line_offs = string.gsub(func, "\n", "\n")
|
||||
line_offs = line_offs + 1
|
||||
err = patch_error_string(err, line_offs)
|
||||
output(pos, err)
|
||||
local number = meta:get_string("number")
|
||||
meta:set_string("infotext", "Controller "..number..": error")
|
||||
meta:set_int("state", techage.STOPPED)
|
||||
meta:set_int("running", STATE_STOPPED)
|
||||
meta:set_string("formspec", formspec4(meta))
|
||||
minetest.get_node_timer(pos):stop()
|
||||
return false
|
||||
end
|
||||
|
||||
local function compile(pos, meta, number)
|
||||
local init = meta:get_string("init")
|
||||
local func = meta:get_string("func")
|
||||
local loop = meta:get_string("loop")
|
||||
local owner = meta:get_string("owner")
|
||||
local env = table.copy(tCommands)
|
||||
env.meta = {pos=pos, owner=owner, number=number, error=error}
|
||||
local code = safer_lua.init(pos, init, func.."\n"..loop, env, error)
|
||||
|
||||
if code then
|
||||
Cache[number] = {code=code, inputs={}, events=env.meta.events}
|
||||
Cache[number].inputs.term = nil -- terminal inputs
|
||||
Cache[number].inputs.msg = {} -- message queue
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function battery(pos)
|
||||
local battery_pos = minetest.find_node_near(pos, 1, {"techage:ta4_battery"})
|
||||
if battery_pos then
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("battery", minetest.pos_to_string(battery_pos))
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function start_controller(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = meta:get_string("number")
|
||||
if not battery(pos) then
|
||||
meta:set_string("formspec", formspec0(meta))
|
||||
return false
|
||||
end
|
||||
|
||||
meta:set_string("output", "<press update>")
|
||||
meta:set_int("cycletime", 1)
|
||||
meta:set_int("cyclecount", 0)
|
||||
meta:set_int("cpu", 0)
|
||||
|
||||
if compile(pos, meta, number) then
|
||||
meta:set_int("state", techage.RUNNING)
|
||||
meta:set_int("running", STATE_RUNNING)
|
||||
minetest.get_node_timer(pos):start(1)
|
||||
meta:set_string("formspec", formspec4(meta))
|
||||
meta:set_string("infotext", "Controller "..number..": running")
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function stop_controller(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = meta:get_string("number")
|
||||
meta:set_int("state", techage.STOPPED)
|
||||
meta:set_int("running", STATE_STOPPED)
|
||||
minetest.get_node_timer(pos):stop()
|
||||
meta:set_string("infotext", "Controller "..number..": stopped")
|
||||
meta:set_string("formspec", formspec3(meta))
|
||||
end
|
||||
|
||||
local function no_battery(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = meta:get_string("number")
|
||||
meta:set_int("state", techage.STOPPED)
|
||||
meta:set_int("running", STATE_STOPPED)
|
||||
minetest.get_node_timer(pos):stop()
|
||||
meta:set_string("infotext", "Controller "..number..": No battery")
|
||||
meta:set_string("formspec", formspec0(meta))
|
||||
end
|
||||
|
||||
local function update_battery(meta, cpu)
|
||||
local pos = minetest.string_to_pos(meta:get_string("battery"))
|
||||
if pos then
|
||||
meta = minetest.get_meta(pos)
|
||||
local content = meta:get_int("content") - cpu
|
||||
if content <= 0 then
|
||||
meta:set_int("content", 0)
|
||||
return false
|
||||
end
|
||||
meta:set_int("content", content)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function call_loop(pos, meta, elapsed)
|
||||
local t = minetest.get_us_time()
|
||||
local number = meta:get_string("number")
|
||||
if Cache[number] or compile(pos, meta, number) then
|
||||
local cpu = meta:get_int("cpu") or 0
|
||||
local code = Cache[number].code
|
||||
local res = safer_lua.run_loop(pos, elapsed, code, error)
|
||||
if res then
|
||||
t = minetest.get_us_time() - t
|
||||
cpu = math.floor(((cpu * 20) + t) / 21)
|
||||
meta:set_int("cpu", cpu)
|
||||
meta:set_string("infotext", "Controller "..number..": running ("..cpu.."us)")
|
||||
if not update_battery(meta, cpu) then
|
||||
no_battery(pos)
|
||||
return false
|
||||
end
|
||||
end
|
||||
-- further messages available?
|
||||
if next(Cache[number].inputs["msg"]) then
|
||||
minetest.after(1, call_loop, pos, meta, -1)
|
||||
end
|
||||
return res
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function on_timer(pos, elapsed)
|
||||
local meta = minetest.get_meta(pos)
|
||||
-- considering cycle frequency
|
||||
local cycletime = meta:get_int("cycletime") or 1
|
||||
local cyclecount = (meta:get_int("cyclecount") or 0) + 1
|
||||
if cycletime == 0 or cyclecount < cycletime then
|
||||
meta:set_int("cyclecount", cyclecount)
|
||||
return true
|
||||
end
|
||||
meta:set_int("cyclecount", 0)
|
||||
|
||||
return call_loop(pos, meta, elapsed)
|
||||
end
|
||||
|
||||
local function on_receive_fields(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
--print(dump(fields))
|
||||
if fields.cancel == nil then
|
||||
if fields.init then
|
||||
meta:set_string("init", fields.init)
|
||||
meta:set_string("formspec", formspec1(meta))
|
||||
elseif fields.func then
|
||||
meta:set_string("func", fields.func)
|
||||
meta:set_string("formspec", formspec2(meta))
|
||||
elseif fields.loop then
|
||||
meta:set_string("loop", fields.loop)
|
||||
meta:set_string("formspec", formspec3(meta))
|
||||
elseif fields.notes then
|
||||
meta:set_string("notes", fields.notes)
|
||||
meta:set_string("formspec", formspec5(meta))
|
||||
end
|
||||
end
|
||||
|
||||
if fields.update then
|
||||
meta:set_string("formspec", formspec4(meta))
|
||||
elseif fields.clear then
|
||||
meta:set_string("output", "<press update>")
|
||||
meta:set_string("formspec", formspec4(meta))
|
||||
elseif fields.tab == "1" then
|
||||
meta:set_string("formspec", formspec1(meta))
|
||||
elseif fields.tab == "2" then
|
||||
meta:set_string("formspec", formspec2(meta))
|
||||
elseif fields.tab == "3" then
|
||||
meta:set_string("formspec", formspec3(meta))
|
||||
elseif fields.tab == "4" then
|
||||
meta:set_string("formspec", formspec4(meta))
|
||||
elseif fields.tab == "5" then
|
||||
meta:set_string("formspec", formspec5(meta))
|
||||
elseif fields.tab == "6" then
|
||||
meta:set_string("formspec", formspec6(sFunctionList, 1, sHELP))
|
||||
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)
|
||||
elseif fields.functions then
|
||||
local key = fields.functions
|
||||
local text = tHelpTexts[key] or ""
|
||||
local pos = tFunctionIndex[key] or 1
|
||||
meta:set_string("formspec", formspec6(sFunctionList, pos, text))
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("techage:ta4_lua_controller", {
|
||||
description = "TA4 Lua Controller",
|
||||
inventory_image = "techage_lua_controller_inventory.png",
|
||||
wield_image = "techage_lua_controller_inventory.png",
|
||||
stack_max = 1,
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_smartline.png",
|
||||
"techage_smartline.png",
|
||||
"techage_smartline.png",
|
||||
"techage_smartline.png",
|
||||
"techage_smartline.png",
|
||||
"techage_smartline.png^techage_lua_controller.png",
|
||||
},
|
||||
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -6/32, -6/32, 14/32, 6/32, 6/32, 16/32},
|
||||
},
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = techage.add_node(pos, "techage:ta4_lua_controller")
|
||||
meta:set_string("owner", placer:get_player_name())
|
||||
meta:set_string("number", number)
|
||||
meta:set_int("state", techage.STOPPED)
|
||||
meta:set_int("running", STATE_STOPPED)
|
||||
meta:set_string("init", "-- called only once")
|
||||
meta:set_string("func", "-- for your functions")
|
||||
meta:set_string("loop", "-- called every second")
|
||||
meta:set_string("notes", "For your notes / snippets")
|
||||
meta:mark_as_private("init")
|
||||
meta:mark_as_private("func")
|
||||
meta:mark_as_private("loop")
|
||||
meta:mark_as_private("notes")
|
||||
meta:set_string("formspec", formspec1(meta))
|
||||
meta:set_string("infotext", "Controller "..number..": stopped")
|
||||
end,
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
|
||||
on_dig = function(pos, node, puncher, pointed_thing)
|
||||
if minetest.is_protected(pos, puncher:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
minetest.node_dig(pos, node, puncher, pointed_thing)
|
||||
techage.remove_node(pos)
|
||||
end,
|
||||
|
||||
on_timer = on_timer,
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=1, cracky=1, crumbly=1},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta4_lua_controller",
|
||||
recipe = {
|
||||
{"basic_materials:plastic_sheet", "dye:blue", "basic_materials:plastic_sheet"},
|
||||
{"", "default:copper_ingot", ""},
|
||||
{"techage:ta4_ramchip", "techage:ta4_wlanchip", "techage:ta4_ramchip"},
|
||||
},
|
||||
})
|
||||
|
||||
-- write inputs from remote nodes
|
||||
local function set_input(pos, number, input, val)
|
||||
if input and M(pos):get_int("state") == techage.RUNNING then
|
||||
if (Cache[number] or compile(pos, M(pos), number)) and Cache[number].inputs then
|
||||
if input == "msg" then
|
||||
if #Cache[number].inputs["msg"] < 10 then
|
||||
table.insert(Cache[number].inputs["msg"], val)
|
||||
end
|
||||
else
|
||||
Cache[number].inputs[input] = val
|
||||
end
|
||||
if Cache[number].events then -- events enabled?
|
||||
local t = minetest.get_us_time()
|
||||
if not Cache[number].last_event or Cache[number].last_event < t then
|
||||
local meta = minetest.get_meta(pos)
|
||||
minetest.after(0.01, call_loop, pos, meta, -1)
|
||||
Cache[number].last_event = t + 100000 -- add 100 ms
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- used by the command "input"
|
||||
function techage.lua_ctlr.get_input(number, input)
|
||||
if input then
|
||||
if Cache[number] and Cache[number].inputs then
|
||||
return Cache[number].inputs[input] or "off"
|
||||
end
|
||||
end
|
||||
return "off"
|
||||
end
|
||||
|
||||
-- used for Terminal commands
|
||||
function techage.lua_ctlr.get_command(number)
|
||||
if Cache[number] and Cache[number].inputs then
|
||||
local cmnd = Cache[number].inputs["term"]
|
||||
Cache[number].inputs["term"] = nil
|
||||
return cmnd
|
||||
end
|
||||
end
|
||||
|
||||
-- used for queued messages
|
||||
function techage.lua_ctlr.get_msg(number)
|
||||
if Cache[number] and Cache[number].inputs then
|
||||
return table.remove(Cache[number].inputs["msg"], 1)
|
||||
end
|
||||
end
|
||||
|
||||
techage.register_node({"techage:ta4_lua_controller"}, {
|
||||
on_recv_message = function(pos, topic, payload)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = meta:get_string("number")
|
||||
|
||||
if topic == "on" then
|
||||
set_input(pos, number, payload, topic)
|
||||
elseif topic == "off" then
|
||||
set_input(pos, number, payload, topic)
|
||||
elseif topic == "term" then
|
||||
set_input(pos, number, "term", payload)
|
||||
elseif topic == "msg" then
|
||||
set_input(pos, number, "msg", payload)
|
||||
elseif topic == "state" then
|
||||
local running = meta:get_int("running") or STATE_STOPPED
|
||||
return techage.statestring(running)
|
||||
else
|
||||
return "unsupported"
|
||||
end
|
||||
end,
|
||||
})
|
193
lua_controller/sensorchest.lua
Normal file
193
lua_controller/sensorchest.lua
Normal file
@ -0,0 +1,193 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA4 Sensor Chest
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local PlayerActions = {}
|
||||
local InventoryState = {}
|
||||
|
||||
|
||||
local function store_action(pos, player, action, stack)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local name = player and player:get_player_name() or ""
|
||||
local number = meta:get_string("node_number")
|
||||
local item = stack:get_name().." "..stack:get_count()
|
||||
PlayerActions[number] = {name, action, item}
|
||||
end
|
||||
|
||||
local function send_off_command(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local numbers = meta:get_string("numbers") or ""
|
||||
if numbers ~= "" then
|
||||
local own_num = meta:get_string("node_number")
|
||||
techage.send_multi(own_num, numbers, "off")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function send_command(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local numbers = meta:get_string("numbers") or ""
|
||||
if numbers ~= "" then
|
||||
local own_num = meta:get_string("node_number")
|
||||
techage.send_multi(own_num, numbers, "on")
|
||||
minetest.after(1, send_off_command, pos)
|
||||
end
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
store_action(pos, player, "put", stack)
|
||||
send_command(pos)
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
store_action(pos, player, "take", stack)
|
||||
send_command(pos)
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
local function can_dig(pos, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return false
|
||||
end
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
return inv:is_empty("main")
|
||||
end
|
||||
|
||||
local function after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
techage.remove_node(pos)
|
||||
end
|
||||
|
||||
local function formspec(pos)
|
||||
local text = M(pos):get_string("text")
|
||||
return "size[8,6]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"list[context;main;0,0;2,2;]"..
|
||||
"button[2,0;1,1;f1;F1]"..
|
||||
"button[2,1;1,1;ok;OK]"..
|
||||
"label[3,0;"..text.."]"..
|
||||
"list[current_player;main;0,2.3;8,4;]"..
|
||||
"listring[context;main]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
minetest.register_node("techage:ta4_sensor_chest", {
|
||||
description = S("TA4 Sensor Chest"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta4.png^techage_frame_ta4_top.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_chest_back_ta4.png^techage_appl_sensor.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_chest_back_ta4.png^techage_appl_sensor.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_chest_back_ta4.png^techage_appl_sensor.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_chest_front_ta4.png^techage_appl_sensor.png",
|
||||
},
|
||||
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('main', 4)
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = techage.add_node(pos, "techage:ta4_sensor_chest")
|
||||
meta:set_string("node_number", number)
|
||||
meta:set_string("owner", placer:get_player_name())
|
||||
meta:set_string("text", "Text to be changed\nby command.")
|
||||
meta:set_string("formspec", formspec(pos))
|
||||
meta:set_string("infotext", S("TA4 Sensor Chest").." "..number)
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if fields.f1 then
|
||||
store_action(pos, player, "f1")
|
||||
send_command(pos)
|
||||
end
|
||||
if fields.ok then
|
||||
store_action(pos, player, "ok")
|
||||
send_command(pos)
|
||||
end
|
||||
meta:set_string("formspec", formspec(pos, meta))
|
||||
end,
|
||||
|
||||
techage_set_numbers = function(pos, numbers, player_name)
|
||||
return techage.logic.set_numbers(pos, numbers, player_name, S("TA4 Sensor Chest"))
|
||||
end,
|
||||
|
||||
can_dig = can_dig,
|
||||
after_dig_node = after_dig_node,
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
techage.register_node({"ta4_sensor_chest"}, {
|
||||
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, src, topic, payload)
|
||||
if topic == "state" then
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return techage.get_inv_state(inv, "main")
|
||||
elseif topic == "player_action" then
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = meta:get_string("node_number")
|
||||
return PlayerActions[number]
|
||||
elseif topic == "text" then
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("text", tostring(payload))
|
||||
else
|
||||
return "unsupported"
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "techage:ta4_sensor_chest",
|
||||
recipe = {"techage:chest_ta4", "techage:ta4_wlanchip"}
|
||||
})
|
||||
|
232
lua_controller/server.lua
Normal file
232
lua_controller/server.lua
Normal file
@ -0,0 +1,232 @@
|
||||
--[[
|
||||
|
||||
sl_controller
|
||||
=============
|
||||
|
||||
Copyright (C) 2018 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
server.lua:
|
||||
|
||||
]]--
|
||||
|
||||
local SERVER_CAPA = 5000
|
||||
local DEFAULT_MEM = {
|
||||
size=0,
|
||||
data={
|
||||
version = 1,
|
||||
info = "SaferLua key/value Server",
|
||||
}
|
||||
}
|
||||
|
||||
local function formspec(meta)
|
||||
local names = meta:get_string("names") or ""
|
||||
return "size[9,4]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"field[0.2,1;9,1;names;Allowed user names (spaces separated):;"..names.."]" ..
|
||||
"button_exit[3.5,2.5;2,1;exit;Save]"
|
||||
end
|
||||
|
||||
|
||||
local function on_time(pos, elasped)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if next(nvm) == nil then
|
||||
nvm = table.copy(DEFAULT_MEM)
|
||||
end
|
||||
local number = meta:get_string("number")
|
||||
meta:set_string("infotext", "Server "..number..": ("..(nvm.size or 0).."/"..SERVER_CAPA..")")
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_node("techage:ta4_server", {
|
||||
description = "Central Server",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_server_top.png",
|
||||
"techage_server_top.png",
|
||||
"techage_server_side.png",
|
||||
"techage_server_side.png^[transformFX",
|
||||
"techage_server_back.png",
|
||||
{
|
||||
image = "techage_server_front.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -3/16, -8/16, -7/16, 3/16, 6/16, 7/16},
|
||||
},
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = techage.add_node(pos, "techage:ta4_server")
|
||||
meta:set_string("owner", placer:get_player_name())
|
||||
meta:set_string("number", number)
|
||||
meta:set_string("formspec", formspec(meta))
|
||||
on_time(pos, 0)
|
||||
minetest.get_node_timer(pos):start(20)
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local owner = meta:get_string("owner")
|
||||
if player:get_player_name() == owner then
|
||||
if fields.names and fields.names ~= "" then
|
||||
local names = string.gsub(fields.names, " +", " ")
|
||||
meta:set_string("names", names)
|
||||
meta:set_string("formspec", formspec(meta))
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
on_dig = function(pos, node, puncher, pointed_thing)
|
||||
if minetest.is_protected(pos, puncher:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local number = meta:get_string("number")
|
||||
techage.del_mem(pos)
|
||||
minetest.node_dig(pos, node, puncher, pointed_thing)
|
||||
techage.remove_node(pos)
|
||||
end,
|
||||
|
||||
on_timer = on_time,
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=1, cracky=1, crumbly=1},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta4_server",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "dye:black", "default:steel_ingot"},
|
||||
{"techage:ta4_ramchip", "default:copper_ingot", "techage:ta4_ramchip"},
|
||||
{"techage:ta4_ramchip", "techage:ta4_wlanchip", "techage:ta4_ramchip"},
|
||||
},
|
||||
})
|
||||
|
||||
local function calc_size(v)
|
||||
if type(v) == "number" then
|
||||
return 1
|
||||
elseif v == nil then
|
||||
return 0
|
||||
elseif type(v) == "string" then
|
||||
return #v
|
||||
elseif v.MemSize then
|
||||
return v.MemSize
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
local function get_memory(pos, num, name)
|
||||
local info = techage.get_node_info(num)
|
||||
if info and info.name == "techage:ta4_server" then
|
||||
local meta = minetest.get_meta(info.pos)
|
||||
local owner = meta:get_string("owner")
|
||||
if name == owner then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if next(nvm) == nil then
|
||||
nvm = table.copy(DEFAULT_MEM)
|
||||
end
|
||||
return nvm
|
||||
end
|
||||
local names = meta:get_string("names")
|
||||
for _,n in ipairs(string.split(names, " ")) do
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if name == n then
|
||||
if next(nvm) == nil then
|
||||
nvm = table.copy(DEFAULT_MEM)
|
||||
end
|
||||
return nvm
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function write_value(nvm, key, item)
|
||||
if nvm and nvm.size < SERVER_CAPA then
|
||||
if nvm.data[key] then
|
||||
nvm.size = nvm.size - calc_size(nvm.data[key])
|
||||
end
|
||||
if type(item) == "table" then
|
||||
item = safer_lua.datastruct_to_table(item)
|
||||
end
|
||||
nvm.size = nvm.size + calc_size(item)
|
||||
nvm.data[key] = item
|
||||
end
|
||||
end
|
||||
|
||||
local function read_value(nvm, key)
|
||||
local item = nvm.data[key]
|
||||
if type(item) == "table" then
|
||||
item = safer_lua.table_to_datastruct(item)
|
||||
end
|
||||
return item
|
||||
end
|
||||
|
||||
techage.register_node({"techage:ta4_server"}, {
|
||||
on_recv_message = function(pos, topic, payload)
|
||||
return "unsupported"
|
||||
end,
|
||||
on_node_load = function(pos)
|
||||
minetest.get_node_timer(pos):start(20)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
techage.lua_ctlr.register_function("server_read", {
|
||||
cmnd = function(self, num, key)
|
||||
if type(key) == "string" then
|
||||
local nvm = get_memory(self.meta.pos, num, self.meta.owner)
|
||||
if nvm then
|
||||
return read_value(nvm, key)
|
||||
end
|
||||
else
|
||||
self.error("Invalid server_read parameter")
|
||||
end
|
||||
end,
|
||||
help = " $server_read(num, key)\n"..
|
||||
" Read a value from the server.\n"..
|
||||
" 'key' must be a string.\n"..
|
||||
' example: state = $server_read("0123", "state")'
|
||||
})
|
||||
|
||||
techage.lua_ctlr.register_action("server_write", {
|
||||
cmnd = function(self, num, key, value)
|
||||
if type(key) == "string" then
|
||||
local nvm = get_memory(self.meta.pos, num, self.meta.owner)
|
||||
if nvm then
|
||||
write_value(nvm, key, value)
|
||||
end
|
||||
else
|
||||
self.error("Invalid server_write parameter")
|
||||
end
|
||||
end,
|
||||
help = " $server_write(num, key, value)\n"..
|
||||
" Store a value on the server under the key 'key'.\n"..
|
||||
" 'key' must be a string. 'value' can be either a\n"..
|
||||
" number, string, boolean, nil or data structure.\n"..
|
||||
' example: $server_write("0123", "state", state)'
|
||||
})
|
||||
|
||||
|
@ -212,7 +212,7 @@ minetest.register_node("techage:power_terminal", {
|
||||
on_rotate = screwdriver.disallow,
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 1, level = 2},
|
||||
groups = {cracky = 2, level = 2},
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
})
|
||||
|
||||
|
BIN
textures/techage_appl_sensor.png
Normal file
BIN
textures/techage_appl_sensor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
Loading…
Reference in New Issue
Block a user