tubes seam to work
This commit is contained in:
parent
6c59ecc963
commit
d2d5e17c96
2
door.lua
2
door.lua
@ -86,7 +86,7 @@ minetest.register_node("hyperloop:doorBottom", {
|
||||
})
|
||||
|
||||
minetest.register_node("hyperloop:doorframe", {
|
||||
description = "Hyperloop Doorframe",
|
||||
description = "Hyperloop Pod Doorframe",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"hyperloop_skin_door.png^[transformR90]",
|
||||
|
352
init.lua
352
init.lua
@ -17,355 +17,15 @@
|
||||
|
||||
|
||||
hyperloop = {
|
||||
ringList = {},
|
||||
tAllStations = {},
|
||||
order = {},
|
||||
}
|
||||
|
||||
-- max teleport distance
|
||||
-- Intllib
|
||||
local S
|
||||
|
||||
if minetest.get_modpath("intllib") then
|
||||
S = intllib.Getter()
|
||||
else
|
||||
S = function(s, a, ...) a = {a, ...}
|
||||
return s:gsub("@(%d+)", function(n)
|
||||
return a[tonumber(n)]
|
||||
end)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
local dist = tonumber(minetest.setting_get("map_generation_limit") or 31000)
|
||||
|
||||
|
||||
dofile(minetest.get_modpath("hyperloop") .. "/utils.lua")
|
||||
dofile(minetest.get_modpath("hyperloop") .. "/door.lua")
|
||||
dofile(minetest.get_modpath("hyperloop") .. "/tubes.lua")
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function enter_display(pos, text)
|
||||
-- Use LCD from digilines. TODO: Own display
|
||||
local node = minetest.get_node(pos)
|
||||
local spec = digilines.getspec(node)
|
||||
if spec then
|
||||
-- Effector actions --> Receive
|
||||
if spec.effector then
|
||||
spec.effector.action(pos, node, "lcd", text)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function check_coordinates(str)
|
||||
-- obsolete?
|
||||
if not str or str == "" then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- get coords from string
|
||||
local x, y, z, desc = string.match(str, "^(-?%d+),(-?%d+),(-?%d+),?(.*)$")
|
||||
|
||||
-- check coords
|
||||
if x == nil or string.len(x) > 6
|
||||
or y == nil or string.len(y) > 6
|
||||
or z == nil or string.len(z) > 6 then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- convert string coords to numbers
|
||||
x = tonumber(x)
|
||||
y = tonumber(y)
|
||||
z = tonumber(z)
|
||||
|
||||
-- are coords in map range ?
|
||||
if x > dist or x < -dist
|
||||
or y > dist or y < -dist
|
||||
or z > dist or z < -dist then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- return ok coords
|
||||
return {x = x, y = y, z = z, desc = desc}
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
-- seat_pos: position of the seat
|
||||
-- facedir: direction to the display
|
||||
-- cmnd: "close", "open", or "animate"
|
||||
local function door_command(seat_pos, facedir, cmnd)
|
||||
-- one step forward
|
||||
local lcd_pos = vector.add(seat_pos, facedir2dir(facedir))
|
||||
-- one step left
|
||||
local door_pos1 = vector.add(lcd_pos, facedir2dir(facedir + 1))
|
||||
-- one step up
|
||||
local door_pos2 = vector.add(door_pos1, {x=0, y=1, z=0})
|
||||
|
||||
local node1 = minetest.get_node(door_pos1)
|
||||
local node2 = minetest.get_node(door_pos2)
|
||||
|
||||
-- switch from the radian following facedir to the silly original one
|
||||
local tbl = {[0]=0, [1]=3, [2]=2, [3]=1}
|
||||
facedir = (facedir + 3) % 4 -- first turn left
|
||||
facedir = tbl[facedir]
|
||||
|
||||
if cmnd == "open" then
|
||||
node1.name = "air"
|
||||
minetest.swap_node(door_pos1, node1)
|
||||
node2.name = "air"
|
||||
minetest.swap_node(door_pos2, node2)
|
||||
elseif cmnd == "close" then
|
||||
node1.name = "hyperloop:doorBottom"
|
||||
node1.param2 = facedir
|
||||
minetest.swap_node(door_pos1, node1)
|
||||
node2.name = "hyperloop:doorTopPassive"
|
||||
node2.param2 = facedir
|
||||
minetest.swap_node(door_pos2, node2)
|
||||
elseif cmnd == "animate" then
|
||||
node2.name = "hyperloop:doorTopActive"
|
||||
node2.param2 = facedir
|
||||
minetest.swap_node(door_pos2, node2)
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function on_open_door(pos, facedir)
|
||||
-- open the door and play sound
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("arrival_time", 0) -- finished
|
||||
|
||||
-- open the door
|
||||
minetest.sound_play("door", {
|
||||
pos = pos,
|
||||
gain = 0.5,
|
||||
max_hear_distance = 10,
|
||||
})
|
||||
door_command(pos, facedir, "open")
|
||||
|
||||
-- prepare dislay for the next trip
|
||||
local text = "We will start | in a few | seconds"
|
||||
enter_display(lcd_pos, text)
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function on_arrival(player, src_pos, dst_pos, snd, radiant)
|
||||
-- open the door an the departure station
|
||||
local meta = minetest.get_meta(src_pos)
|
||||
local facedir = meta:get_int("facedir")
|
||||
door_command(src_pos, facedir, "open")
|
||||
|
||||
-- get coords from arrival station
|
||||
meta = minetest.get_meta(dst_pos)
|
||||
facedir = meta:get_int("facedir")
|
||||
--print("on_arrival "..dump(dst_pos))----------------------------------------------
|
||||
|
||||
-- close the door at arrival station
|
||||
door_command(dst_pos, facedir, "close")
|
||||
|
||||
-- move player to the arrival station
|
||||
player:setpos(dst_pos)
|
||||
-- rotate player to look in correct arrival direction
|
||||
-- calculate the look correction
|
||||
local offs = radiant - player:get_look_horizontal()
|
||||
local yaw = facedir2rad(facedir) + offs
|
||||
player:set_look_yaw(yaw)
|
||||
|
||||
-- play arrival sound
|
||||
minetest.sound_stop(snd)
|
||||
minetest.sound_play("down", {
|
||||
pos = dst_pos,
|
||||
gain = 1.0,
|
||||
max_hear_distance = 10
|
||||
})
|
||||
-- activate display
|
||||
local lcd_pos = vector.add(dst_pos, facedir2dir(facedir))
|
||||
lcd_pos.y = lcd_pos.y + 1
|
||||
--print("LCD "..dump(pos)..dump(lcd_pos))
|
||||
local text = "Wellcome in | | Hauptstadt"
|
||||
enter_display(lcd_pos, text)
|
||||
|
||||
minetest.after(6.0, on_open_door, dst_pos, facedir)
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function on_travel(src_pos, facedir, player, dst_pos, radiant)
|
||||
-- play sound and switch door state
|
||||
-- radiant is the player look direction at departure
|
||||
local snd = minetest.sound_play("normal", {
|
||||
pos = src_pos,
|
||||
gain = 1.0,
|
||||
max_hear_distance = 1,
|
||||
loop = true,
|
||||
})
|
||||
door_command(src_pos, facedir, "animate")
|
||||
minetest.after(6.0, on_arrival, player, src_pos, dst_pos, snd, radiant)
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function display_timer(pos, elapsed)
|
||||
-- update display with trip data
|
||||
local meta = minetest.get_meta(pos)
|
||||
local atime = meta:get_int("arrival_time") - 1
|
||||
meta:set_int("arrival_time", atime)
|
||||
local lcd_pos = minetest.string_to_pos(meta:get_string("lcd_pos"))
|
||||
local text = meta:get_string("lcd_text")
|
||||
if atime > 0 then
|
||||
enter_display(lcd_pos, text..atime.." sec")
|
||||
return true
|
||||
else
|
||||
enter_display(lcd_pos, "We will start | in a view | minutes..")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------------------------
|
||||
local function on_start_travel(pos, node, clicker)
|
||||
-- place the player, close the door, activate display
|
||||
local meta = minetest.get_meta(pos)
|
||||
local facedir = meta:get_int("facedir")
|
||||
if meta:get_int("arrival_time") ~= 0 then
|
||||
return
|
||||
end
|
||||
local target_coords = {
|
||||
x = meta:get_int("x"),
|
||||
y = meta:get_int("y"),
|
||||
z = meta:get_int("z")
|
||||
}
|
||||
|
||||
minetest.sound_play("up", {
|
||||
pos = pos,
|
||||
gain = 1.0,
|
||||
max_hear_distance = 10
|
||||
})
|
||||
-- place player on the seat
|
||||
clicker:setpos(pos)
|
||||
-- rotate player to look in move direction
|
||||
clicker:set_look_horizontal(facedir2rad(facedir))
|
||||
|
||||
-- activate display
|
||||
local lcd_pos = vector.add(pos, facedir2dir(facedir))
|
||||
lcd_pos.y = lcd_pos.y + 1
|
||||
--print("LCD "..dump(pos)..dump(lcd_pos))
|
||||
local text = "Next stop: | Hauptstadt | Dist: 2.2km | Arrival in: | "
|
||||
local atime = 15
|
||||
enter_display(lcd_pos, text..atime.." sec")
|
||||
|
||||
-- store some data
|
||||
meta:set_int("arrival_time", atime)
|
||||
meta:set_string("lcd_pos", minetest.pos_to_string(lcd_pos))
|
||||
meta:set_string("lcd_text", text)
|
||||
meta:set_string("lcd_text", text)
|
||||
minetest.get_node_timer(pos):start(1.0)
|
||||
|
||||
--print("on_rightclick "..dump(pos))----------------------------------------------
|
||||
|
||||
-- close the door
|
||||
minetest.sound_play("door", {
|
||||
pos = pos,
|
||||
gain = 0.5,
|
||||
max_hear_distance = 10,
|
||||
})
|
||||
door_command(pos, facedir, "close")
|
||||
|
||||
minetest.after(4.9, on_travel, pos, facedir, clicker, target_coords, facedir2rad(facedir))
|
||||
end
|
||||
|
||||
-- Hyperloop Seat
|
||||
minetest.register_node("hyperloop:seat", {
|
||||
tiles = {
|
||||
"seat-top.png",
|
||||
"seat-side.png",
|
||||
"seat-side.png",
|
||||
"seat-side.png",
|
||||
"seat-side.png",
|
||||
"seat-side.png",
|
||||
},
|
||||
drawtype = "nodebox",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
walkable = false,
|
||||
--description = S("Hyperloop Pad (place and right-click to enchant location)"),
|
||||
groups = {snappy = 3},
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -6/16, -8/16, -8/16, 6/16, -2/16, 5/16},
|
||||
{ -8/16, -8/16, -8/16, -6/16, 4/16, 8/16},
|
||||
{ 6/16, -8/16, -8/16, 8/16, 4/16, 8/16},
|
||||
{ -6/16, -8/16, 4/16, 6/16, 6/16, 8/16},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = { -8/16, -8/16, -8/16, 8/16, -2/16, 8/16 },
|
||||
},
|
||||
|
||||
on_timer = display_timer,
|
||||
|
||||
on_construct = function(pos)
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
-- text entry formspec
|
||||
meta:set_string("formspec", "field[text;" .. S("Enter teleport coords (e.g. 200,20,-200,Home)") .. ";${text}]")
|
||||
meta:set_string("infotext", S("Right-click to enchant teleport location"))
|
||||
meta:set_string("text", pos.x .. "," .. pos.y .. "," .. pos.z)
|
||||
meta:set_int("arrival_time", 0)
|
||||
|
||||
-- set default coords
|
||||
meta:set_int("x", pos.x)
|
||||
meta:set_int("y", pos.y)
|
||||
meta:set_int("z", pos.z)
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local yaw = placer:get_look_horizontal()
|
||||
-- facedir according to radiant
|
||||
local facedir = rad2facedir(yaw)
|
||||
-- do a 180 degree correction
|
||||
meta:set_int("facedir", (facedir + 2) % 4)
|
||||
print("on_construct "..dump(pos))----------------------------------------------
|
||||
end,
|
||||
|
||||
-- once entered, check coords, if ok then return potion
|
||||
on_receive_fields = function(pos, formname, fields, sender)
|
||||
|
||||
local name = sender:get_player_name()
|
||||
|
||||
if minetest.is_protected(pos, name) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return
|
||||
end
|
||||
|
||||
local coords = check_coordinates(fields.text)
|
||||
|
||||
if coords then
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
print("on_receive_fields "..dump(pos))----------------------------------------------
|
||||
|
||||
meta:set_int("x", coords.x)
|
||||
meta:set_int("y", coords.y)
|
||||
meta:set_int("z", coords.z)
|
||||
meta:set_string("text", fields.text)
|
||||
|
||||
if coords.desc and coords.desc ~= "" then
|
||||
|
||||
meta:set_string("infotext", S("Teleport to @1", coords.desc))
|
||||
else
|
||||
meta:set_string("infotext", S("Pad Active (@1,@2,@3)",
|
||||
coords.x, coords.y, coords.z))
|
||||
end
|
||||
-- delete formspec so that right-click will work
|
||||
meta:set_string("formspec", nil)
|
||||
else
|
||||
minetest.chat_send_player(name, S("Teleport Pad coordinates failed!"))
|
||||
end
|
||||
end,
|
||||
|
||||
on_rightclick = on_start_travel,
|
||||
})
|
||||
dofile(minetest.get_modpath("hyperloop") .. "/order.lua")
|
||||
dofile(minetest.get_modpath("hyperloop") .. "/station.lua")
|
||||
dofile(minetest.get_modpath("hyperloop") .. "/door.lua")
|
||||
dofile(minetest.get_modpath("hyperloop") .. "/seat.lua")
|
||||
|
||||
print ("[MOD] Hyperloop loaded")
|
||||
|
56
order.lua
56
order.lua
@ -20,23 +20,22 @@ local function final_formspec(name)
|
||||
if stations == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
local tRes = {"size[10,9]label[3,0;Wähle dein Ziel / Select your destination]"}
|
||||
table.sort(stations)
|
||||
local tRes = {"size[10,9]label[2,0; Abfahrt ".. name ..": Wähle dein Ziel\nDeparture ".. name .. ": Select your destination]"}
|
||||
for idx,s in ipairs(stations) do
|
||||
if idx < 9 then
|
||||
pos1 = "0,"..idx
|
||||
pos2 = "3,"..idx
|
||||
pos2 = "1,"..idx
|
||||
else
|
||||
pos1 = "6,"..(idx-8)
|
||||
pos2 = "9,"..(idx-8)
|
||||
pos1 = "5,"..(idx-8)
|
||||
pos2 = "6,"..(idx-8)
|
||||
end
|
||||
tRes[#tRes + 1] = "label["..pos1..".2;"..s.."]"
|
||||
tRes[#tRes + 1] = "button_exit["..pos2..";1,1;h;X]"
|
||||
tRes[#tRes + 1] = "button_exit["..pos1..";1,1;button;"..idx.."]"
|
||||
tRes[#tRes + 1] = "label["..pos2..".2;"..s.."]"
|
||||
end
|
||||
return table.concat(tRes)
|
||||
end
|
||||
|
||||
|
||||
minetest.register_node("hyperloop:order", {
|
||||
description = "Hyperloop Order Machine",
|
||||
tiles = {
|
||||
@ -61,35 +60,44 @@ minetest.register_node("hyperloop:order", {
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if fields.name ~= nil then
|
||||
local station_name = fields.name
|
||||
print(station_name)
|
||||
meta:set_string("station_name", station_name)
|
||||
local s = final_formspec(station_name)
|
||||
if s == nil then
|
||||
if hyperloop.tAllStations ~= nil and hyperloop.tAllStations[fields.name] ~= nil then
|
||||
local station_pos = minetest.string_to_pos(hyperloop.tAllStations[fields.name].pos)
|
||||
if hyperloop.distance(pos, station_pos) > 30 then
|
||||
minetest.chat_send_player(player:get_player_name(), "Error: station too far away!")
|
||||
return
|
||||
end
|
||||
hyperloop.tAllStations[fields.name]["automat_pos"] = pos
|
||||
meta:set_string("station_name", fields.name)
|
||||
meta:set_string("infotext", "Station: "..fields.name)
|
||||
meta:set_string("formspec", final_formspec(fields.name))
|
||||
else
|
||||
minetest.chat_send_player(player:get_player_name(), "Error: Invalid station name!")
|
||||
else
|
||||
meta:set_string("formspec", s)
|
||||
if hyperloop.tAllStations ~= nil and hyperloop.tAllStations[station_name] ~= nil then
|
||||
local tmp = hyperloop.tAllStations[station_name]["pos"]
|
||||
hyperloop.tAllStations[station_name]["order"] = pos
|
||||
meta:set_string("station_pos", tmp)
|
||||
end
|
||||
end
|
||||
else
|
||||
elseif fields.button ~= nil then
|
||||
local station_name = meta:get_string("station_name")
|
||||
local stations = hyperloop.get_stations(table.copy(hyperloop.tAllStations), station_name, {})
|
||||
table.sort(stations)
|
||||
-- place order
|
||||
local idx = tonumber(fields.button)
|
||||
print(station_name .. ":" .. stations[idx])
|
||||
hyperloop.order[station_name] = stations[idx]
|
||||
end
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local station_name = meta:get_string("station_name")
|
||||
hyperloop.tAllStations[station_name]["order"] = nil
|
||||
if hyperloop.tAllStations ~= nil and hyperloop.tAllStations[station_name.name] ~= nil
|
||||
and hyperloop.tAllStations[station_name.name]["automat_pos"] ~= nil then
|
||||
hyperloop.tAllStations[station_name]["automat_pos"] = nil
|
||||
end
|
||||
end,
|
||||
|
||||
on_punch = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local station_name = meta:get_string("station_name")
|
||||
local s = final_formspec(station_name)
|
||||
meta:set_string("formspec", s)
|
||||
meta:set_string("infotext", "Station: "..station_name)
|
||||
meta:set_string("formspec", final_formspec(station_name))
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
|
191
station.lua
191
station.lua
@ -1,84 +1,145 @@
|
||||
-- We need:
|
||||
-- * tube_power0, can be placed and docked by a tube
|
||||
-- * tube_power1, can be docked by a second tube
|
||||
-- * tube_power2, can't be docked by a third tube
|
||||
for idx = 0,2 do
|
||||
local img
|
||||
if idx < 2 then
|
||||
img = "hyperloop_power_tube_green.png"
|
||||
else
|
||||
img = "hyperloop_power_tube_red.png"
|
||||
--[[
|
||||
|
||||
Hyperloop Mod
|
||||
=============
|
||||
|
||||
Copyright (C) 2017 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
History:
|
||||
see init.lua
|
||||
|
||||
]]--
|
||||
|
||||
local function store_routes(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local station_name = meta:get_string("station_name")
|
||||
print("station_name="..station_name)
|
||||
if station_name ~= nil and station_name ~= "" then
|
||||
local res, nodes = hyperloop.scan_neighbours(pos)
|
||||
-- generate a list with all tube heads
|
||||
local tRoutes = {}
|
||||
for _,node in ipairs(nodes) do
|
||||
print(node.name)
|
||||
if node.name == "hyperloop:tube1" then
|
||||
local meta = minetest.get_meta(node.pos)
|
||||
local route = {meta:get_string("local"), meta:get_string("remote")}
|
||||
--print(dump(route))
|
||||
table.insert(tRoutes, route)
|
||||
end
|
||||
minetest.register_node("hyperloop:tube_power"..idx, {
|
||||
description = "Hyperloop Power Tube",
|
||||
tiles = {
|
||||
{
|
||||
name = img,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
end
|
||||
-- store list
|
||||
local spos = minetest.pos_to_string(pos)
|
||||
hyperloop.tAllStations[station_name] = {pos=spos, routes=tRoutes}
|
||||
end
|
||||
end
|
||||
|
||||
local function punch_all_stations()
|
||||
for _, item in pairs(hyperloop.tAllStations) do
|
||||
minetest.punch_node(minetest.string_to_pos(item.pos))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
minetest.register_node("hyperloop:junction", {
|
||||
description = "Hyperloop Junction Block",
|
||||
tiles = {"hyperloop_station.png"},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
local nodes = scan_tube_neighbours(pos, true, {"hyperloop:tube_head", "hyperloop:tube_power1"})
|
||||
-- power node can't be placed nearby another power node
|
||||
for _,node in ipairs(nodes) do
|
||||
if node.name == "hyperloop:tube_power0" or node.name == "hyperloop:tube_power1" then
|
||||
-- remove node again
|
||||
minetest.chat_send_player(placer:get_player_name(), "Power Tube block can't be placed here.")
|
||||
minetest.remove_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local formspec = "size[5,4]"..
|
||||
"label[0,0;Please insert station name]" ..
|
||||
"field[1,1.5;3,1;name;Name;MyTown]" ..
|
||||
"button_exit[1,2;2,1;exit;Save]"
|
||||
meta:set_string("formspec", formspec)
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
if fields.name == nil then
|
||||
return
|
||||
end
|
||||
local station_name = string.trim(fields.name)
|
||||
if station_name == "" then
|
||||
return
|
||||
end
|
||||
-- check if station already available
|
||||
local spos = minetest.pos_to_string(pos)
|
||||
if hyperloop.tAllStations[station_name] ~= nil and hyperloop.tAllStations[station_name]["pos"] ~= spos then
|
||||
minetest.chat_send_player(player:get_player_name(), "Error: Station name already assigned!")
|
||||
return
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local station_name = meta:get_string("station") or "<unknown>"
|
||||
local ring_addr
|
||||
if #nodes == 0 then -- are we the one and only?
|
||||
--print("start ring")----------------------
|
||||
-- a new ring starts here
|
||||
ring_addr = determine_ring_addr(pos)
|
||||
else
|
||||
--print("degrade to tubes")----------------------
|
||||
-- degrade neighbor nodes
|
||||
swap_to_tube(pos, placer, nodes)
|
||||
ring_addr = meta:get_string("ring_addr")
|
||||
meta:set_string("formspec", nil)
|
||||
meta:set_string("station_name", station_name)
|
||||
meta:set_string("infotext", "Station '"..station_name.."'")
|
||||
store_routes(pos)
|
||||
-- update routes in station list
|
||||
--punch_all_stations() --????????????????????????????????????????????
|
||||
end,
|
||||
|
||||
-- already connected with two tube nodes?
|
||||
if #nodes == 2 then
|
||||
--print("switch to tube_power1")----------------------
|
||||
-- tube_power1 cant be docked by a third tube
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = "hyperloop:tube_power1"
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
end
|
||||
meta:set_string("infotext", "Power Tube block "..idx..". ring at: "..ring_addr.." Station Name: "..station_name)
|
||||
-- store ring_addr in ring list
|
||||
if hyperloop.ringList[ring_addr] ~= nil then
|
||||
table.insert(hyperloop.ringList[ring_addr], pos)
|
||||
else
|
||||
hyperloop.ringList[ring_addr] = {pos}
|
||||
end
|
||||
--print("store ring_addr in ring list")-------------------------------------
|
||||
--hyperloop.dbg_ringlist()------------------------------------------
|
||||
on_punch = function(pos)
|
||||
print("Junction punched")
|
||||
store_routes(pos)
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
local nodes = scan_tube_neighbours(pos, true, {"hyperloop:tube"})
|
||||
-- upgrade neighbor nodes
|
||||
swap_to_tube_head(pos, nodes)
|
||||
-- delete station data
|
||||
local meta = minetest.get_meta(pos)
|
||||
local station_name = meta:get_string("station_name")
|
||||
if hyperloop.tAllStations[station_name] ~= nil then
|
||||
hyperloop.tAllStations[station_name] = nil
|
||||
end
|
||||
-- update routes in station list
|
||||
--punch_all_stations()
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, not_in_creative_inventory=idx},
|
||||
groups = {cracky=2},
|
||||
is_ground_content = false,
|
||||
drop = "hyperloop:tube_power0",
|
||||
})
|
||||
|
||||
|
||||
-- to build the pod
|
||||
minetest.register_node("hyperloop:pod_wall", {
|
||||
description = "Hyperloop Pod Wall",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"hyperloop_skin.png^[transformR90]",
|
||||
"hyperloop_skin.png^[transformR90]",
|
||||
"hyperloop_skin.png",
|
||||
"hyperloop_skin.png",
|
||||
"hyperloop_skin.png",
|
||||
"hyperloop_skin.png",
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=1},
|
||||
is_ground_content = false,
|
||||
})
|
||||
|
||||
|
||||
local function book_on_use(itemstack, user)
|
||||
local player_name = user:get_player_name()
|
||||
local pos = user:get_pos()
|
||||
local sStationList = hyperloop.get_stations_as_string(pos)
|
||||
local formspec = "size[8,8]" .. default.gui_bg ..
|
||||
default.gui_bg_img ..
|
||||
"textarea[0.5,0.5;7.5,8;text;Station List:;" ..
|
||||
sStationList .. "]" ..
|
||||
"button_exit[2.5,7.5;3,1;close;Close]"
|
||||
|
||||
minetest.show_formspec(player_name, "default:book", formspec)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- Tool for tube workers to find the next station
|
||||
minetest.register_node(":hyperloop:station_map", {
|
||||
description = "Hyperloop Station Map",
|
||||
inventory_image = "hyperloop_stations_book.png",
|
||||
wield_image = "hyperloop_stations_book.png",
|
||||
groups = {cracky=1, book=1},
|
||||
on_use = book_on_use,
|
||||
on_place = book_on_use,
|
||||
})
|
||||
|
||||
|
1
test.lua
1
test.lua
@ -165,6 +165,7 @@ res = hyperloop.get_stations(table.copy(hyperloop.tAllStations), "Düsseldorf",
|
||||
|
||||
local function final_formspec(name)
|
||||
local stations = hyperloop.get_stations(table.copy(hyperloop.tAllStations), name, {})
|
||||
table.sort(stations)
|
||||
local tRes = {"size[10,9]label[3,0;Wähle dein Ziel / Select your destination]"}
|
||||
for idx,s in ipairs(stations) do
|
||||
if idx < 9 then
|
||||
|
76
tubes.lua
76
tubes.lua
@ -13,7 +13,7 @@
|
||||
|
||||
]]--
|
||||
|
||||
local function scan_neighbours(pos)
|
||||
-- Block arrangement: [0] [1][2][1] [S][1][2][2][1][S]
|
||||
-- Scan all 8 neighbor positions for tube nodes.
|
||||
-- Return:
|
||||
-- 0, nodes - no node available
|
||||
@ -21,6 +21,7 @@ local function scan_neighbours(pos)
|
||||
-- 3, nodes - two tube1 available
|
||||
-- 4, nodes - one tube2 available
|
||||
-- 5, nodes - invalid position
|
||||
function hyperloop.scan_neighbours(pos)
|
||||
local nodes = {}
|
||||
local node, npos, idx
|
||||
local res = 0
|
||||
@ -37,16 +38,17 @@ local function scan_neighbours(pos)
|
||||
return 4, nodes
|
||||
end
|
||||
res = res * 2 + idx
|
||||
end
|
||||
end
|
||||
if res > 3 then
|
||||
return 5, nodes
|
||||
end
|
||||
end
|
||||
res = 5
|
||||
end
|
||||
return res, nodes
|
||||
end
|
||||
|
||||
-- Degrade one node.
|
||||
-- Needed when a new node is placed nearby.
|
||||
local function degrade_tupe_node(node)
|
||||
print("degrade_tupe_node"..node.name)
|
||||
if node.name == "hyperloop:tube0" then
|
||||
node.name = "hyperloop:tube1"
|
||||
elseif node.name == "hyperloop:tube1" then
|
||||
@ -58,9 +60,9 @@ local function degrade_tupe_node(node)
|
||||
minetest.swap_node(node.pos, node)
|
||||
end
|
||||
|
||||
local function upgrade_node(pos, node)
|
||||
-- Upgrade one node.
|
||||
-- Is needed when a tube node is digged.
|
||||
-- Needed when a tube node is digged.
|
||||
local function upgrade_node(pos, node)
|
||||
local meta_local = minetest.get_meta(pos)
|
||||
local meta_head = minetest.get_meta(node.pos)
|
||||
meta_head:set_string("other", meta_local:get_string("other"))
|
||||
@ -74,6 +76,7 @@ local function upgrade_node(pos, node)
|
||||
minetest.swap_node(node.pos, node)
|
||||
end
|
||||
|
||||
-- Place a node without neighbours
|
||||
local function starter_node(node)
|
||||
local meta = minetest.get_meta(node.pos)
|
||||
meta:set_string("local", minetest.pos_to_string(node.pos))
|
||||
@ -83,6 +86,7 @@ local function starter_node(node)
|
||||
minetest.swap_node(node.pos, node)
|
||||
end
|
||||
|
||||
-- Place a node with one neighbor
|
||||
local function head_node(node, node1)
|
||||
local meta_local = minetest.get_meta(node.pos)
|
||||
local meta_head = minetest.get_meta(node1.pos)
|
||||
@ -93,6 +97,9 @@ local function head_node(node, node1)
|
||||
local rpos = minetest.string_to_pos(meta_head:get_string("remote"))
|
||||
local rmeta = minetest.get_meta(rpos)
|
||||
rmeta:set_string("remote", minetest.pos_to_string(node.pos))
|
||||
print("rmeta:get_string(remote) = " .. rmeta:get_string("remote"))
|
||||
-- punch remote node
|
||||
minetest.punch_node(rpos)
|
||||
-- upgrade self
|
||||
node.name = "hyperloop:tube1"
|
||||
minetest.swap_node(node.pos, node)
|
||||
@ -111,6 +118,9 @@ local function link_node(node, node1, node2)
|
||||
-- exchange position data
|
||||
meta_rmt2:set_string("remote", meta_rmt1:get_string("local"))
|
||||
meta_rmt1:set_string("remote", meta_rmt2:get_string("local"))
|
||||
-- punch remote nodes
|
||||
minetest.punch_node(pos1)
|
||||
minetest.punch_node(pos2)
|
||||
-- set to tube2
|
||||
node.name = "hyperloop:tube2"
|
||||
node.diggable = true
|
||||
@ -129,10 +139,10 @@ end
|
||||
|
||||
-- simple tube without logic or "memory"
|
||||
minetest.register_node("hyperloop:tube2", {
|
||||
description = "Hyperloop Tube 2",
|
||||
description = "Hyperloop Tube",
|
||||
tiles = {
|
||||
{
|
||||
name = "hyperloop_tube_red.png",
|
||||
name = "hyperloop_tube_locked.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
@ -151,52 +161,58 @@ minetest.register_node("hyperloop:tube2", {
|
||||
-- single-node and head-node with meta info about the counter part node
|
||||
for idx = 0,1 do
|
||||
minetest.register_node("hyperloop:tube"..idx, {
|
||||
description = "Hyperloop Tube "..idx,
|
||||
description = "Hyperloop Tube",
|
||||
inventory_image = "hyperloop_tube_inventury.png",
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
{
|
||||
name = "hyperloop_tube_green.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
-- up, down, right, left, back, front
|
||||
'hyperloop_tube_closed.png',
|
||||
'hyperloop_tube_closed.png',
|
||||
'hyperloop_tube_closed.png',
|
||||
'hyperloop_tube_closed.png',
|
||||
'hyperloop_tube_open.png',
|
||||
'hyperloop_tube_open.png',
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
local res, nodes = scan_neighbours(pos)
|
||||
minetest.chat_send_player(placer:get_player_name(), "res="..res)
|
||||
local res, nodes = hyperloop.scan_neighbours(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
node.pos = pos
|
||||
hyperloop.dbg_nodes(nodes)-------------------------------------
|
||||
if res == 0 then -- no neighbor available?
|
||||
starter_node(node)
|
||||
elseif res == 1 then -- one neighbor available?
|
||||
head_node(node, nodes[1])
|
||||
elseif res == 3 then -- two neighbours available?
|
||||
minetest.chat_send_player(placer:get_player_name(), "two neighbours")
|
||||
--minetest.chat_send_player(placer:get_player_name(), "two neighbours")
|
||||
link_node(node, nodes[1], nodes[2])
|
||||
else -- invalid position
|
||||
minetest.chat_send_player(placer:get_player_name(), "Invalid tube block position")
|
||||
minetest.chat_send_player(placer:get_player_name(), "Error: Invalid tube block position!")
|
||||
remove_node(pos, node)
|
||||
return itemstack
|
||||
end
|
||||
-- for debugging purposes
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", meta:get_string("local").." => "..meta:get_string("remote"))
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
print("on_destruct")------------------------------
|
||||
local res, nodes = scan_neighbours(pos)
|
||||
print("res="..res.." nodes="..dump(nodes))------------------------------
|
||||
local res, nodes = hyperloop.scan_neighbours(pos)
|
||||
if res == 4 then
|
||||
upgrade_node(pos, nodes[1])
|
||||
end
|
||||
end,
|
||||
|
||||
-- wake up station node so that it updates its dataset
|
||||
on_punch = function(pos, node, puncher, pointed_thing)
|
||||
print("Tube punched")
|
||||
local res, nodes = hyperloop.scan_for_nodes(pos, "hyperloop:junction")
|
||||
for _,node in ipairs(nodes) do
|
||||
print(dump(node.pos))
|
||||
minetest.punch_node(node.pos)
|
||||
-- for debugging purposes
|
||||
local meta = minetest.get_meta(pos)
|
||||
loc = meta:get_string("local")
|
||||
rmt = meta:get_string("remote")
|
||||
minetest.chat_send_player(puncher:get_player_name(), "local="..loc.." remote="..rmt)
|
||||
meta:set_string("infotext", meta:get_string("local").." => "..meta:get_string("remote"))
|
||||
end
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
|
133
utils.lua
133
utils.lua
@ -15,6 +15,16 @@
|
||||
|
||||
local PI = 3.1415926
|
||||
|
||||
function table_extend(table1, table2)
|
||||
for k,v in pairs(table2) do
|
||||
if (type(table1[k]) == 'table' and type(v) == 'table') then
|
||||
table_extend(table1[k], v)
|
||||
else
|
||||
table1[k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hyperloop.NeighborPos = {
|
||||
{ x=1, y=0, z=0},
|
||||
{ x=-1, y=0, z=0},
|
||||
@ -73,19 +83,15 @@ function hyperloop.table2file(filename, table)
|
||||
f:close()
|
||||
end
|
||||
|
||||
function hyperloop.store_ring_list()
|
||||
hyperloop.table2file("hyperloop_ringlist", hyperloop.ringList)
|
||||
function hyperloop.store_station_list()
|
||||
hyperloop.table2file("hyperloop_station_list", hyperloop.tAllStations)
|
||||
end
|
||||
|
||||
|
||||
function hyperloop.dbg_ringlist()
|
||||
print("RingList:")
|
||||
print(dump(hyperloop.ringList))-------------------------------------------
|
||||
for addr,list in ipairs(hyperloop.ringList) do
|
||||
for idx, pos in ipairs(list) do
|
||||
print("addr:"..addr.." idx:"..idx.." pos:"..minetest.pos_to_string(pos))
|
||||
end
|
||||
end
|
||||
-- distance between two points in (tube) blocks
|
||||
function hyperloop.distance(pos1, pos2)
|
||||
pos1 = vector.floor(pos1)
|
||||
pos2 = vector.floor(pos2)
|
||||
return math.abs(pos1.x - pos2.x) + math.abs(pos1.y - pos2.y) + math.abs(pos1.z - pos2.z)
|
||||
end
|
||||
|
||||
function hyperloop.dbg_nodes(nodes)
|
||||
@ -95,13 +101,112 @@ function hyperloop.dbg_nodes(nodes)
|
||||
end
|
||||
end
|
||||
|
||||
-- Return true if both blocks given bei string-positions are nearby
|
||||
function hyperloop.nearby(pos1, pos2)
|
||||
pos1 = minetest.string_to_pos(pos1)
|
||||
pos2 = minetest.string_to_pos(pos2)
|
||||
local pos = vector.subtract(pos1, pos2)
|
||||
local res = pos.x + pos.y + pos.z
|
||||
return res == 1 or res == -1
|
||||
end
|
||||
|
||||
-- Scan for nodes with the given name in the surrounding
|
||||
function hyperloop.scan_for_nodes(pos, name)
|
||||
local nodes = {}
|
||||
local node, npos
|
||||
local res = 0
|
||||
for _,dir in ipairs(hyperloop.NeighborPos) do
|
||||
npos = vector.add(pos, dir)
|
||||
node = minetest.get_node(npos)
|
||||
if node.name == name then
|
||||
node.pos = npos
|
||||
table.insert(nodes, node)
|
||||
res = res + 1
|
||||
end
|
||||
end
|
||||
return res, nodes
|
||||
end
|
||||
|
||||
-- Return station name, which matches the given retoure route
|
||||
function hyperloop.get_station(tStations, rev_route)
|
||||
for station,dataSet in pairs(tStations) do
|
||||
print(station)
|
||||
for _,route in ipairs(dataSet["routes"]) do
|
||||
print("get_station "..rev_route[1].." "..route[1].." "..rev_route[2].." "..route[2])
|
||||
if rev_route[1] == route[1] and rev_route[2] == route[2] then
|
||||
return station
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Return a table with all station names, the given 'sStation' is connected with
|
||||
-- tRes is used for the resulting table (recursive call)
|
||||
function hyperloop.get_stations(tStations, sStation, tRes)
|
||||
if tStations[sStation] == nil then
|
||||
return nil
|
||||
end
|
||||
local dataSet = table.copy(tStations[sStation])
|
||||
if dataSet == nil then
|
||||
return nil
|
||||
end
|
||||
tStations[sStation] = nil
|
||||
for _,route in ipairs(dataSet["routes"]) do
|
||||
local rev_route = {route[2], route[1]}
|
||||
local s = hyperloop.get_station(tStations, rev_route)
|
||||
if s ~= nil then
|
||||
tRes[#tRes + 1] = s
|
||||
hyperloop.get_stations(tStations, s, tRes)
|
||||
end
|
||||
end
|
||||
return tRes
|
||||
end
|
||||
|
||||
-- Return a text block with all station names and their direct connections
|
||||
function hyperloop.get_stations_as_string(pos)
|
||||
local sortedList = {}
|
||||
local distance = 0
|
||||
for name, dataSet in pairs(table.copy(hyperloop.tAllStations)) do
|
||||
distance = hyperloop.distance(pos, minetest.string_to_pos(dataSet["pos"]))
|
||||
dataSet.name = name
|
||||
dataSet.distance = distance
|
||||
sortedList[#sortedList+1] = dataSet
|
||||
end
|
||||
table.sort(sortedList, function(x,y)
|
||||
return x.distance < y.distance
|
||||
end)
|
||||
print(dump(sortedList))
|
||||
local tRes = {"(player distance: station name (position) => directly connected with)\n\n"}
|
||||
for _,dataSet in ipairs(sortedList) do
|
||||
|
||||
tRes[#tRes+1] = dataSet.distance
|
||||
tRes[#tRes+1] = ": "
|
||||
tRes[#tRes+1] = dataSet.name
|
||||
tRes[#tRes+1] = " "
|
||||
tRes[#tRes+1] = dataSet.pos
|
||||
tRes[#tRes+1] = " => "
|
||||
for _,route in ipairs(dataSet["routes"]) do
|
||||
local rev_route = {route[2], route[1]}
|
||||
local s = hyperloop.get_station(hyperloop.tAllStations, rev_route)
|
||||
if s ~= nil then
|
||||
tRes[#tRes + 1] = s
|
||||
tRes[#tRes + 1] = ", "
|
||||
end
|
||||
end
|
||||
tRes[#tRes] = "\n"
|
||||
end
|
||||
return table.concat(tRes)
|
||||
end
|
||||
|
||||
-- Store and read the RingList to / from a file
|
||||
-- so that upcoming actions are remembered when the game
|
||||
-- is restarted
|
||||
hyperloop.ringList = hyperloop.file2table("hyperloop_ringlist")
|
||||
hyperloop.tAllStations = hyperloop.file2table("hyperloop_station_list")
|
||||
|
||||
minetest.register_on_shutdown(hyperloop.store_ring_list)
|
||||
minetest.register_on_shutdown(hyperloop.store_station_list)
|
||||
|
||||
-- store ring list once a day
|
||||
minetest.after(60*60*24, hyperloop.store_ring_list)
|
||||
minetest.after(60*60*24, hyperloop.store_station_list)
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user