mirror of
https://github.com/joe7575/tubelib2.git
synced 2024-08-19 21:14:22 +02:00
bugs fixed
This commit is contained in:
parent
61ee18124a
commit
8a10828b55
168
internal.lua
168
internal.lua
@ -37,6 +37,10 @@ local M = minetest.get_meta
|
|||||||
--
|
--
|
||||||
-- All other nodes are build by means of axis/rotation variants based on param2
|
-- All other nodes are build by means of axis/rotation variants based on param2
|
||||||
-- (paramtype2 == "facedir").
|
-- (paramtype2 == "facedir").
|
||||||
|
--
|
||||||
|
-- The 3 free MSB bits of param2 of tube nodes are used to store the number of connections (0..2).
|
||||||
|
--
|
||||||
|
-- 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 = {3,4,1,2,6,5}
|
||||||
@ -99,6 +103,7 @@ local function Tbl(list)
|
|||||||
return tbl
|
return tbl
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Return val in the range of min and max
|
||||||
local function range(val, min, max)
|
local function range(val, min, max)
|
||||||
if val > max then return max end
|
if val > max then return max end
|
||||||
if val < min then return min end
|
if val < min then return min end
|
||||||
@ -132,20 +137,20 @@ local function get_next_node(pos, dir)
|
|||||||
return pos, get_node_lvm(pos)
|
return pos, get_node_lvm(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Tubelib2 Methods
|
-- Tubelib2 Methods
|
||||||
--
|
--
|
||||||
|
|
||||||
local Tube = tubelib2.Tube
|
local Tube = tubelib2.Tube
|
||||||
|
|
||||||
-- check if node has a connection on the given dir
|
-- Check if node has a connection on the given dir
|
||||||
function Tube:connected(pos, dir)
|
function Tube:connected(pos, dir)
|
||||||
local _, node = get_next_node(pos, dir)
|
local _, node = get_next_node(pos, dir)
|
||||||
return self.primary_node_names[node.name] or self.secondary_node_names[node.name]
|
return self.primary_node_names[node.name] or self.secondary_node_names[node.name]
|
||||||
end
|
end
|
||||||
|
|
||||||
-- The 3 free bits or param2 are used to store the number of connections.
|
-- Return param2 and tube type ("A"/"S")
|
||||||
-- return param2 and tube type
|
|
||||||
function Tube:encode_param2(dir1, dir2, num_conn)
|
function Tube:encode_param2(dir1, dir2, num_conn)
|
||||||
if dir1 > dir2 then
|
if dir1 > dir2 then
|
||||||
dir1, dir2 = dir2, dir1
|
dir1, dir2 = dir2, dir1
|
||||||
@ -154,7 +159,7 @@ function Tube:encode_param2(dir1, dir2, num_conn)
|
|||||||
return (num_conn * 32) + param2, _type
|
return (num_conn * 32) + param2, _type
|
||||||
end
|
end
|
||||||
|
|
||||||
-- return dir1, dir2, num_conn
|
-- Return dir1, dir2, num_conn
|
||||||
function Tube:decode_param2(param2)
|
function Tube:decode_param2(param2)
|
||||||
local val = Param2ToDir[param2 % 32]
|
local val = Param2ToDir[param2 % 32]
|
||||||
if val then
|
if val then
|
||||||
@ -162,30 +167,58 @@ function Tube:decode_param2(param2)
|
|||||||
local num_conn = math.floor(param2 / 32)
|
local num_conn = math.floor(param2 / 32)
|
||||||
return dir1, dir2, num_conn
|
return dir1, dir2, num_conn
|
||||||
end
|
end
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- return pos for a primary_node and true if num_conn < 2, else false
|
-- Return pos for a primary_node and true if num_conn < 2, else false
|
||||||
function Tube:friendly_primary_node(pos, dir)
|
function Tube:friendly_primary_node(pos, dir)
|
||||||
-- read node
|
|
||||||
local npos, node = get_next_node(pos, dir)
|
local npos, node = get_next_node(pos, dir)
|
||||||
-- tube node with max one connection?
|
|
||||||
local _,_,num_conn = self:decode_param2(node.param2)
|
local _,_,num_conn = self:decode_param2(node.param2)
|
||||||
if self.primary_node_names[node.name] then
|
if self.primary_node_names[node.name] then
|
||||||
|
-- tube node with max one connection?
|
||||||
return npos, num_conn < 2
|
return npos, num_conn < 2
|
||||||
end
|
end
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function Tube:secondary_node(pos, dir)
|
function Tube:secondary_node(pos, dir)
|
||||||
-- read node
|
|
||||||
local npos, node = get_next_node(pos, dir)
|
local npos, node = get_next_node(pos, dir)
|
||||||
if self.secondary_node_names[node.name] then
|
if self.secondary_node_names[node.name] then
|
||||||
return npos
|
return npos
|
||||||
end
|
end
|
||||||
return nil
|
|
||||||
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", P(pos2).." / "..num_tubes.." tubes")
|
||||||
|
end
|
||||||
|
M(pos1):set_string("peer_pos", P(pos2))
|
||||||
|
M(pos1):set_int("peer_dir", dir2)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add meta data on both tube sides pos1 and pos2
|
||||||
|
-- dir1/dir2 are the tube output directions (inventory nodes)
|
||||||
|
function Tube:add_meta_data(pos1, pos2, dir1, dir2, num_tubes)
|
||||||
|
self:update_head_tube(pos1, pos2, 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 = S(M(pos):get_string("peer_pos"))
|
||||||
|
if peer_pos then
|
||||||
|
M(pos):from_table(nil)
|
||||||
|
M(peer_pos):from_table(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function Tube:fdir(player)
|
function Tube:fdir(player)
|
||||||
local pitch = player:get_look_pitch()
|
local pitch = player:get_look_pitch()
|
||||||
if pitch > 1.1 then -- up?
|
if pitch > 1.1 then -- up?
|
||||||
@ -285,13 +318,16 @@ function Tube:determine_tube_dirs(pos, preferred_pos, fdir)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- format and return given data as table
|
||||||
function Tube:tube_data_to_table(pos, dir1, dir2, num_tubes)
|
function Tube:tube_data_to_table(pos, dir1, dir2, num_tubes)
|
||||||
local param2, ttype = self:encode_param2(dir1, dir2, num_tubes)
|
local param2, ttype = self:encode_param2(dir1, dir2, num_tubes)
|
||||||
return {pos = pos, param2 = param2, type = ttype, num_tubes = num_tubes}
|
return {pos = pos, param2 = param2, type = ttype, num_tubes = num_tubes}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Determine a tube side without connection, increment the number of connections
|
||||||
|
-- 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)
|
function Tube:add_tube_dir(pos, dir)
|
||||||
local npos, node = get_next_node(pos, dir)
|
local npos, node = get_next_node(pos, dir)
|
||||||
if self.primary_node_names[node.name] then
|
if self.primary_node_names[node.name] then
|
||||||
@ -314,7 +350,9 @@ function Tube:add_tube_dir(pos, dir)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Decrement the number of tube connections
|
||||||
|
-- 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)
|
function Tube:del_tube_dir(pos, dir)
|
||||||
local npos, node = get_next_node(pos, dir)
|
local npos, node = get_next_node(pos, dir)
|
||||||
if self.primary_node_names[node.name] then
|
if self.primary_node_names[node.name] then
|
||||||
@ -323,84 +361,94 @@ function Tube:del_tube_dir(pos, dir)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Return the param2 stored tube dirs
|
||||||
function Tube:get_tube_dirs(pos)
|
function Tube:get_tube_dirs(pos)
|
||||||
local node = minetest.get_node(pos)
|
local _, node = get_next_node(pos)
|
||||||
if self.primary_node_names[node.name] then
|
if self.primary_node_names[node.name] then
|
||||||
local d1, d2 = self:decode_param2(node.param2)
|
local d1, d2 = self:decode_param2(node.param2)
|
||||||
return d1, d2
|
return d1, d2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Tube:get_next_tube(pos, dir)
|
|
||||||
local npos, node = get_next_node(pos, dir)
|
-- Go down the tube to the end position and
|
||||||
local dir1, dir2, num = self:decode_param2(node.param2)
|
-- return pos, dir to the next node, and num tubes
|
||||||
if self.primary_node_names[node.name] then
|
function Tube:find_tube_head(pos)
|
||||||
if Turn180Deg[dir] == dir1 then
|
local get_next_tube = function(self, pos, dir)
|
||||||
return npos, dir2
|
-- Return pos and dir to the next node of the tube node at pos/dir
|
||||||
else
|
local npos, node = get_next_node(pos, dir)
|
||||||
return npos, dir1
|
local dir1, dir2, num = self:decode_param2(node.param2)
|
||||||
|
if self.primary_node_names[node.name] then
|
||||||
|
if Turn180Deg[dir] == dir1 then
|
||||||
|
return npos, dir2
|
||||||
|
else
|
||||||
|
return npos, dir1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
function Tube:find_tube_head(pos)
|
|
||||||
local cnt = 0
|
local cnt = 0
|
||||||
local dir = nil
|
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
|
||||||
|
|
||||||
while cnt <= self.max_tube_length do
|
while cnt <= self.max_tube_length do
|
||||||
local new_pos, new_dir = self:get_next_tube(pos, dir)
|
local new_pos, new_dir = get_next_tube(self, pos, dir)
|
||||||
if not new_dir then break end
|
if not new_dir then break end
|
||||||
|
print(P(new_pos), new_dir)
|
||||||
pos, dir = new_pos, new_dir
|
pos, dir = new_pos, new_dir
|
||||||
cnt = cnt + 1
|
cnt = cnt + 1
|
||||||
end
|
end
|
||||||
return pos, dir
|
return pos, dir, cnt
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Set tube to a 2 connection node without meta data
|
||||||
-- Do a correction of param2, delete meta data and
|
function Tube:set_2_conn_tube(pos)
|
||||||
-- return the new pos, dir
|
local npos, node = get_next_node(pos)
|
||||||
function Tube:repair_next_tube(pos, dir)
|
|
||||||
local npos, node = get_next_node(pos, dir)
|
|
||||||
if self.primary_node_names[node.name] then
|
if self.primary_node_names[node.name] then
|
||||||
local dir1, dir2, num = self:decode_param2(node.param2)
|
local dir1, dir2, _ = self:decode_param2(node.param2)
|
||||||
if num ~= 2 then
|
node.param2 = self:encode_param2(dir1, dir2, 2)
|
||||||
node.param2 = self:encode_param2(dir1, dir2, 2)
|
minetest.set_node(npos, node)
|
||||||
minetest.set_node(npos, node)
|
|
||||||
end
|
|
||||||
M(npos):from_table(nil)
|
M(npos):from_table(nil)
|
||||||
if Turn180Deg[dir] == dir1 then
|
|
||||||
return npos, dir2
|
|
||||||
else
|
|
||||||
return npos, dir1
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Do a correction of param2 and delete meta data of all 2-conn-tubes,
|
||||||
|
-- update the meta data of the head tubes and
|
||||||
|
-- return head-pos and number of nodes
|
||||||
function Tube:repair_tube_line(pos, dir)
|
function Tube:repair_tube_line(pos, dir)
|
||||||
|
local repair_next_tube = function(self, pos, dir)
|
||||||
|
local npos, node = 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
|
||||||
|
node.param2 = self:encode_param2(dir1, dir2, 2)
|
||||||
|
minetest.set_node(npos, node)
|
||||||
|
end
|
||||||
|
M(npos):from_table(nil)
|
||||||
|
if Turn180Deg[dir] == dir1 then
|
||||||
|
return npos, dir2
|
||||||
|
else
|
||||||
|
return npos, dir1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local cnt = 0
|
local cnt = 0
|
||||||
if not dir then return pos, cnt end
|
if not dir then return pos, cnt end
|
||||||
while cnt <= self.max_tube_length do
|
while cnt <= self.max_tube_length do
|
||||||
local new_pos, new_dir = self:repair_next_tube(pos, dir)
|
local new_pos, new_dir = repair_next_tube(self, pos, dir)
|
||||||
if not new_dir then break end
|
if not new_dir then break end
|
||||||
pos, dir = new_pos, new_dir
|
pos, dir = new_pos, new_dir
|
||||||
cnt = cnt + 1
|
cnt = cnt + 1
|
||||||
end
|
end
|
||||||
return pos, cnt
|
return pos, dir, cnt
|
||||||
end
|
end
|
||||||
|
|
||||||
-- update meta data and set number of connections to 1 or 0
|
|
||||||
function Tube:update_head_tube(pos1, pos2, num_tubes)
|
|
||||||
local _, node = get_next_node(pos1)
|
|
||||||
local dir1, dir2, num = self:decode_param2(node.param2)
|
|
||||||
num = (self:connected(pos1, dir1) and 1 or 0) + (self:connected(pos1, dir2) and 1 or 0)
|
|
||||||
node.param2 = self:encode_param2(dir1, dir2, num)
|
|
||||||
minetest.set_node(pos1, node)
|
|
||||||
if self.show_infotext then
|
|
||||||
M(pos1):set_string("infotext", P(pos2).." / "..num_tubes.." tubes")
|
|
||||||
end
|
|
||||||
M(pos1):set_string("peer_pos", P(pos2))
|
|
||||||
end
|
|
||||||
|
|
||||||
function Tube:add_meta(pos1, pos2, num_tubes)
|
|
||||||
self:update_head_tube(pos1, pos2, num_tubes)
|
|
||||||
self:update_head_tube(pos2, pos1, num_tubes)
|
|
||||||
end
|
|
||||||
|
41
tube_api.lua
41
tube_api.lua
@ -47,7 +47,7 @@ function Tube:new(attr)
|
|||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Register (foreign) tubelib compatible nodes
|
-- Register (foreign) tubelib compatible nodes.
|
||||||
function Tube:add_secondary_node_names(names)
|
function Tube:add_secondary_node_names(names)
|
||||||
for _,name in ipairs(names) do
|
for _,name in ipairs(names) do
|
||||||
self.secondary_node_names[name] = true
|
self.secondary_node_names[name] = true
|
||||||
@ -57,23 +57,26 @@ end
|
|||||||
-- From node to node via tube
|
-- From node to node via tube
|
||||||
-- Used for item transportation via tubes
|
-- Used for item transportation via tubes
|
||||||
function Tube:get_connected_node_pos(pos, dir)
|
function Tube:get_connected_node_pos(pos, dir)
|
||||||
-- update_meta
|
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
|
return pos, dir
|
||||||
end
|
end
|
||||||
|
|
||||||
-- From tube head to tube head
|
-- From tube head to tube head.
|
||||||
|
-- Return pos and dir to the connected/next node.
|
||||||
function Tube:get_tube_end_pos(pos)
|
function Tube:get_tube_end_pos(pos)
|
||||||
local spos = M(pos):get_string("peer_pos")
|
local spos = M(pos):get_string("peer_pos")
|
||||||
if spos then
|
if spos ~= "" then
|
||||||
return S(spos)
|
return S(spos), M(pos):get_int("peer_dir")
|
||||||
end
|
end
|
||||||
local npos, num = self:find_tube_head(pos)
|
local npos, dir, num = self:find_tube_head(pos)
|
||||||
self:update_head_tube(pos, npos, num)
|
self:update_head_tube(pos, npos, dir, num)
|
||||||
return pos
|
return npos, dir
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- To be called after a tube node is placed
|
-- 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, placer, pointed_thing)
|
||||||
local preferred_pos, fdir = self:get_player_data(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)
|
local dir1, dir2, num_tubes = self:determine_tube_dirs(pos, preferred_pos, fdir)
|
||||||
@ -103,7 +106,7 @@ function Tube:update_tubes_after_place_node(pos, placer, pointed_thing)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- To be called after a tube node is removed
|
-- To be called after a tube node is removed.
|
||||||
function Tube:update_tubes_after_dig_node(pos, oldnode)
|
function Tube:update_tubes_after_dig_node(pos, oldnode)
|
||||||
local dir1, dir2, num_tubes = self:decode_param2(oldnode.param2)
|
local dir1, dir2, num_tubes = self:decode_param2(oldnode.param2)
|
||||||
local tbl = {}
|
local tbl = {}
|
||||||
@ -121,17 +124,19 @@ function Tube:update_tubes_after_dig_node(pos, oldnode)
|
|||||||
return tbl
|
return tbl
|
||||||
end
|
end
|
||||||
|
|
||||||
-- To be called from a repair tool
|
|
||||||
|
-- To be called from a repair tool in the case of a "WorldEdit" corrupted tube line.
|
||||||
function Tube:repair_tubes(pos)
|
function Tube:repair_tubes(pos)
|
||||||
local dir1, dir2 = self:get_tube_dirs(pos)
|
local d1, d2 = self:get_tube_dirs(pos)
|
||||||
self:repair_next_tube(pos)
|
self:set_2_conn_tube(pos)
|
||||||
local npos1, cnt1 = self:repair_tube_line(pos, dir1)
|
local npos1, dir1, cnt1 = self:repair_tube_line(pos, d1)
|
||||||
local npos2, cnt2 = self:repair_tube_line(pos, dir2)
|
local npos2, dir2, cnt2 = self:repair_tube_line(pos, d2)
|
||||||
self:add_meta(npos1, npos2, cnt1+cnt2+1)
|
self:add_meta_data(npos1, npos2, dir1, dir2, cnt1+cnt2+1)
|
||||||
return npos1, npos2, cnt1, cnt2
|
return npos1, npos2, dir1, dir2, cnt1, cnt2
|
||||||
end
|
end
|
||||||
|
|
||||||
-- To be called from a repair tool
|
|
||||||
|
-- To be called from a repair tool in the case, tube nodes are "unbreakable".
|
||||||
function Tube:remove_tube(pos, sound)
|
function Tube:remove_tube(pos, sound)
|
||||||
local dir1, dir2 = self:get_tube_dirs(pos)
|
local dir1, dir2 = self:get_tube_dirs(pos)
|
||||||
if dir1 and dir2 then
|
if dir1 and dir2 then
|
||||||
|
@ -177,9 +177,14 @@ end
|
|||||||
local function repair_tubes(itemstack, placer, pointed_thing)
|
local function repair_tubes(itemstack, placer, pointed_thing)
|
||||||
if pointed_thing.type == "node" then
|
if pointed_thing.type == "node" then
|
||||||
local pos = pointed_thing.under
|
local pos = pointed_thing.under
|
||||||
local pos1, pos2, cnt1, cnt2 = Tube:repair_tubes(pos)
|
if placer:get_player_control().sneak then
|
||||||
minetest.chat_send_player(placer:get_player_name(), "[Tubelib2] 1: "..P(pos1).." / "..cnt1.." tubes")
|
local end_pos, dir = Tube:get_tube_end_pos(pos)
|
||||||
minetest.chat_send_player(placer:get_player_name(), "[Tubelib2] 2: "..P(pos2).." / "..cnt2.." tubes")
|
minetest.chat_send_player(placer:get_player_name(), "[Tubelib2] end_pos = "..P(end_pos)..", dir = "..dir)
|
||||||
|
else
|
||||||
|
local pos1, pos2, dir1, dir2, cnt1, cnt2 = Tube:repair_tubes(pos)
|
||||||
|
minetest.chat_send_player(placer:get_player_name(), "[Tubelib2] 1: "..P(pos1)..", dir = "..dir1..", "..cnt1.." tubes")
|
||||||
|
minetest.chat_send_player(placer:get_player_name(), "[Tubelib2] 2: "..P(pos2)..", dir = "..dir2..", "..cnt2.." tubes")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user