hyperloop/migrate.lua
2018-11-03 19:08:54 +01:00

241 lines
5.8 KiB
Lua

--[[
Hyperloop Mod
=============
Copyright (C) 2017 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
History:
see init.lua
Migrate from v1 to v2
]]--
-- for lazy programmers
local S = minetest.pos_to_string
local P = minetest.string_to_pos
local M = minetest.get_meta
local Tube = hyperloop.Tube
local Shaft = hyperloop.Shaft
-- convert legacy tubes to current tubes
minetest.register_node("hyperloop:tube0", {
description = "Hyperloop Legacy Tube",
tiles = {
-- up, down, right, left, back, front
"hyperloop_tube_locked.png^[transformR90]",
"hyperloop_tube_locked.png^[transformR90]",
'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 node = minetest.get_node(pos)
node.name = "hyperloop:tube"
minetest.swap_node(pos, node)
if not Tube:after_place_tube(pos, placer, pointed_thing) then
minetest.remove_node(pos)
return true
end
return false
end,
paramtype2 = "facedir",
node_placement_prediction = "hyperloop:tube",
groups = {cracky=2, not_in_creative_inventory=1},
is_ground_content = false,
sounds = default.node_sound_metal_defaults(),
})
--
-- Wifi nodes
--
local tWifiNodes = {}
-- Wifi nodes don't know their counterpart.
-- But by means of the tube head nodes, two
-- Wifi nodes in one tube line can be determined.
local function determine_wifi_pairs(pos)
-- determine 1. tube head node
local pos1 = M(pos):get_string("peer")
if pos1 == "" then return end
-- determine 2. tube head node
local pos2 = M(P(pos1)):get_string("peer")
if pos2 == "" then return end
for k,item in pairs(tWifiNodes) do
-- entry already available
if item[1] == pos2 and item[2] == pos1 then
tWifiNodes[k] = nil
-- start paring
Tube:set_pairing(P(k), pos)
return
end
end
-- add single Wifi node to pairing table
tWifiNodes[S(pos)] = {pos1, pos2}
end
local function next_node_on_the_way_to_a_wifi_node(pos)
local dirs = {}
for dir = 1, 6 do
local npos, node = Tube:get_next_node(pos, dir)
if node.name == "hyperloop:tube" or node.name == "hyperloop:tube1" or node.name == "hyperloop:tube2" then
dirs[#dirs+1] = dir
elseif node and node.name == "hyperloop:tube_wifi1" then
determine_wifi_pairs(npos)
end
end
if #dirs == 1 then
return dirs[1], nil, 1
elseif #dirs == 2 then
return dirs[1], dirs[2], 2
else
print("on_convert_tube", dump(dirs))
end
end
local function search_wifi_node(pos, dir)
local convert_next_tube = function(pos, dir)
local npos, node = Tube:get_next_node(pos, dir)
local dir1, dir2, num = next_node_on_the_way_to_a_wifi_node(npos)
if dir1 then
if tubelib2.Turn180Deg[dir] == dir1 then
return npos, dir2
else
return npos, dir1
end
end
end
local cnt = 0
if not dir then return pos, cnt end
while true do
local new_pos, new_dir = convert_next_tube(pos, dir)
if not new_dir then break end
pos, dir = new_pos, new_dir
cnt = cnt + 1
end
return pos, dir, cnt
end
local function search_wifi_node_in_all_dirs(pos)
-- check all positions
for dir = 1, 6 do
local npos, node = Tube:get_next_node(pos, dir)
if node and node.name == "hyperloop:tube1" then
search_wifi_node(pos, dir)
end
end
end
--
-- Stations/Junctions
--
local function convert_tube_line(pos)
-- check all positions
for dir = 1, 6 do
local npos, node = Tube:get_next_node(pos, dir)
if node and node.name == "hyperloop:tube1" then
local peer = Tube:convert_tube_line(pos, dir)
--print("npos", FoundWifiNodes[S(npos)])
end
end
end
--
-- Elevator shafts
--
local function convert_shaft_line(pos)
-- check lower position
if Shaft:primary_node(pos, 5) then
Shaft:convert_tube_line(pos, 5)
end
-- check upper position
pos.y = pos.y + 1
if Shaft:primary_node(pos, 6) then
Shaft:convert_tube_line(pos, 6)
end
pos.y = pos.y - 1
end
local function convert_station_data(tAllStations)
for key,item in pairs(tAllStations) do
if item.pos and Tube:secondary_node(item.pos) then
hyperloop.data.tAllStations[key] = item
end
end
-- First perform the Wifi node pairing
-- before all tube node loose their meta data
-- while converted.
for key,item in pairs(tAllStations) do
if item.pos and Tube:secondary_node(item.pos) then
search_wifi_node_in_all_dirs(item.pos)
end
end
-- Then convert all tube nodes
for key,item in pairs(tAllStations) do
if item.pos and Tube:secondary_node(item.pos) then
convert_tube_line(item.pos)
Tube:after_place_node(item.pos)
hyperloop.update_routes(item.pos)
end
end
end
local function convert_elevator_data(tAllElevators)
hyperloop.data.tAllElevators = {}
for pos,item in pairs(tAllElevators) do
local tbl = {}
for _,floor in ipairs(item.floors) do
if floor.pos and Shaft:secondary_node(floor.pos) then
tbl[#tbl+1] = floor
end
end
hyperloop.data.tAllElevators[pos] = {floors = tbl}
end
for pos,item in pairs(tAllElevators) do
for _,floor in ipairs(item.floors) do
if floor.pos and Shaft:secondary_node(floor.pos) then
convert_shaft_line(floor.pos)
end
end
end
end
local wpath = minetest.get_worldpath()
function hyperloop.file2table(filename)
local f = io.open(wpath..DIR_DELIM..filename, "r")
if f == nil then return {} end
local t = f:read("*all")
f:close()
if t == "" or t == nil then return nil end
return minetest.deserialize(t)
end
local function migrate()
Shaft:add_legacy_node_names({"hyperloop:shaft", "hyperloop:shaft2"})
Tube:add_legacy_node_names({"hyperloop:tube", "hyperloop:tube1", "hyperloop:tube2"})
local data = hyperloop.file2table("mod_hyperloop.data")
if data then
hyperloop.convert = true
convert_station_data(data.tAllStations)
convert_elevator_data(data.tAllElevators)
os.remove(wpath..DIR_DELIM.."mod_hyperloop.data")
hyperloop.convert = nil
end
end
minetest.after(5, migrate)