Traitor/mods/vents/station.lua
2022-05-23 20:51:28 -05:00

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}},
})