Fix problems with incorrectly destructed teleport tubes.
authorNovatux <nathanael.courant@laposte.net>
Sun, 29 Jun 2014 10:36:22 +0000 (12:36 +0200)
committerNovatux <nathanael.courant@laposte.net>
Sun, 29 Jun 2014 10:36:22 +0000 (12:36 +0200)
teleport_tube.lua

index f57f55a340ddd88cef102f2fdfc733cf790c4a8c..1bd62d3c887ea2ccd56b69d1acb10ce6b6cc1cf7 100644 (file)
@@ -3,10 +3,10 @@ local filename=minetest.get_worldpath() .. "/teleport_tubes"
 
 local function read_file()
        local f = io.open(filename, "r")
-       if f==nil then return {} end
+       if f == nil then return {} end
        local t = f:read("*all")
        f:close()
-       if t=="" or t==nil then return {} end
+       if t == "" or t == nil then return {} end
        return minetest.deserialize(t)
 end
 
@@ -18,8 +18,8 @@ end
 
 local function update_pos_in_file(pos)
        local tbl=read_file()
-       for _,val in ipairs(tbl) do
-               if val.x==pos.x and val.y==pos.y and val.z==pos.z then
+       for _, val in ipairs(tbl) do
+               if val.x == pos.x and val.y == pos.y and val.z == pos.z then
                        local meta = minetest.get_meta(val)
                        val.channel = meta:get_string("channel")
                        val.cr = meta:get_int("can_receive")
@@ -40,34 +40,56 @@ local function add_tube_in_file(pos,channel, cr)
 end
 
 local function remove_tube_in_file(pos)
-       local tbl=read_file()
-       local newtbl={}
-       for _,val in ipairs(tbl) do
-               if val.x~=pos.x or val.y~=pos.y or val.z~=pos.z then
-                       table.insert(newtbl,val)
+       local tbl = read_file()
+       local newtbl = {}
+       for _, val in ipairs(tbl) do
+               if val.x ~= pos.x or val.y ~= pos.y or val.z ~= pos.z then
+                       table.insert(newtbl, val)
                end
        end
        write_file(newtbl)
 end
 
+local function read_node_with_vm(pos)
+       local vm = VoxelManip()
+       local MinEdge, MaxEdge = vm:read_from_map(pos, pos)
+       local data = vm:get_data()
+       local area = VoxelArea:new({MinEdge = MinEdge, MaxEdge = MaxEdge})
+       return minetest.get_name_from_content_id(data[area:index(pos.x, pos.y, pos.z)])
+end
+
 local function get_tubes_in_file(pos,channel)
-       local tbl=read_file()
-       local newtbl={}
-       local changed=false
-       for _,val in ipairs(tbl) do
-               local node = minetest.get_node(val)
+       local tbl = read_file()
+       local newtbl = {}
+       local changed = false
+       for _, val in ipairs(tbl) do
                local meta = minetest.get_meta(val)
-               -- That shouldn't be needed anymore since the mvps callback, but we leave it nevertheless
-               if node.name~="ignore"  and (val.channel~=meta:get_string("channel") or val.cr~=meta:get_int("can_receive")) then
-                       val.channel=meta:get_string("channel")
-                       val.cr=meta:get_int("can_receive")
-                       changed=true
+               local name = read_node_with_vm(val)
+               local is_loaded = (minetest.get_node_or_nil(val) ~= nil)
+               local is_teleport_tube = minetest.registered_nodes[name] and minetest.registered_nodes[name].is_teleport_tube
+               if is_teleport_tube then
+                       if is_loaded and (val.channel ~= meta:get_string("channel") or val.cr ~= meta:get_int("can_receive")) then
+                               val.channel = meta:get_string("channel")
+                               val.cr = meta:get_int("can_receive")
+                               changed = true
+                       end
+                       if val.cr == 1 and val.channel == channel and (val.x ~= pos.x or val.y ~= pos.y or val.z ~= pos.z) then
+                               table.insert(newtbl, val)
+                       end
+               else
+                       val.to_remove = true
+                       changed = true
                end
-               if val.cr==1 and val.channel==channel and (val.x~=pos.x or val.y~=pos.y or val.z~=pos.z) then
-                       table.insert(newtbl,val)
+       end
+       if changed then
+               local updated = {}
+               for _, val in ipairs(tbl) do
+                       if not val.to_remove then
+                               table.insert(updated, val)
+                       end
                end
+               write_file(updated)
        end
-       if changed then write_file(tbl) end
        return newtbl
 end
 
@@ -82,6 +104,7 @@ local teleport_inv_texture="pipeworks_teleport_tube_inv.png"
 
 pipeworks.register_tube("pipeworks:teleport_tube","Teleporter pneumatic tube segment",teleport_plain_textures,
        teleport_noctr_textures,teleport_end_textures,teleport_short_texture,teleport_inv_texture, {
+       is_teleport_tube = true,
        tube = {
                can_go = function(pos,node,velocity,stack)
                        velocity.x = 0