diff --git a/design.txt b/design.txt index 46de9b6..eb3f8c6 100644 --- a/design.txt +++ b/design.txt @@ -55,3 +55,52 @@ dir1/dir2 1/2 1/4 2/3 3/4 axis/rot 2/3 3/2 1/3 1/1 + + +after_place_node() + Tube:update_tubes_after_place_node() + get_player_data() + determine_tube_dirs() + friendly_primary_node() + tube_data_to_table() + add_tube_dir() + del_meta_data() + get_next_node() + decode_param2() + +after_dig_node() + Tube:update_tubes_after_dig_node() + decode_param2() + del_tube_dir() + del_meta_data() + decode_param2() + tube_data_to_table() + +on_timer() + Tube:get_connected_node_pos() + +Wifi:after_place_node() + Tube:prepare_pairing() + del_meta_data() + +Wifi:on_receive_fields() + Tube:pairing() + store_teleport_data() + del_meta_data() + +Wifi:on_destruct() + Tube:stop_pairing() + del_meta_data() + +Tool:repair_tubes() + Tube:repair_tubes() + get_tube_dirs() + repair_tube_line() + add_meta_data() + update_head_tube() + +Tool:remove_tube() + Tube:remove_tube() + get_tube_dirs() + friendly_primary_node() + repair_tubes() diff --git a/internal.lua b/internal.lua index f321ade..a45357f 100644 --- a/internal.lua +++ b/internal.lua @@ -43,7 +43,7 @@ local M = minetest.get_meta -- The data of the peer head tube are stored as meta data: "peer_pos" and "peer_dir" -local Turn180Deg = {3,4,1,2,6,5} +local Turn180Deg = {[0]=0,3,4,1,2,6,5} -- To calculate param2 based on dir6d information local DirToParam2 = { @@ -72,7 +72,8 @@ for k,item in pairs(DirToParam2) do end -- For neighbour position calculation -local Dir6dToVector = { +local Dir6dToVector = {[0] = + {x=0, y=0, z=0}, {x=0, y=0, z=1}, {x=1, y=0, z=0}, {x=0, y=0, z=-1}, @@ -81,6 +82,8 @@ local Dir6dToVector = { {x=0, y=1, z=0}, } +tubelib2.Dir6dToVector = Dir6dToVector + local VectorToDir6d = { [{x=0, y=0, z=1}] = 1, [{x=1, y=0, z=0}] = 2, @@ -128,15 +131,6 @@ local function get_node_lvm(pos) return node end --- Return node next to pos in direction 'dir' -local function get_next_node(pos, dir) - if dir and Dir6dToVector[dir] then - local npos = vector.add(pos, Dir6dToVector[dir]) - return npos, get_node_lvm(npos) - end - return pos, get_node_lvm(pos) -end - -- -- Tubelib2 Methods @@ -144,12 +138,6 @@ end local Tube = tubelib2.Tube --- Check if node has a connection on the given dir -function Tube:connected(pos, dir) - local _, node = get_next_node(pos, dir) - return self.primary_node_names[node.name] or self.secondary_node_names[node.name] -end - -- Return param2 and tube type ("A"/"S") function Tube:encode_param2(dir1, dir2, num_conn) if dir1 > dir2 then @@ -169,9 +157,31 @@ function Tube:decode_param2(param2) end end +-- Return node next to pos in direction 'dir' +function Tube:get_next_node(pos, dir) + local npos = vector.add(pos, Dir6dToVector[dir or 0]) + return npos, get_node_lvm(npos) +end + +-- Check if node has a connection on the given dir +function Tube:connected(pos, dir) + local npos = vector.add(pos, Dir6dToVector[dir or 0]) + local node = get_node_lvm(npos) + return self.primary_node_names[node.name] or self.secondary_node_names[node.name] +end + +-- Return the param2 stored tube dirs or 0,0 +function Tube:get_tube_dirs(pos) + local node = get_node_lvm(pos) + if self.primary_node_names[node.name] then + return self:decode_param2(node.param2) + end + return 0,0 +end + -- Return pos for a primary_node and true if num_conn < 2, else false function Tube:friendly_primary_node(pos, dir) - local npos, node = get_next_node(pos, dir) + local npos, node = self:get_next_node(pos, dir) local _,_,num_conn = self:decode_param2(node.param2) if self.primary_node_names[node.name] then -- tube node with max one connection? @@ -180,25 +190,41 @@ function Tube:friendly_primary_node(pos, dir) end function Tube:secondary_node(pos, dir) - local npos, node = get_next_node(pos, dir) + local npos, node = self:get_next_node(pos, dir) if self.secondary_node_names[node.name] then return npos end end +-- Jump over the teleport nodes to the next tube node +function Tube:get_next_teleport_node(pos, dir) + local npos = vector.add(pos, Dir6dToVector[dir or 0]) + local meta = M(npos) + local s = meta:get_string("tele_pos") + if s ~= "" then + local tele_pos = P(s) + local tube_dir = M(tele_pos):get_int("tube_dir") + if tube_dir ~= 0 then + return tele_pos, tube_dir + end + end +end + -- Update meta data and number of connections in param2 -- pos1 is the node to be updated with the data pos2, dir2, num_tubes function Tube:update_head_tube(pos1, pos2, dir2, num_tubes) - local _, node = get_next_node(pos1) - local d1, d2, num = self:decode_param2(node.param2) - num = (self:connected(pos1, d1) and 1 or 0) + (self:connected(pos1, d2) and 1 or 0) - node.param2 = self:encode_param2(d1, d2, num) - minetest.set_node(pos1, node) - if self.show_infotext then - M(pos1):set_string("infotext", S(pos2).." / "..num_tubes.." tubes") + local node = get_node_lvm(pos1) + if self.primary_node_names[node.name] then + local d1, d2, num = self:decode_param2(node.param2) + num = (self:connected(pos1, d1) and 1 or 0) + (self:connected(pos1, d2) and 1 or 0) + node.param2 = self:encode_param2(d1, d2, num) + minetest.set_node(pos1, node) + if self.show_infotext then + M(pos1):set_string("infotext", S(pos2).." / "..num_tubes.." tubes") + end + M(pos1):set_string("peer_pos", S(pos2)) + M(pos1):set_int("peer_dir", dir2) end - M(pos1):set_string("peer_pos", S(pos2)) - M(pos1):set_int("peer_dir", dir2) end -- Add meta data on both tube sides pos1 and pos2 @@ -208,17 +234,25 @@ function Tube:add_meta_data(pos1, pos2, dir1, dir2, num_tubes) self:update_head_tube(pos2, pos1, dir1, num_tubes) end --- Delete meta data on both tube sides --- pos is the position of one head node -function Tube:del_meta_data(pos) - local peer_pos = P(M(pos):get_string("peer_pos")) - if peer_pos then - M(pos):from_table(nil) - M(peer_pos):from_table(nil) +-- Delete meta data on both tube sides. +-- If dir is nil, pos is the position of one head node. +function Tube:del_meta_data(pos, dir) + local npos = vector.add(pos, Dir6dToVector[dir or 0]) + local speer_pos = M(npos):get_string("peer_pos") + if speer_pos ~= "" then + local meta = M(pos) + if meta:get_string("peer_pos") ~= "" then + meta:from_table(nil) + end + meta = M(P(speer_pos)) + if meta:get_string("peer_pos") ~= "" then + meta:from_table(nil) + end + return true end + return false end - function Tube:fdir(player) local pitch = player:get_look_pitch() if pitch > 1.1 then -- up? @@ -329,7 +363,7 @@ end -- and return the new data to be able to update the node: -- new_pos, dir1, dir2, num_connections (1, 2) function Tube:add_tube_dir(pos, dir) - local npos, node = get_next_node(pos, dir) + local npos, node = self:get_next_node(pos, dir) if self.primary_node_names[node.name] then local d1, d2, num = self:decode_param2(node.param2) -- not already connected to the new tube? @@ -354,42 +388,35 @@ end -- and return the new data to be able to update the node: -- new_pos, dir1, dir2, num_connections (0, 1) function Tube:del_tube_dir(pos, dir) - local npos, node = get_next_node(pos, dir) + local npos, node = self:get_next_node(pos, dir) if self.primary_node_names[node.name] then local d1, d2, num = self:decode_param2(node.param2) return npos, d1, d2, math.max(num - 1, 0) end end --- Return the param2 stored tube dirs -function Tube:get_tube_dirs(pos) - local _, node = get_next_node(pos) - if self.primary_node_names[node.name] then - local d1, d2 = self:decode_param2(node.param2) - return d1, d2 - end -end - --- Jump over the teleport nodes to the next tube node -function Tube:get_next_teleport_node(pos, dir) - local meta = M(pos) - local s = meta:get_string("tele_pos") - if s ~= "" then - local tele_pos = P(s) - local tube_dir = M(tele_pos):get_int("tube_dir") - if tube_dir ~= 0 then - return tele_pos, tube_dir +-- Store the node data in out_tbl for later use +-- and return true/false +function Tube:is_tube_head(pos, dir, out_tbl) + out_tbl.pos, out_tbl.node = self:get_next_node(pos, dir) + if self.primary_node_names[out_tbl.node.name] then + local dir1, dir2, num_conn = self:decode_param2(out_tbl.node.param2) + if Turn180Deg[dir] == dir1 then + out_tbl.dir = dir2 + else + out_tbl.dir = dir1 end + return true end -end - + return false +end -- Go down the tube to the end position and -- return pos, dir to the next node, and num tubes -function Tube:find_tube_head(pos) +function Tube:find_peer_tube_head(node_tbl) local get_next_tube = function(self, pos, dir) -- Return pos and dir to the next node of the tube node at pos/dir - local npos, node = get_next_node(pos, dir) + local npos, node = self:get_next_node(pos, dir) if self.primary_node_names[node.name] then local dir1, dir2, num = self:decode_param2(node.param2) if Turn180Deg[dir] == dir1 then @@ -399,19 +426,12 @@ function Tube:find_tube_head(pos) end end - return Tube:get_next_teleport_node(npos, dir, node) + return self:get_next_teleport_node(npos) end local cnt = 0 - local dir - -- first determine the walk direction - local d1, d2 = self:get_tube_dirs(pos) - local _, node = get_next_node(pos, d1) - if self.primary_node_names[node.name] then - dir = d1 - else - dir = d2 - end + local pos = node_tbl.pos + local dir = node_tbl.dir while cnt <= self.max_tube_length do local new_pos, new_dir = get_next_tube(self, pos, dir) @@ -424,7 +444,7 @@ end -- Set tube to a 2 connection node without meta data function Tube:set_2_conn_tube(pos) - local npos, node = get_next_node(pos) + local npos, node = self:get_next_node(pos) if self.primary_node_names[node.name] then local dir1, dir2, _ = self:decode_param2(node.param2) node.param2 = self:encode_param2(dir1, dir2, 2) @@ -438,7 +458,7 @@ end -- return head-pos and number of nodes function Tube:repair_tube_line(pos, dir) local repair_next_tube = function(self, pos, dir) - local npos, node = get_next_node(pos, dir) + local npos, node = self:get_next_node(pos, dir) if self.primary_node_names[node.name] then local dir1, dir2, num = self:decode_param2(node.param2) if num ~= 2 then @@ -452,8 +472,7 @@ function Tube:repair_tube_line(pos, dir) return npos, dir1 end end - - return Tube:get_next_teleport_node(npos, dir, node) + return self:get_next_teleport_node(npos) end local cnt = 0 @@ -474,4 +493,52 @@ function Tube:store_teleport_data(pos, peer_pos) meta:set_string("channel", nil) meta:set_string("formspec", nil) meta:set_string("infotext", "Connected with "..S(peer_pos)) + return meta:get_int("tube_dir") end + +function Tube:get_peer_tube_head(node_tbl) + -- if meta data is available, return peer_pos, peer_pos + local meta = M(node_tbl.pos) + local spos = meta:get_string("peer_pos") + if spos ~= "" then + return P(spos), meta:get_int("peer_dir") + end + -- repair tube line + local pos2, dir2, cnt = self:find_peer_tube_head(node_tbl) + self:add_meta_data(node_tbl.pos, pos2, node_tbl.dir, dir2, cnt) + return pos2, dir2 +end + +function Tube:delete_tube_meta_data(pos, dir1, dir2, oldmetadata) + local t = minetest.get_us_time() + + -- tube with two connections? + if dir2 then + local res + if dir1 then + local npos = self:find_peer_tube_head({pos=pos, dir=dir1}) + if not self:del_meta_data(npos) then + -- try the other direction + npos = self:find_peer_tube_head({pos=pos, dir=dir2}) + self:del_meta_data(npos) + end + end + -- removed node with meta data? + elseif oldmetadata and oldmetadata.fields and oldmetadata.fields.peer_pos then + local npos = P(oldmetadata.fields.peer_pos) + self:del_meta_data(npos) + elseif dir1 then + local npos = vector.add(pos, Dir6dToVector[dir1]) + -- node with peer meta data? + if not self:del_meta_data(npos) then + -- try teleport node + local tele_pos, tube_dir = self:get_next_teleport_node(npos) + if tele_pos then + local npos = self:find_peer_tube_head({pos=tele_pos, dir=tube_dir}) + self:del_meta_data(npos) + end + end + end + t = minetest.get_us_time() - t + print("del time", t) +end \ No newline at end of file diff --git a/textures/tubelib2_source.png b/textures/tubelib2_source.png new file mode 100644 index 0000000..84944d1 Binary files /dev/null and b/textures/tubelib2_source.png differ diff --git a/tube_api.lua b/tube_api.lua index 7af628c..cc4d4d6 100644 --- a/tube_api.lua +++ b/tube_api.lua @@ -55,38 +55,65 @@ function Tube:add_secondary_node_names(names) end end --- From node to node via tube --- Used for item transportation via tubes +-- From source node to destination node via tubes. +-- pos is the source node position, dir the output dir +-- The returned pos is the destination position, dir +-- is the direction into the destination node. function Tube:get_connected_node_pos(pos, dir) - pos, _ = self:get_next_node(pos, dir) - pos, dir = self:get_tube_end_pos(pos) - pos, _ = self:get_next_node(pos, dir) - return pos, dir -end + local node = {} + if self:is_tube_head(pos, dir, node) then + local npos, ndir = self:get_peer_tube_head(node) + return vector.add(npos, tubelib2.Dir6dToVector[ndir or 0]), ndir + end + return vector.add(pos, tubelib2.Dir6dToVector[dir or 0]), dir +end -- From tube head to tube head. --- Return pos and dir to the connected/next node. -function Tube:get_tube_end_pos(pos) - local spos = M(pos):get_string("peer_pos") - if spos ~= "" then - return P(spos), M(pos):get_int("peer_dir") +-- pos is the tube head position, dir is the direction into the head node. +-- The returned pos is the peer head position, dir +-- is the direction out of the peer head node. +function Tube:get_tube_end_pos(pos, dir) + local node = {} + if self:is_tube_head(pos, nil, node) then + return self:get_peer_tube_head(node) end - local npos, dir, num = self:find_tube_head(pos) - self:update_head_tube(pos, npos, dir, num) - return npos, dir + return pos, dir end -- To be called after a tube node is placed. -function Tube:update_tubes_after_place_node(pos, placer, pointed_thing) +function Tube:update_tubes_after_place_node(pos, dir1, dir2) + self:delete_tube_meta_data(pos, dir1, dir2) + local tbl = {} + + if dir1 then + local npos, d1, d2, num = self:add_tube_dir(pos, dir1) + if npos then + tbl[#tbl+1] = self:tube_data_to_table(npos, d1, d2, num) + end + end + + if dir2 then + local npos, d1, d2, num = self:add_tube_dir(pos, dir2) + if npos then + tbl[#tbl+1] = self:tube_data_to_table(npos, d1, d2, num) + end + end + + return tbl +end + +-- To be called after a tube node is placed. +function Tube:update_tubes_after_place_tube(pos, placer, pointed_thing) local preferred_pos, fdir = self:get_player_data(placer, pointed_thing) local dir1, dir2, num_tubes = self:determine_tube_dirs(pos, preferred_pos, fdir) if dir1 == nil then return {} end - local tbl = {self:tube_data_to_table(pos, dir1, dir2, num_tubes)} + self:delete_tube_meta_data(pos, dir1, dir2) + local tbl = {self:tube_data_to_table(pos, dir1, dir2, num_tubes)} if num_tubes >= 1 then local npos, d1, d2, num = self:add_tube_dir(pos, dir1) if npos then @@ -104,12 +131,32 @@ function Tube:update_tubes_after_place_node(pos, placer, pointed_thing) return tbl end +-- To be called after a secondary node is removed. +function Tube:update_tubes_after_dig_node(pos, dir1, dir2) + local tbl = {} + + self:delete_tube_meta_data(pos, dir1, dir2) + + local npos, d1, d2, num = self:del_tube_dir(pos, dir1) + if npos then + tbl[#tbl+1] = self:tube_data_to_table(npos, d1, d2, num) + end + + npos, d1, d2, num = self:del_tube_dir(pos, dir2) + if npos then + tbl[#tbl+1] = self:tube_data_to_table(npos, d1, d2, num) + end + + return tbl +end -- To be called after a tube node is removed. -function Tube:update_tubes_after_dig_node(pos, oldnode) +function Tube:update_tubes_after_dig_tube(pos, oldnode, oldmetadata) local dir1, dir2, num_tubes = self:decode_param2(oldnode.param2) local tbl = {} + self:delete_tube_meta_data(pos, dir1, dir2, oldmetadata) + local npos, d1, d2, num = self:del_tube_dir(pos, dir1) if npos then tbl[#tbl+1] = self:tube_data_to_table(npos, d1, d2, num) @@ -125,9 +172,9 @@ end -- To be called from a repair tool in the case of a "WorldEdit" corrupted tube line. -function Tube:repair_tubes(pos) +function Tube:tool_repair_tubes(pos) local d1, d2 = self:get_tube_dirs(pos) - if d1 and d2 then + if d1 ~= 0 then self:set_2_conn_tube(pos) local npos1, dir1, cnt1 = self:repair_tube_line(pos, d1) local npos2, dir2, cnt2 = self:repair_tube_line(pos, d2) @@ -138,9 +185,9 @@ end -- To be called from a repair tool in the case, tube nodes are "unbreakable". -function Tube:remove_tube(pos, sound) +function Tube:tool_remove_tube(pos, sound) local dir1, dir2 = self:get_tube_dirs(pos) - if dir1 and dir2 then + if dir1 ~= 0 then minetest.sound_play({ name=sound},{ gain=1, @@ -149,14 +196,18 @@ function Tube:remove_tube(pos, sound) local npos1 = self:friendly_primary_node(pos, dir1) local npos2 = self:friendly_primary_node(pos, dir2) minetest.remove_node(pos) - if npos1 then self:repair_tubes(npos1) end - if npos2 then self:repair_tubes(npos2) end + if npos1 then self:tool_repair_tubes(npos1) end + if npos2 then self:tool_repair_tubes(npos2) end end end function Tube:prepare_pairing(pos, tube_dir, sFormspec) local meta = M(pos) meta:set_int("tube_dir", tube_dir) + + -- break the connection + self:delete_tube_meta_data(pos, tube_dir) + meta:set_string("channel", nil) meta:set_string("infotext", "Unconnected") meta:set_string("formspec", sFormspec) @@ -166,8 +217,13 @@ function Tube:pairing(pos, channel) if self.pairingList[channel] and pos ~= self.pairingList[channel] then -- store peer position on both nodes local peer_pos = self.pairingList[channel] - self:store_teleport_data(pos, peer_pos) - self:store_teleport_data(peer_pos, pos) + + local tube_dir1 = self:store_teleport_data(pos, peer_pos) + local tube_dir2 = self:store_teleport_data(peer_pos, pos) + + self:delete_tube_meta_data(pos, tube_dir1) + self:delete_tube_meta_data(peer_pos, tube_dir2) + self.pairingList[channel] = nil return true else @@ -179,17 +235,22 @@ function Tube:pairing(pos, channel) end end -function Tube:stop_pairing(pos, sFormspec) +function Tube:stop_pairing(pos, oldmetadata, sFormspec) -- unpair peer node - local s = M(pos):get_string("peer_pos") - if s ~= "" then - local peer_pos = P(s) - local peer_meta = M(peer_pos) + if oldmetadata and oldmetadata.fields and oldmetadata.fields.tele_pos then + local tele_pos = P(oldmetadata.fields.tele_pos) + local peer_meta = M(tele_pos) if peer_meta then + self:delete_tube_meta_data(tele_pos, peer_meta:get_int("tube_dir")) + peer_meta:set_string("channel", nil) peer_meta:set_string("tele_pos", nil) peer_meta:set_string("formspec", sFormspec) peer_meta:set_string("infotext", "Unconnected") end end + + if oldmetadata and oldmetadata.fields then + self:delete_tube_meta_data(pos, tonumber(oldmetadata.fields.tube_dir or 0), nil, oldmetadata) + end end diff --git a/tube_test.lua b/tube_test.lua index f17ae25..64ddb01 100644 --- a/tube_test.lua +++ b/tube_test.lua @@ -25,7 +25,8 @@ local Tube = tubelib2.Tube:new({ max_tube_length = 1000, show_infotext = true, primary_node_names = {"tubelib2:tubeS", "tubelib2:tubeA"}, - secondary_node_names = {"default:chest", "default:chest_open"}, + secondary_node_names = {"default:chest", "default:chest_open", + "tubelib2:source", "tubelib2:teleporter"}, }) minetest.register_node("tubelib2:tubeS", { @@ -40,7 +41,7 @@ minetest.register_node("tubelib2:tubeS", { }, after_place_node = function(pos, placer, itemstack, pointed_thing) - local nodes = Tube:update_tubes_after_place_node(pos, placer, pointed_thing) + local nodes = Tube:update_tubes_after_place_tube(pos, placer, pointed_thing) if #nodes > 0 then for _,item in ipairs(nodes) do minetest.set_node(item.pos, {name = "tubelib2:tube"..item.type, param2 = item.param2}) @@ -53,7 +54,7 @@ minetest.register_node("tubelib2:tubeS", { end, after_dig_node = function(pos, oldnode, oldmetadata, digger) - for _,item in ipairs(Tube:update_tubes_after_dig_node(pos, oldnode)) do + for _,item in ipairs(Tube:update_tubes_after_dig_tube(pos, oldnode, oldmetadata)) do minetest.set_node(item.pos, {name = "tubelib2:tube"..item.type, param2 = item.param2}) end end, @@ -87,7 +88,7 @@ minetest.register_node("tubelib2:tubeA", { }, after_dig_node = function(pos, oldnode, oldmetadata, digger) - for _,item in ipairs(Tube:update_tubes_after_dig_node(pos, oldnode)) do + for _,item in ipairs(Tube:update_tubes_after_dig_tube(pos, oldnode, oldmetadata)) do minetest.set_node(item.pos, {name = "tubelib2:tube"..item.type, param2 = item.param2}) end end, @@ -115,6 +116,65 @@ local sFormspec = "size[7.5,3]".. "button_exit[2,2;3,1;exit;Save]" +minetest.register_node("tubelib2:source", { + description = "Tubelib2 Item Source", + tiles = { + -- up, down, right, left, back, front + 'tubelib2_source.png', + 'tubelib2_source.png', + 'tubelib2_source.png', + 'tubelib2_source.png', + 'tubelib2_source.png', + 'tubelib2_conn.png', + }, + + after_place_node = function(pos, placer) + local tube_dir = ((minetest.dir_to_facedir(placer:get_look_dir()) + 2) % 4) + 1 + M(pos):set_int("tube_dir", tube_dir) + + for _,item in ipairs(Tube:update_tubes_after_place_tube(pos, tube_dir)) do + minetest.set_node(item.pos, {name = "tubelib2:tube"..item.type, param2 = item.param2}) + end + + minetest.get_node_timer(pos):start(2) + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0) + for _,item in ipairs(Tube:update_tubes_after_dig_node(pos, tube_dir)) do + minetest.set_node(item.pos, {name = "tubelib2:tube"..item.type, param2 = item.param2}) + end + end, + + on_timer = function(pos, elapsed) + local tube_dir = M(pos):get_int("tube_dir") + local dest_pos = Tube:get_connected_node_pos(pos, tube_dir) + local inv = minetest.get_inventory({type="node", pos=dest_pos}) + local stack = ItemStack("default:dirt") + if inv then + local leftover = inv:add_item("main", stack) + if leftover:get_count() == 0 then + return true + end + end + local node = minetest.get_node(dest_pos) + if node.name == "air" then + minetest.add_item(dest_pos, stack) + else + print("add_item error") + end + return true + end, + + paramtype2 = "facedir", -- important! + on_rotate = screwdriver.disallow, -- important! + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + groups = {crumbly = 3, cracky = 3, snappy = 3}, + sounds = default.node_sound_glass_defaults(), +}) + minetest.register_node("tubelib2:teleporter", { description = "Tubelib2 Teleporter", tiles = { @@ -128,10 +188,13 @@ minetest.register_node("tubelib2:teleporter", { }, after_place_node = function(pos, placer) - Tube:pairing(pos, sFormspec) -- the tube_dir calculation depends on the player look-dir and the hole side of the node local tube_dir = ((minetest.dir_to_facedir(placer:get_look_dir()) + 2) % 4) + 1 Tube:prepare_pairing(pos, tube_dir, sFormspec) + + for _,item in ipairs(Tube:update_tubes_after_place_tube(pos, tube_dir)) do + minetest.set_node(item.pos, {name = "tubelib2:tube"..item.type, param2 = item.param2}) + end end, on_receive_fields = function(pos, formname, fields, player) @@ -140,8 +203,13 @@ minetest.register_node("tubelib2:teleporter", { end end, - on_destruct = function(pos) - Tube:stop_pairing(pos, sFormspec) + after_dig_node = function(pos, oldnode, oldmetadata, digger) + Tube:stop_pairing(pos, oldmetadata, sFormspec) + + local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0) + for _,item in ipairs(Tube:update_tubes_after_dig_node(pos, tube_dir)) do + minetest.set_node(item.pos, {name = "tubelib2:tube"..item.type, param2 = item.param2}) + end end, paramtype2 = "facedir", -- important! @@ -153,59 +221,59 @@ minetest.register_node("tubelib2:teleporter", { sounds = default.node_sound_glass_defaults(), }) -local function read_test_type(itemstack, placer, pointed_thing) - local param2 - if pointed_thing.type == "node" then - local node = minetest.get_node(pointed_thing.under) - param2 = node.param2 - else - param2 = 0 - end - local num = math.floor(param2/32) - local axis = math.floor(param2/4) % 8 - local rot = param2 % 4 - minetest.chat_send_player(placer:get_player_name(), "[Tubelib2] param2 = "..param2.."/"..num.."/"..axis.."/"..rot) +--local function read_test_type(itemstack, placer, pointed_thing) +-- local param2 +-- if pointed_thing.type == "node" then +-- local node = minetest.get_node(pointed_thing.under) +-- param2 = node.param2 +-- else +-- param2 = 0 +-- end +-- local num = math.floor(param2/32) +-- local axis = math.floor(param2/4) % 8 +-- local rot = param2 % 4 +-- minetest.chat_send_player(placer:get_player_name(), "[Tubelib2] param2 = "..param2.."/"..num.."/"..axis.."/"..rot) - return itemstack -end +-- return itemstack +--end -local function TEST_determine_tube_dirs(itemstack, placer, pointed_thing) - if pointed_thing.type == "node" then - local pos = pointed_thing.above - local preferred_pos = pointed_thing.under - local fdir = Tube:fdir(placer) - local dir1, dir2, num_tubes = Tube:determine_tube_dirs(pos, preferred_pos, fdir) - print("num_tubes="..num_tubes.." dir1="..(dir1 or "nil").." dir2="..(dir2 or "nil")) - end -end +--local function TEST_determine_tube_dirs(itemstack, placer, pointed_thing) +-- if pointed_thing.type == "node" then +-- local pos = pointed_thing.above +-- local preferred_pos = pointed_thing.under +-- local fdir = Tube:fdir(placer) +-- local dir1, dir2, num_tubes = Tube:determine_tube_dirs(pos, preferred_pos, fdir) +-- print("num_tubes="..num_tubes.." dir1="..(dir1 or "nil").." dir2="..(dir2 or "nil")) +-- end +--end -local function TEST_update_tubes_after_place_node(itemstack, placer, pointed_thing) - if pointed_thing.type == "node" then - local pos = pointed_thing.above - local nodes = Tube:update_tubes_after_place_node(pos, placer, pointed_thing) - print("nodes"..dump(nodes)) - end -end +--local function TEST_update_tubes_after_place_node(itemstack, placer, pointed_thing) +-- if pointed_thing.type == "node" then +-- local pos = pointed_thing.above +-- local nodes = Tube:update_tubes_after_place_node(pos, placer, pointed_thing) +-- print("nodes"..dump(nodes)) +-- end +--end -local function TEST_add_tube_dir(itemstack, placer, pointed_thing) - read_test_type(itemstack, placer, pointed_thing) - if pointed_thing.type == "node" then - local pos = pointed_thing.above - local fdir = Tube:fdir(placer) - local npos, d1, d2, num = Tube:add_tube_dir(pos, fdir) - print("npos, d1, d2, num", npos and S(npos), d1, d2, num) - end -end +--local function TEST_add_tube_dir(itemstack, placer, pointed_thing) +-- read_test_type(itemstack, placer, pointed_thing) +-- if pointed_thing.type == "node" then +-- local pos = pointed_thing.above +-- local fdir = Tube:fdir(placer) +-- local npos, d1, d2, num = Tube:add_tube_dir(pos, fdir) +-- print("npos, d1, d2, num", npos and S(npos), d1, d2, num) +-- end +--end -local function TEST_del_tube_dir(itemstack, placer, pointed_thing) - read_test_type(itemstack, placer, pointed_thing) - if pointed_thing.type == "node" then - local pos = pointed_thing.above - local fdir = Tube:fdir(placer) - local npos, d1, d2, num = Tube:del_tube_dir(pos, fdir) - print("npos, d1, d2, num", npos and S(npos), d1, d2, num) - end -end +--local function TEST_del_tube_dir(itemstack, placer, pointed_thing) +-- read_test_type(itemstack, placer, pointed_thing) +-- if pointed_thing.type == "node" then +-- local pos = pointed_thing.above +-- local fdir = Tube:fdir(placer) +-- local npos, d1, d2, num = Tube:del_tube_dir(pos, fdir) +-- print("npos, d1, d2, num", npos and S(npos), d1, d2, num) +-- end +--end local function read_param2(pos, player) local node = minetest.get_node(pos) @@ -219,12 +287,15 @@ local function repair_tubes(itemstack, placer, pointed_thing) if pointed_thing.type == "node" then local pos = pointed_thing.under if placer:get_player_control().sneak then - local end_pos, dir = Tube:get_tube_end_pos(pos) + local end_pos, dir = Tube:get_tube_end_pos(pos, 0) if end_pos and dir then minetest.chat_send_player(placer:get_player_name(), "[Tubelib2] end_pos = "..S(end_pos)..", dir = "..dir) end else - local pos1, pos2, dir1, dir2, cnt1, cnt2 = Tube:repair_tubes(pos) + local t = minetest.get_us_time() + local pos1, pos2, dir1, dir2, cnt1, cnt2 = Tube:tool_repair_tubes(pos) + t = minetest.get_us_time() - t + print("time", t) if pos1 and pos2 then minetest.chat_send_player(placer:get_player_name(), "[Tubelib2] 1: "..S(pos1)..", dir = "..dir1..", "..cnt1.." tubes") minetest.chat_send_player(placer:get_player_name(), "[Tubelib2] 2: "..S(pos2)..", dir = "..dir2..", "..cnt2.." tubes") @@ -239,7 +310,7 @@ local function remove_tube(itemstack, placer, pointed_thing) if placer:get_player_control().sneak then read_param2(pos, placer) else - Tube:remove_tube(pos, "default_break_glass") + Tube:tool_remove_tube(pos, "default_break_glass") end end end