123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- --[[
- 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.')..']' ..
- 'label[0,.35;Punch the vent to see locations you can teleport too.]' ..
- '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
- 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,
- on_punch = function(pos, node, puncher)
- local wield = puncher:get_wielded_item()
- local wield_name = wield:get_name()
- if wield_name == 'creative:tool_breaking' then
- return
- else
- local name = puncher:get_player_name()
- local player_attributes = puncher:get_meta()
- local mode = player_attributes:get_string('mode')
- vents.player_pos[name] = pos
- if mode == 'builder' then
- minetest.show_formspec(name, 'vents:station_list', station_list_as_string(pos))
- end
- 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}},
- })
|