241 lines
6.3 KiB
Lua
241 lines
6.3 KiB
Lua
--[[
|
|
|
|
TechAge
|
|
=======
|
|
|
|
Copyright (C) 2019-2022 Joachim Stolberg
|
|
|
|
AGPL v3
|
|
See LICENSE.txt for more information
|
|
|
|
For chests and tanks with hyperloop support
|
|
|
|
]]--
|
|
|
|
-- for lazy programmers
|
|
local S2P = minetest.string_to_pos
|
|
local P2S = minetest.pos_to_string
|
|
local M = minetest.get_meta
|
|
local N = techage.get_node_lvm
|
|
local S = techage.S
|
|
|
|
-- Will be initialized when mods are loaded
|
|
local Stations = nil
|
|
local Tube = nil
|
|
local HYPERLOOP = nil
|
|
|
|
techage.hyperloop = {}
|
|
|
|
--[[
|
|
|
|
tStations["(x,y,z)"] = {
|
|
conn = {dir = "(200,0,20)", ...},
|
|
name = <node_type>, -- chest/tank
|
|
owner = "singleplayer",
|
|
conn_name = <own name>,
|
|
single = true/nil,
|
|
}
|
|
|
|
]]--
|
|
|
|
minetest.register_on_mods_loaded(function()
|
|
if minetest.global_exists("hyperloop") then
|
|
Stations = hyperloop.Stations
|
|
Tube = hyperloop.Tube
|
|
HYPERLOOP = true
|
|
Tube:add_secondary_node_names({"techage:ta5_hl_chest", "techage:ta5_hl_tank"})
|
|
end
|
|
end)
|
|
|
|
local function get_remote_pos(pos, rmt_name)
|
|
local owner = M(pos):get_string("owner")
|
|
for key,item in pairs(Stations:get_node_table(pos)) do
|
|
if item.owner == owner and item.conn_name == rmt_name then
|
|
return S2P(key)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function get_free_server_list(pos, owner)
|
|
if Stations and Stations.get_node_table then
|
|
local tbl = {M(pos):get_string("remote_name")}
|
|
for key,item in pairs(Stations:get_node_table(pos) or {}) do
|
|
if item.single and item.owner == owner then
|
|
if M(pos):get_string("node_type") == M(S2P(key)):get_string("node_type") then
|
|
tbl[#tbl+1] = item.conn_name
|
|
end
|
|
end
|
|
end
|
|
tbl[#tbl+1] = ""
|
|
return tbl
|
|
end
|
|
return {}
|
|
end
|
|
|
|
local function on_lose_connection(pos, node_type)
|
|
local name = techage.get_node_lvm(pos).name
|
|
local ndef = minetest.registered_nodes[name]
|
|
if ndef and ndef.on_lose_connection then
|
|
ndef.on_lose_connection(pos, node_type)
|
|
end
|
|
end
|
|
|
|
local function on_dropdown(pos)
|
|
if pos then
|
|
local owner = M(pos):get_string("owner")
|
|
return table.concat(get_free_server_list(pos, owner), ",") or ""
|
|
end
|
|
return ""
|
|
end
|
|
|
|
local function update_node_data(pos, state, conn_name, remote_name, rmt_pos)
|
|
local meta = M(pos)
|
|
local nvm = techage.get_nvm(pos)
|
|
|
|
if state == "server_connected" then
|
|
Stations:update(pos, {conn_name=conn_name, single="nil"})
|
|
meta:set_string("status", "server")
|
|
meta:set_string("conn_name", conn_name)
|
|
meta:set_string("remote_name", "")
|
|
meta:set_string("conn_status", S("connected to") .. " " .. P2S(rmt_pos))
|
|
nvm.rmt_pos = rmt_pos
|
|
elseif state == "client_connected" then
|
|
Stations:update(pos, {conn_name="nil", single="nil"})
|
|
meta:set_string("status", "client")
|
|
meta:set_string("conn_name", "")
|
|
meta:set_string("remote_name", remote_name)
|
|
meta:set_string("conn_status", S("connected to") .. " " .. P2S(rmt_pos))
|
|
nvm.rmt_pos = rmt_pos
|
|
elseif state == "server_not_connected" then
|
|
Stations:update(pos, {conn_name=conn_name, single=true})
|
|
meta:set_string("status", "server")
|
|
meta:set_string("conn_name", conn_name)
|
|
meta:set_string("remote_name", "")
|
|
meta:set_string("conn_status", S("not connected"))
|
|
nvm.rmt_pos = nil
|
|
on_lose_connection(pos, "server")
|
|
elseif state == "client_not_connected" then
|
|
Stations:update(pos, {conn_name="nil", single=nil})
|
|
meta:set_string("status", "not connected")
|
|
meta:set_string("conn_name", "")
|
|
meta:set_string("remote_name", "")
|
|
meta:set_string("conn_status", S("not connected"))
|
|
nvm.rmt_pos = nil
|
|
on_lose_connection(pos, "client")
|
|
end
|
|
end
|
|
|
|
techage.hyperloop.SUBMENU = {
|
|
{
|
|
type = "label",
|
|
label = S("Enter a block name or select an existing one"),
|
|
tooltip = "",
|
|
name = "l1",
|
|
},
|
|
{
|
|
type = "ascii",
|
|
name = "conn_name",
|
|
label = S("Block name"),
|
|
tooltip = S("Connection name for this block"),
|
|
default = "",
|
|
},
|
|
{
|
|
type = "dropdown",
|
|
choices = "",
|
|
on_dropdown = on_dropdown,
|
|
name = "remote_name",
|
|
label = S("Remote name"),
|
|
tooltip = S("Connection name of the remote block"),
|
|
},
|
|
}
|
|
|
|
function techage.hyperloop.is_client(pos)
|
|
if HYPERLOOP then
|
|
local nvm = techage.get_nvm(pos)
|
|
if Stations:get(nvm.rmt_pos) then
|
|
if M(pos):get_string("status") == "client" then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function techage.hyperloop.is_server(pos)
|
|
if HYPERLOOP then
|
|
if M(pos):get_string("status") == "server" then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
|
|
function techage.hyperloop.is_paired(pos)
|
|
if HYPERLOOP then
|
|
local nvm = techage.get_nvm(pos)
|
|
if Stations:get(nvm.rmt_pos) then
|
|
if M(pos):get_string("status") ~= "not connected" then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function techage.hyperloop.remote_pos(pos)
|
|
if HYPERLOOP then
|
|
local nvm = techage.get_nvm(pos)
|
|
if Stations:get(nvm.rmt_pos) then
|
|
if M(pos):contains("remote_name") then
|
|
return nvm.rmt_pos or pos
|
|
end
|
|
end
|
|
end
|
|
return pos
|
|
end
|
|
|
|
function techage.hyperloop.after_place_node(pos, placer, node_type)
|
|
if HYPERLOOP then
|
|
Stations:set(pos, node_type, {owner=placer:get_player_name()})
|
|
M(pos):set_string("node_type", node_type)
|
|
Tube:after_place_node(pos)
|
|
end
|
|
end
|
|
|
|
function techage.hyperloop.after_dig_node(pos, oldnode, oldmetadata, digger)
|
|
if HYPERLOOP then
|
|
local conn_name = oldmetadata.fields.conn_name
|
|
local remote_name = oldmetadata.fields.remote_name
|
|
local loc_pos, rmt_pos = pos, techage.get_nvm(pos).rmt_pos
|
|
|
|
-- Close connections
|
|
if remote_name and rmt_pos then -- Connected client
|
|
update_node_data(rmt_pos, "server_not_connected", remote_name, "")
|
|
elseif conn_name and rmt_pos then -- Connected server
|
|
update_node_data(rmt_pos, "client_not_connected", "", conn_name)
|
|
end
|
|
|
|
Tube:after_dig_node(pos)
|
|
Stations:delete(pos)
|
|
end
|
|
end
|
|
|
|
function techage.hyperloop.after_formspec(pos, fields)
|
|
if HYPERLOOP and fields.save or fields.key_enter_field then
|
|
local meta = M(pos)
|
|
local conn_name = meta:get_string("conn_name")
|
|
local remote_name = meta:get_string("remote_name")
|
|
local status = meta:contains("status") and meta:get_string("status") or "not connected"
|
|
local loc_pos, rmt_pos = pos, techage.get_nvm(pos).rmt_pos
|
|
|
|
if status == "not connected" then
|
|
if fields.remote_name ~= "" then -- Client
|
|
local rmt_pos = get_remote_pos(pos, fields.remote_name)
|
|
if rmt_pos then
|
|
update_node_data(loc_pos, "client_connected", "", fields.remote_name, rmt_pos)
|
|
update_node_data(rmt_pos, "server_connected", fields.remote_name, "", loc_pos)
|
|
end
|
|
elseif fields.conn_name ~= "" then -- Server
|
|
update_node_data(loc_pos, "server_not_connected", fields.conn_name, "")
|
|
end
|
|
end
|
|
end
|
|
end
|