--[[ 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)