225 lines
6.9 KiB
Lua
225 lines
6.9 KiB
Lua
--[[
|
|
|
|
Hyperloop Mod
|
|
=============
|
|
|
|
Copyright (C) 2017-2019 Joachim Stolberg
|
|
|
|
LGPLv2.1+
|
|
See LICENSE.txt for more information
|
|
|
|
]]--
|
|
|
|
-- for lazy programmers
|
|
local SP = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
|
local P = minetest.string_to_pos
|
|
local M = minetest.get_meta
|
|
|
|
-- Load support for intllib.
|
|
local S = vents.S
|
|
local NS = vents.NS
|
|
|
|
local Tube = vents.Tube
|
|
local Stations = vents.Stations
|
|
|
|
-- Used to store the Station list for each vent:
|
|
-- tStationList[SP(pos)] = {pos1, pos2, ...}
|
|
local tStationList = {}
|
|
|
|
local function store_station(pos, placer)
|
|
local facedir = vents.get_facedir(placer)
|
|
-- do a facedir correction
|
|
facedir = (facedir + 3) % 4 -- face to LCD
|
|
Stations:set(pos, 'Station', {
|
|
owner = placer:get_player_name(),
|
|
facedir = facedir,
|
|
time_blocked = 0})
|
|
end
|
|
|
|
local function naming_formspec(pos)
|
|
local data = Stations:get(pos)
|
|
local vent = data.name or 'vent'
|
|
local info = data.booking_info or ''
|
|
local formspec =
|
|
'size[7,4.4]'..
|
|
'label[0,0;'..S('Please enter the vent name.')..']' ..
|
|
'field[0.2,1.5;7.1,1;name;'..S('Vent name')..';'..vent..']' ..
|
|
'field[0.2,2.7;7.1,1;info;'..S('Additional vent information')..';'..info..']' ..
|
|
'button_exit[2.5,3.7;2,1;exit;Save]'
|
|
return formspec
|
|
end
|
|
|
|
-- Form spec for the station list
|
|
local function generate_string(sortedList)
|
|
local tRes = {'size[12,8]'..
|
|
'label[4,0; '..S('Select your destination')..']'}
|
|
tRes[2] = 'tablecolumns[text,width=20;text,width=6,align=right;text]'
|
|
|
|
local stations = {}
|
|
for idx,tDest in ipairs(sortedList) do
|
|
local name = tDest.name or S('<unknown>')
|
|
local distance = tDest.distance or 0
|
|
local info = tDest.booking_info or ''
|
|
|
|
stations[#stations+1] = minetest.formspec_escape(string.sub(name, 1, 28))
|
|
stations[#stations+1] = distance..'m'
|
|
stations[#stations+1] = minetest.formspec_escape(info)
|
|
end
|
|
|
|
if #stations>0 then
|
|
tRes[#tRes+1] = 'table[0,1;11.8,7.2;button;'..table.concat(stations, ',')..']'
|
|
else
|
|
tRes[#tRes+1] = 'button_exit[4,4;3,1;button;Update]'
|
|
end
|
|
|
|
return table.concat(tRes)
|
|
end
|
|
|
|
local function store_station_list(pos, sortedList)
|
|
local tbl = {}
|
|
for idx,item in ipairs(sortedList) do
|
|
tbl[#tbl+1] = item.pos
|
|
end
|
|
tStationList[SP(pos)] = tbl
|
|
end
|
|
|
|
local function remove_junctions(sortedList)
|
|
local tbl = {}
|
|
for idx,item in ipairs(sortedList) do
|
|
if not item.junction and item.booking_pos then
|
|
tbl[#tbl+1] = item
|
|
end
|
|
end
|
|
return tbl
|
|
end
|
|
|
|
local function filter_subnet(sortedList, subnet)
|
|
if vents.subnet_enabled then
|
|
if subnet == '' then
|
|
subnet = nil
|
|
end
|
|
|
|
local tbl = {}
|
|
for idx,item in ipairs(sortedList) do
|
|
if item.subnet == subnet then
|
|
tbl[#tbl+1] = item
|
|
end
|
|
end
|
|
return tbl
|
|
end
|
|
return sortedList
|
|
end
|
|
|
|
-- Used to update the station list for booking machine
|
|
-- and teleport list.
|
|
local function station_list_as_string(pos, subnet)
|
|
local meta = M(pos)
|
|
-- Generate a name sorted list of all connected stations
|
|
local sortedList = Stations:station_list(pos, pos, 'name')
|
|
-- remove all junctions from the list
|
|
sortedList = remove_junctions(sortedList)
|
|
-- use subnet pattern to reduce the list
|
|
sortedList = filter_subnet(sortedList, subnet)
|
|
-- store the list for later use
|
|
store_station_list(pos, sortedList)
|
|
-- Generate the formspec string
|
|
return generate_string(sortedList)
|
|
end
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
local name = player:get_player_name()
|
|
local pos = vents.player_pos[name]
|
|
if formname == 'vents:setup' then
|
|
if fields.exit then
|
|
if fields.name ~= nil then
|
|
local station_name = string.trim(fields.name)
|
|
if station_name == '' then
|
|
return
|
|
end
|
|
--if Stations:get(pos).booking_pos then
|
|
-- minetest.chat_send_player(name, S('Remove and replace to change name.'))
|
|
--Figure out how to allow a builder to update station.
|
|
-- return
|
|
--end
|
|
-- store meta and generate station formspec
|
|
Stations:update(pos, {
|
|
name = station_name,
|
|
booking_pos = pos,
|
|
booking_info = string.trim(fields.info),
|
|
})
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string('infotext', 'Station: '..station_name)
|
|
minetest.chat_send_player(name, 'Saving data')
|
|
else
|
|
vents.chat(player, S('Invalid station name!'))
|
|
end
|
|
end
|
|
elseif formname == 'vents:station_list' then
|
|
local te = minetest.explode_table_event(fields.button)
|
|
local idx = tonumber(te.row)
|
|
if idx and te.type=='CHG' then
|
|
local tStation, src_pos = vents.get_base_station(pos)
|
|
local dest_pos = tStationList[SP(pos)] and tStationList[SP(pos)][idx]
|
|
if dest_pos and tStation then
|
|
local air = minetest.find_node_near(dest_pos, 2, {'air'})
|
|
if air then
|
|
player:set_pos(air)
|
|
else
|
|
minetest.chat_send_player(name, 'Sorry, can\'t teleport you there.')
|
|
end
|
|
--Should there be some sort of freeze on movement or health loss for using the vents?
|
|
end
|
|
minetest.close_formspec(player:get_player_name(), formname)
|
|
end
|
|
end
|
|
end)
|
|
|
|
local function on_destruct(pos)
|
|
Stations:update((pos), {
|
|
booking_pos = 'nil',
|
|
booking_info = 'nil',
|
|
name = 'Station',
|
|
})
|
|
end
|
|
|
|
minetest.register_node('vents:station', {
|
|
description = S('Vent Access'),
|
|
drawtype = 'nodebox',
|
|
tiles = {'vents_station.png'},
|
|
|
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
|
vents.check_network_level(pos, placer)
|
|
M(pos):set_string('infotext', S('Access Point'))
|
|
store_station(pos, placer)
|
|
Tube:after_place_node(pos)
|
|
end,
|
|
|
|
on_rightclick = function(pos, node, clicker)
|
|
local name = clicker:get_player_name()
|
|
local player_attributes = clicker:get_meta()
|
|
local mode = player_attributes:get_string('mode')
|
|
vents.player_pos[name] = pos
|
|
if mode == 'traitor' or mode == 'solo' or mode == 'ghost' then --allow everybody but crew mambers to use.
|
|
minetest.show_formspec(name, 'vents:station_list', station_list_as_string(pos))
|
|
elseif mode == 'builder' then
|
|
minetest.show_formspec(name, 'vents:setup', naming_formspec(pos))
|
|
else
|
|
minetest.chat_send_player(name, 'Sorry, you can\'t use this.')
|
|
end
|
|
end,
|
|
|
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
|
Tube:after_dig_node(pos)
|
|
Stations:delete(pos)
|
|
end,
|
|
|
|
on_destruct = on_destruct,
|
|
on_rotate = screwdriver.disallow,
|
|
paramtype = 'light',
|
|
paramtype2 = 'facedir',
|
|
groups = {breakable=1},
|
|
is_ground_content = false,
|
|
sounds = {footstep = {name = 'metal', gain = 1}},
|
|
})
|