280 lines
8.7 KiB
Lua
280 lines
8.7 KiB
Lua
-- computers/api.lua
|
|
|
|
local path = digicompute.path
|
|
local main_path = path.."computers/"
|
|
|
|
local computers = digicompute.loaded_computers
|
|
|
|
----------------------------------
|
|
-- MID-BOOT COMPUTER MANAGEMENT --
|
|
----------------------------------
|
|
|
|
-- Loop through all computers in a coroutine and check if
|
|
-- any were left in the midst of the boot process
|
|
local check_booting = coroutine.create(function()
|
|
-- [function] Get node
|
|
local function get_node(pos)
|
|
local node = minetest.get_node_or_nil(pos)
|
|
if node then return node end
|
|
minetest.get_voxel_manip(pos, pos)
|
|
return minetest.get_node(pos)
|
|
end
|
|
|
|
for id, c in pairs(computers) do
|
|
if c.booting then
|
|
local temp = get_node(c.pos)
|
|
local ddef = minetest.registered_nodes[temp.name].digicompute
|
|
if ddef.state == "off" or ddef.state == "bios" then
|
|
local name, param2 = "digicompute_redo:"..ddef.base, temp.param2
|
|
digicompute.c:complete_boot(c.pos, id, name, param2)
|
|
else
|
|
c.booting = nil
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
-- Start coroutine
|
|
minetest.after(0, function()
|
|
coroutine.resume(check_booting)
|
|
end)
|
|
|
|
-------------------------
|
|
-- COMPUTER OPERATIONS --
|
|
-------------------------
|
|
|
|
-- [function] update infotext
|
|
function digicompute.c:infotext(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
local state = minetest.registered_nodes[minetest.get_node(pos).name].digicompute.state
|
|
|
|
if meta:get_string("setup") == "true" then
|
|
meta:set_string("infotext", meta:get_string("name").." - "..state.."\n(owned by "
|
|
..meta:get_string("owner")..")")
|
|
else
|
|
meta:set_string("infotext", "Unconfigured Computer - "..state.."\n(owned by "
|
|
..meta:get_string("owner")..")")
|
|
end
|
|
end
|
|
|
|
-- [function] print to computer debug buffer
|
|
function digicompute.c:print_debug(pos, msg)
|
|
if type(msg) ~= "string" then msg = dump(msg) end
|
|
local meta = minetest.get_meta(pos)
|
|
local debug = minetest.deserialize(meta:get_string("debug"))
|
|
table.insert(debug, os.date("[%d/%m/%Y @ %H:%M] ")..msg)
|
|
meta:set_string("debug", minetest.serialize(debug))
|
|
return true
|
|
end
|
|
|
|
-- [function] initialize computer
|
|
function digicompute.c:init(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
local new_path = meta:get_string("path")
|
|
|
|
if new_path and new_path ~= "" then
|
|
digicompute.builtin.mkdir(main_path..meta:get_string("owner"))
|
|
digicompute.builtin.mkdir(new_path)
|
|
digicompute.builtin.cpdir(digicompute.modpath.."/octos/", new_path.."os")
|
|
digicompute.log("Initialized computer "..meta:get_string("id").." owned by "..
|
|
meta:get_string("owner").." at "..minetest.pos_to_string(pos))
|
|
digicompute.c:infotext(pos)
|
|
digicompute.c:print_debug(pos, "Initialized")
|
|
end
|
|
end
|
|
|
|
-- [function] deinitialize computer
|
|
function digicompute.c:deinit(pos, clear_entry)
|
|
local meta = minetest.get_meta(pos)
|
|
local old_path = meta:get_string("path")
|
|
local owner = meta:get_string("owner")
|
|
|
|
if old_path and old_path ~= "" then
|
|
digicompute.builtin.rmdir(old_path)
|
|
digicompute.log("Deinitialized computer "..meta:get_string("id").." owned by "..
|
|
meta:get_string("owner").." at "..minetest.pos_to_string(pos))
|
|
|
|
if digicompute.builtin.list(main_path..owner).subdirs then
|
|
digicompute.builtin.rmdir(main_path..owner)
|
|
end
|
|
end
|
|
|
|
local id = meta:get_string("id")
|
|
-- Remove saved environment
|
|
digicompute.c:remove_env(pos)
|
|
|
|
if clear_entry ~= false then
|
|
computers[id] = nil
|
|
end
|
|
end
|
|
|
|
-- [function] reinitialize computer (reset)
|
|
function digicompute.c:reinit(pos)
|
|
digicompute.c:deinit(pos, false)
|
|
digicompute.c:init(pos)
|
|
end
|
|
|
|
-- [function] complete computer boot process (swap from bios to on)
|
|
function digicompute.c:complete_boot(pos, index, name, param2)
|
|
minetest.swap_node({x = pos.x, y = pos.y, z = pos.z}, {name = name.."_on", param2 = param2})
|
|
|
|
-- Remove computer booting tag
|
|
computers[index].booting = nil
|
|
|
|
-- Update infotext
|
|
digicompute.c:infotext(pos)
|
|
-- Set last boot to the current time for later use on_rightclick to
|
|
-- check if os/start.lua should be run
|
|
minetest.get_meta(pos):set_int("last_boot", os.time())
|
|
-- Log boot in debug buffer
|
|
digicompute.c:print_debug(pos, "Booted")
|
|
end
|
|
|
|
-- [function] turn computer on
|
|
function digicompute.c:on(pos)
|
|
local temp = minetest.get_node(pos)
|
|
local ddef = minetest.registered_nodes[temp.name].digicompute
|
|
if ddef.state == "off" then
|
|
local name, param2 = temp.name, temp.param2
|
|
|
|
-- Swap to Bios
|
|
minetest.swap_node({x = pos.x, y = pos.y, z = pos.z}, {name = name.."_bios", param2 = param2}) -- set node to bios
|
|
|
|
-- Update infotext
|
|
digicompute.c:infotext(pos)
|
|
|
|
-- Save event so that if the game is exited mid-boot, the boot
|
|
-- process can be resumed immediately thereafter
|
|
local id = minetest.get_meta(pos):get_string("id")
|
|
computers[id].booting = true
|
|
|
|
-- Swap to on node after 2 seconds
|
|
minetest.after(2, function(pos_, index)
|
|
digicompute.c:complete_boot(pos_, index, name, param2)
|
|
end, vector.new(pos), id)
|
|
end
|
|
end
|
|
|
|
-- [function] turn computer off
|
|
function digicompute.c:off(pos, player)
|
|
local temp = minetest.get_node(pos) -- Get basic node information
|
|
local offname = "digicompute_redo:"..minetest.registered_nodes[temp.name].digicompute.base
|
|
local meta = minetest.get_meta(pos)
|
|
-- Swap node to off
|
|
minetest.swap_node({x = pos.x, y = pos.y, z = pos.z}, {name = offname, param2 = temp.param2})
|
|
-- Update infotext
|
|
digicompute.c:infotext(pos)
|
|
-- Close formspec if player object is provided
|
|
if player and player.get_player_name then
|
|
minetest.close_formspec(player:get_player_name(), "")
|
|
end
|
|
-- Log action in debug buffer
|
|
digicompute.c:print_debug(pos, "Shut down")
|
|
-- Clear output buffer
|
|
meta:set_string("output", "")
|
|
-- Clear RAM
|
|
meta:set_string("ram", minetest.serialize({}))
|
|
-- Reset environment
|
|
digicompute.c:remove_env(pos)
|
|
end
|
|
|
|
-- [function] reboot computer
|
|
function digicompute.c:reboot(pos, player)
|
|
digicompute.c:off(pos, player)
|
|
digicompute.c:on(pos)
|
|
end
|
|
|
|
----------------------
|
|
-- NODE DEFINITIONS --
|
|
----------------------
|
|
|
|
function digicompute.register_computer(itemstring, def)
|
|
-- off
|
|
minetest.register_node("digicompute_redo:"..itemstring, {
|
|
digicompute = {
|
|
state = "off",
|
|
base = itemstring,
|
|
},
|
|
drawtype = "nodebox",
|
|
description = def.description,
|
|
tiles = def.off_tiles,
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
groups = {cracky = 2},
|
|
drop = "digicompute_redo:"..itemstring,
|
|
sounds = default.node_sound_stone_defaults(),
|
|
node_box = def.node_box,
|
|
after_place_node = function(pos, player)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("owner", player:get_player_name())
|
|
meta:set_string("input", "") -- Initialize input buffer
|
|
meta:set_string("output", "") -- Initialize output buffer
|
|
meta:set_string("debug", minetest.serialize({})) -- Initialize debug buffer
|
|
meta:set_string("system", minetest.serialize({})) -- Initialize system table
|
|
meta:set_string("ram", minetest.serialize({})) -- Initialize RAM preservation table
|
|
meta:set_string("help", "Type a command and press enter.") -- Initialize help
|
|
meta:set_string("output_editable", "false") -- Initialize uneditable output
|
|
meta:set_int("wrap_limit", 90) -- Initialize wrap chracter limit
|
|
digicompute.c:new_id(pos) -- Set up ID
|
|
|
|
-- Update infotext
|
|
digicompute.c:infotext(pos)
|
|
end,
|
|
on_rightclick = function(pos, node, player)
|
|
digicompute.c:on(pos)
|
|
end,
|
|
on_destruct = function(pos)
|
|
if minetest.get_meta(pos):get_string("name") then
|
|
digicompute.c:deinit(pos)
|
|
end
|
|
end,
|
|
})
|
|
-- bios
|
|
minetest.register_node("digicompute_redo:"..itemstring.."_bios", {
|
|
light_source = def.light_source or 7,
|
|
digicompute = {
|
|
state = "bios",
|
|
base = itemstring,
|
|
},
|
|
drawtype = "nodebox",
|
|
defription = def.defription,
|
|
tiles = def.bios_tiles,
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
groups = {cracky = 2, not_in_creative_inventory = 1},
|
|
drop = "digicompute_redo:"..itemstring,
|
|
sounds = default.node_sound_stone_defaults(),
|
|
node_box = def.node_box,
|
|
on_destruct = function(pos)
|
|
if minetest.get_meta(pos):get_string("name") then
|
|
digicompute.c:deinit(pos)
|
|
end
|
|
end,
|
|
})
|
|
-- on
|
|
minetest.register_node("digicompute_redo:"..itemstring.."_on", {
|
|
light_source = def.light_source or 7,
|
|
digicompute = {
|
|
state = "on",
|
|
base = itemstring,
|
|
},
|
|
drawtype = "nodebox",
|
|
description = def.defription,
|
|
tiles = def.on_tiles,
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
groups = {cracky = 2, not_in_creative_inventory = 1},
|
|
drop = "digicompute_redo:"..itemstring,
|
|
sounds = default.node_sound_stone_defaults(),
|
|
node_box = def.node_box,
|
|
on_rightclick = function(pos, node, player)
|
|
digicompute.c:open(pos, player)
|
|
end,
|
|
on_destruct = function(pos)
|
|
if minetest.get_meta(pos):get_string("name") then
|
|
digicompute.c:deinit(pos)
|
|
end
|
|
end,
|
|
})
|
|
end
|