Auke Kok 003cc38c21 Sounds: move them into sounds mod, add electric humm for mech.
Most of the active mech nodes now make the humming sound, which
is very low key but still audible.
2017-03-28 21:35:24 -07:00

294 lines
7.9 KiB
Lua

--[[
terminal - an interactive terminal
]]--
local context = {}
local function get_cmd_params(line)
local cmd = ""
local params = ""
for w in line:gmatch("%w+") do
if cmd == "" then
cmd = w
elseif params == "" then
params = w
else
params = params .. " " .. w
end
end
return cmd, params
end
local help = {
append = "append text to a file",
clear = "clear the output",
echo = "echoes the input back to you",
help = "display help information for commands",
list = "list available files",
lock = "lock the terminal",
read = "read the content of a file",
remove = "removes a file",
unlock = "unlocks the terminal",
write = "write text to a file",
}
local commands = {
clear = function(output, params, c)
return ""
end,
append = function(output, params, c)
if not c.rw then
return output .. "\nno write access"
end
local what, _ = get_cmd_params(params)
if what == "" then
return output .. "\nMissing file name"
end
c.writing = what
return output .. "\n" .. "writing \"" .. what .. "\". Enter STOP on a line by itself to finish"
end,
write = function(output, params, c)
if not c.rw then
return output .. "\nno write access"
end
local what, _ = get_cmd_params(params)
if what == "" then
return output .. "\nMissing file name"
end
c.writing = what
local meta = minetest.get_meta(c.pos)
local meta_files = meta:get_string("files")
if meta_files and meta_files ~= "" then
local files = minetest.parse_json(meta_files)
if files[what] then
files[what] = ""
meta:set_string("files", minetest.write_json(files))
end
end
return output .. "\n" .. "writing \"" .. what .. "\". Enter STOP on a line by itself to finish"
end,
remove = function(output, params, c)
if not c.rw then
return output .. "\nno write access"
end
local meta = minetest.get_meta(c.pos)
local meta_files = meta:get_string("files")
if not meta_files or meta_files == "" then
return output .. "\nNo such file"
end
local files = minetest.parse_json(meta_files)
local first, _ = get_cmd_params(params)
if files[first] then
files[first] = nil
else
return output .. "\n" .. "No such file"
end
meta:set_string("files", minetest.write_json(files))
return output .. "\n" .. "removed \"" .. first .. "\""
end,
list = function(output, params, c)
local meta = minetest.get_meta(c.pos)
local meta_files = meta:get_string("files")
local files
if not meta_files or meta_files == "" then
return output .. "\nNo files found"
end
files = minetest.parse_json(meta_files)
if not files then
return output .. "\nNo files found"
end
for k, _ in pairs(files) do
output = output .. "\n" .. k
end
return output
end,
echo = function(output, params, c)
return output .. "\n" .. params
end,
read = function(output, params, c)
local meta = minetest.get_meta(c.pos)
local meta_files = meta:get_string("files")
if not meta_files or meta_files == "" then
return output .. "\nNo such file"
end
local files = minetest.parse_json(meta_files)
local first, _ = get_cmd_params(params)
if files[first] then
return output .. "\n" .. files[first]
else
return output .. "\n" .. "No such file"
end
end,
lock = function(output, params, c)
if not c.rw then
return output .. "\nno write access"
end
local meta = minetest.get_meta(c.pos)
meta:set_int("locked", 1)
return output .. "\n" .. "terminal locked"
end,
unlock = function(output, params, c)
return output .. "\n" .. "unable to connect to authentication service"
end,
help = function(output, params, c)
if params ~= "" then
local h, _ = get_cmd_params(params)
if help[h] then
return output .. "\n" .. help[h]
else
return output .. "\nno help for \"" .. h .. "\""
end
end
return output .. "\n" ..
"append clear echo help list lock read remove unlock write"
end,
}
local function make_formspec(output, prompt)
local f =
"size[12,8]" ..
"field_close_on_enter[input;false]" ..
"textlist[0.4,0.5;11,6;output;"
local c = 1
for part in output:gmatch("[^\r\n]+") do
f = f .. minetest.formspec_escape(part) .. ","
c = c + 1
end
f = f .. minetest.formspec_escape(prompt) .. ";" .. c .. ";false]"
f = f .. "field[0.7,7;11.2,1;input;;]"
return f
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "terminal:" then
return false
end
local line = fields.input
if line and line ~= "" then
local name = player:get_player_name()
local c = context[name]
local output = c.output or ""
minetest.sound_play("terminal_keyboard_clicks", {pos = c.pos})
if c.writing then
-- this shouldn't get reached, but just to be safe, check ro
if not c.rw then
c.writing = nil
output = output .. "\n" .. line
output = output .. "\nno write access"
c.output = output
minetest.show_formspec(name, "terminal:", make_formspec(output, "> "))
return true
end
-- are we writing a file?
if line == "STOP" then
-- done writing a file
c.writing = nil
output = output .. "\n" .. line
c.output = output
minetest.show_formspec(name, "terminal:", make_formspec(output, "> "))
return true
end
local meta = minetest.get_meta(c.pos)
local meta_files = meta:get_string("files")
local files = {}
if not meta_files or meta_files == "" then
files[c.writing] = line
else
files = minetest.parse_json(meta_files)
if not files[c.writing] then
files[c.writing] = line
else
files[c.writing] = files[c.writing] .. "\n" .. line
end
end
meta:set_string("files", minetest.write_json(files))
output = output .. "\n" .. line
c.output = output
minetest.show_formspec(name, "terminal:", make_formspec(output, ""))
else
-- else parse cmd
output = output .. "\n> " .. line
local meta = minetest.get_meta(c.pos)
local cmd, params = get_cmd_params(line)
if meta:get_int("locked") == 1 and cmd ~= "unlock" then
output = output .. "\nTerminal locked, type \"unlock\" to unlock it"
c.output = output
minetest.show_formspec(name, "terminal:", make_formspec(output, "> "))
return true
end
local fn = commands[cmd]
if fn then
output = fn(output, params, c)
else
output = output .. "\n" .. "Syntax Error. Try \"help\""
end
c.output = output
minetest.show_formspec(name, "terminal:", make_formspec(output, "> "))
end
elseif fields.quit then
local name = player:get_player_name()
local c = context[name]
minetest.sound_play("terminal_power_off", {pos = c.pos})
end
return true
end)
local terminal_use = function(pos, node, clicker, itemstack, pointed_thing)
if not clicker then
return
end
local name = clicker:get_player_name()
context[name] = {
pos = pos,
rw = false,
output = "",
}
if boxes.players_editing_boxes[name] or
(not boxes.players_in_boxes[name] and minetest.check_player_privs(clicker, "server")) then
-- allow rw access
context[name].rw = true
end
-- send formspec to player
minetest.show_formspec(name, "terminal:", make_formspec("", "> "))
minetest.sound_play("terminal_power_on", {pos = pos})
-- trigger on first use
local meta = minetest.get_meta(pos)
if meta:get_int("locked") ~= 1 then
mech.trigger(pos)
minetest.after(1.0, mech.untrigger, pos)
end
end
minetest.register_node("terminal:terminal", {
description = "An interactive terminal console emulator access interface unit controller",
drawtype = "mesh",
mesh = "terminal.obj",
groups = {mech = 1},
tiles = {
{name = "terminal_base.png"},
{name = "terminal_idle.png", animation = {type = "vertical_frames", aspect_w = 14, aspect_h = 13, length = 4.0}},
},
paramtype = "light",
paramtype2 = "facedir",
on_trigger = function(pos)
local meta = minetest.get_meta(pos)
minetest.sound_play("terminal_power_on", {pos = pos})
meta:set_int("locked", 0)
end,
on_untrigger = function(pos)
local meta = minetest.get_meta(pos)
minetest.sound_play("terminal_power_off", {pos = pos})
meta:set_int("locked", 1)
end,
on_rightclick = terminal_use,
})