mirror of
https://github.com/joe7575/tubelib2.git
synced 2024-11-28 10:23:45 +01:00
v0.4 - on_update function for secondary nodes introduced
This commit is contained in:
parent
e3ae449a7b
commit
e04f493667
@ -43,9 +43,8 @@ The 3 free MSB bits of param2 of tube nodes are used to store the number of conn
|
||||
|
||||
The data of the peer head tube are stored as meta data: "peer_pos" and "peer_dir"
|
||||
|
||||
Tubelib2 provides no update mechanism for connected "secondary" nodes.
|
||||
That means, all secondary nodes have to check their surrounding for any changes,
|
||||
based on player interaction and/or on LBM basis.
|
||||
Tubelib2 provides an update mechanism for connected "secondary" nodes. A callback function
|
||||
"tubelib2_on_update" will be called for every change on the connected tubes.
|
||||
|
||||
|
||||
|
||||
@ -64,3 +63,4 @@ default
|
||||
- 2018-10-20 v0.1 * Tested against hyperloop elevator.
|
||||
- 2018-10-27 v0.2 * Tested against and enhanced for the hyperloop mod.
|
||||
- 2018-10-27 v0.3 * Further improvements.
|
||||
- 2018-11-09 v0.4 * on_update function for secondary nodes introduced
|
||||
|
@ -35,7 +35,7 @@ end
|
||||
|
||||
function Tube:convert_tube_line(pos, dir)
|
||||
local convert_next_tube = function(self, pos, dir)
|
||||
local npos, node = self:get_next_node(pos, dir)
|
||||
local npos, node = self:get_node(pos, dir)
|
||||
if self.legacy_node_names[node.name] then
|
||||
local dir1, dir2, num
|
||||
if self.convert_tube_clbk then
|
||||
|
116
design.txt
116
design.txt
@ -55,52 +55,90 @@ 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()
|
||||
update_after_place_node()
|
||||
get_meta()
|
||||
repair_tube_line()
|
||||
get_pos()
|
||||
update_secondary_node()
|
||||
|
||||
after_place_tube()
|
||||
update_after_place_tube()
|
||||
del_meta()
|
||||
repair_tube_line()
|
||||
add_meta()
|
||||
update_secondary_node()
|
||||
|
||||
after_dig_node()
|
||||
Tube:update_tubes_after_dig_node()
|
||||
decode_param2()
|
||||
del_tube_dir()
|
||||
del_meta_data()
|
||||
decode_param2()
|
||||
tube_data_to_table()
|
||||
update_after_dig_node()
|
||||
get_meta()
|
||||
repair_tube_line()
|
||||
get_pos()
|
||||
add_meta()
|
||||
update_secondary_node()
|
||||
|
||||
on_timer()
|
||||
Tube:get_connected_node_pos()
|
||||
after_dig_tube()
|
||||
update_after_dig_tube()
|
||||
get_meta()
|
||||
repair_tube_line()
|
||||
get_pos()
|
||||
add_meta()
|
||||
update_secondary_node()
|
||||
|
||||
Wifi:after_place_node()
|
||||
Tube:prepare_pairing()
|
||||
del_meta_data()
|
||||
get_connected_node_pos()
|
||||
get_meta()
|
||||
repair_tube_line()
|
||||
get_pos()
|
||||
|
||||
Wifi:on_receive_fields()
|
||||
Tube:pairing()
|
||||
store_teleport_data()
|
||||
del_meta_data()
|
||||
tool_repair_tubes()
|
||||
determine_dirs()
|
||||
repair_tube_line()
|
||||
add_meta()
|
||||
update_secondary_node()
|
||||
|
||||
Wifi:on_destruct()
|
||||
Tube:stop_pairing()
|
||||
del_meta_data()
|
||||
tool_remove_tube()
|
||||
remove_tube()
|
||||
repair_tube_line()
|
||||
get_pos()
|
||||
add_meta()
|
||||
update_secondary_node()
|
||||
|
||||
Tool:repair_tubes()
|
||||
Tube:repair_tubes()
|
||||
get_tube_dirs()
|
||||
repair_tube_line()
|
||||
add_meta_data()
|
||||
update_head_tube()
|
||||
#####################################################################
|
||||
|
||||
primary_node()
|
||||
secondary_node()
|
||||
get_primary_dir()
|
||||
get_pos()
|
||||
|
||||
del_meta()
|
||||
get_meta()
|
||||
add_meta()
|
||||
|
||||
repair_tube_line()
|
||||
update_secondary_node()
|
||||
|
||||
update_after_place_node()
|
||||
update_after_dig_node()
|
||||
update_after_place_tube()
|
||||
update_after_dig_tube()
|
||||
|
||||
#####################################################################
|
||||
|
||||
|
||||
|
||||
Neuer Ansatz
|
||||
============
|
||||
|
||||
+------+ +------+
|
||||
|peer->| |<-peer|
|
||||
| |<--------------->| |
|
||||
|dir-> | | <-dir|
|
||||
+------+ +------+
|
||||
|
||||
Beim Setzen eines Nodes x werden immer die Meta-Daten in f1 und f2 aktualisiert
|
||||
sowie die Secundary Update-Funktion von S1 und S2 aufgerufen.
|
||||
|
||||
[S1][f1]----[n1] x [n2]----[f2][S2]
|
||||
|
||||
Tool:remove_tube()
|
||||
Tube:remove_tube()
|
||||
get_tube_dirs()
|
||||
friendly_primary_node()
|
||||
repair_tubes()
|
||||
|
5
init.lua
5
init.lua
@ -1,7 +1,8 @@
|
||||
tubelib2 = {}
|
||||
|
||||
dofile(minetest.get_modpath("tubelib2") .. "/tube_api.lua")
|
||||
dofile(minetest.get_modpath("tubelib2") .. "/internal.lua")
|
||||
dofile(minetest.get_modpath("tubelib2") .. "/internal2.lua")
|
||||
dofile(minetest.get_modpath("tubelib2") .. "/internal1.lua")
|
||||
dofile(minetest.get_modpath("tubelib2") .. "/convert.lua")
|
||||
-- Only for testing/demo purposes
|
||||
--dofile(minetest.get_modpath("tubelib2") .. "/tube_test.lua")
|
||||
dofile(minetest.get_modpath("tubelib2") .. "/tube_test.lua")
|
||||
|
249
internal1.lua
Normal file
249
internal1.lua
Normal file
@ -0,0 +1,249 @@
|
||||
--[[
|
||||
|
||||
Tube Library 2
|
||||
==============
|
||||
|
||||
Copyright (C) 2018 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
internal1.lua
|
||||
|
||||
First level functions behind the API
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local S = minetest.pos_to_string
|
||||
local P = minetest.string_to_pos
|
||||
local M = minetest.get_meta
|
||||
|
||||
local Tube = tubelib2.Tube
|
||||
local Turn180Deg = tubelib2.Turn180Deg
|
||||
local Dir6dToVector = tubelib2.Dir6dToVector
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
-- node get/test functions
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
-- Check if node at given position is a tube node
|
||||
-- If dir == nil then node_pos = pos
|
||||
-- Function returns the new pos or nil
|
||||
function Tube:primary_node(pos, dir)
|
||||
local npos, node = self:get_node(pos, dir)
|
||||
if self.primary_node_names[node.name] then
|
||||
return npos
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if node at given position is a secondary node
|
||||
-- If dir == nil then node_pos = pos
|
||||
-- Function returns the new pos or nil
|
||||
function Tube:secondary_node(pos, dir)
|
||||
local npos, node = self:get_node(pos, dir)
|
||||
if self.secondary_node_names[node.name] then
|
||||
return npos
|
||||
end
|
||||
end
|
||||
|
||||
-- Used to determine the node side to the tube connection.
|
||||
-- Function returns the first found dir value
|
||||
-- to a primary node.
|
||||
-- Only used by convert.set_pairing()
|
||||
function Tube:get_primary_dir(pos)
|
||||
-- Check all valid positions
|
||||
for dir = 1,6 do
|
||||
if self:primary_node(pos, dir) then
|
||||
return dir
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Return the new pos behind pos/dir and the dir our of the node.
|
||||
function Tube:get_pos(pos, dir)
|
||||
return vector.add(pos, Dir6dToVector[dir or 0]), Turn180Deg[dir]
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
-- get/del/add meta data functions
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
function Tube:del_meta(pos, dir)
|
||||
local npos, node = self:get_node(pos, dir)
|
||||
if self.primary_node_names[node.name] then
|
||||
local meta = M(npos)
|
||||
local peer_pos = meta:get_string("peer_pos")
|
||||
local peer_dir = meta:get_int("peer_dir")
|
||||
meta:from_table(nil)
|
||||
if peer_pos ~= "" then
|
||||
return P(peer_pos), peer_dir
|
||||
end
|
||||
end
|
||||
return self:repair_tube_line(pos, dir)
|
||||
end
|
||||
|
||||
function Tube:get_meta(pos, dir)
|
||||
local npos = vector.add(pos, Dir6dToVector[dir or 0])
|
||||
local meta = M(npos)
|
||||
local peer_pos = meta:get_string("peer_pos")
|
||||
local peer_dir = meta:get_int("peer_dir")
|
||||
if peer_pos ~= "" then
|
||||
return P(peer_pos), peer_dir
|
||||
end
|
||||
return self:repair_tube_line(pos, dir)
|
||||
end
|
||||
|
||||
function Tube:get_oldmeta(pos, dir, oldmetadata)
|
||||
if oldmetadata.fields and oldmetadata.fields.peer_pos then
|
||||
return P(oldmetadata.fields.peer_pos), tonumber(oldmetadata.fields.peer_dir)
|
||||
end
|
||||
return self:repair_tube_line(pos, dir)
|
||||
end
|
||||
|
||||
-- Add meta data from the other tube head node
|
||||
function Tube:add_meta(pos, peer_pos, peer_dir)
|
||||
local _, node = self:get_node(pos)
|
||||
if self.primary_node_names[node.name] then
|
||||
if self.show_infotext then
|
||||
M(pos):set_string("infotext", S(peer_pos))
|
||||
end
|
||||
M(pos):set_string("peer_pos", S(peer_pos))
|
||||
M(pos):set_int("peer_dir", peer_dir)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
-- Further helper functions
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
-- Do a correction of param2, delete meta data of all 2-conn-tubes,
|
||||
-- and return peer_pos, peer_dir, and number of tube nodes.
|
||||
function Tube:repair_tube_line(pos, dir)
|
||||
local repair_next_tube = function(self, pos, dir)
|
||||
local npos, dir1, dir2 = self:determine_next_node(pos, dir)
|
||||
if dir1 then
|
||||
M(npos):from_table(nil)
|
||||
if Turn180Deg[dir] == dir1 then
|
||||
return npos, dir2
|
||||
else
|
||||
return npos, dir1
|
||||
end
|
||||
end
|
||||
return self:get_next_teleport_node(pos, dir)
|
||||
end
|
||||
|
||||
local cnt = 0
|
||||
if not dir then return pos, dir, cnt end
|
||||
while cnt <= self.max_tube_length do
|
||||
--if cnt > 1 then M(pos):from_table(nil) end
|
||||
local new_pos, new_dir = repair_next_tube(self, pos, dir)
|
||||
if not new_dir then break end
|
||||
pos, dir = new_pos, new_dir
|
||||
cnt = cnt + 1
|
||||
end
|
||||
return pos, dir, cnt
|
||||
end
|
||||
|
||||
-- fpos,fdir points to the secondary node to be updated.
|
||||
-- npos,ndir are used to calculate the connection data to be written.
|
||||
function Tube:update_secondary_node(fpos,fdir, npos,ndir)
|
||||
-- [s]<-[n]----[f]->[s]
|
||||
local fpos2, node = self:get_node(fpos, fdir)
|
||||
if minetest.registered_nodes[node.name].tubelib2_on_update then
|
||||
local npos2 = self:get_pos(npos, ndir)
|
||||
minetest.registered_nodes[node.name].tubelib2_on_update(fpos2, npos2, ndir)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
-- pairing functions
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
-- Pairing helper function
|
||||
function Tube:store_teleport_data(pos, peer_pos)
|
||||
local meta = M(pos)
|
||||
meta:set_string("tele_pos", S(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
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- update-after/get-dir functions
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function Tube:update_after_place_node(pos, dirs)
|
||||
-- Check all valid positions
|
||||
local lRes= {}
|
||||
dirs = dirs or self.dirs_to_check
|
||||
for _,dir in ipairs(dirs) do
|
||||
local npos, d1, d2, num = self:add_tube_dir(pos, dir)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
lRes[#lRes+1] = dir
|
||||
end
|
||||
end
|
||||
return lRes
|
||||
end
|
||||
|
||||
function Tube:update_after_dig_node(pos, dirs)
|
||||
-- Check all valid positions
|
||||
local lRes= {}
|
||||
dirs = dirs or self.dirs_to_check
|
||||
for _,dir in ipairs(dirs) do
|
||||
local npos, d1, d2, num = self:del_tube_dir(pos, dir)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
lRes[#lRes+1] = dir
|
||||
end
|
||||
end
|
||||
return lRes
|
||||
end
|
||||
|
||||
function Tube:update_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 false
|
||||
end
|
||||
|
||||
self.clbk_after_place_tube(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
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
end
|
||||
|
||||
if num_tubes >= 2 then
|
||||
local npos, d1, d2, num = self:add_tube_dir(pos, dir2)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
end
|
||||
return true, dir1, dir2
|
||||
end
|
||||
|
||||
function Tube:update_after_dig_tube(pos, param2)
|
||||
local dir1, dir2, num_tubes = self:decode_param2(pos, param2)
|
||||
|
||||
local lRes = {}
|
||||
local npos, d1, d2, num = self:del_tube_dir(pos, dir1)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
lRes[#lRes+1] = dir1
|
||||
end
|
||||
|
||||
npos, d1, d2, num = self:del_tube_dir(pos, dir2)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
lRes[#lRes+1] = dir2
|
||||
end
|
||||
return lRes
|
||||
end
|
||||
|
@ -114,6 +114,38 @@ end
|
||||
|
||||
local Tube = tubelib2.Tube
|
||||
|
||||
function Tube:fdir(player)
|
||||
local pitch = player:get_look_pitch()
|
||||
if pitch > 1.1 and self.allowed_6d_dirs[6] then -- up?
|
||||
return 6
|
||||
elseif pitch < -1.1 and self.allowed_6d_dirs[5] then -- down?
|
||||
return 5
|
||||
elseif not self.allowed_6d_dirs[1] then
|
||||
return 6
|
||||
else
|
||||
return minetest.dir_to_facedir(player:get_look_dir()) + 1
|
||||
end
|
||||
end
|
||||
|
||||
function Tube:get_player_data(placer, pointed_thing)
|
||||
if placer and pointed_thing and pointed_thing.type == "node" then
|
||||
if placer:get_player_control().sneak then
|
||||
return pointed_thing.under, self:fdir(placer)
|
||||
else
|
||||
return nil, self:fdir(placer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Return param2 and tube type ("A"/"S")
|
||||
function Tube:encode_param2(dir1, dir2, num_conn)
|
||||
if dir1 > dir2 then
|
||||
dir1, dir2 = dir2, dir1
|
||||
end
|
||||
local param2, _type = unpack(DirToParam2[dir1 * 10 + dir2] or {0, "S"})
|
||||
return (num_conn * 32) + param2, _type
|
||||
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])
|
||||
@ -138,15 +170,6 @@ function Tube:determine_dir1_dir2_and_num_conn(pos)
|
||||
end
|
||||
end
|
||||
|
||||
-- Return param2 and tube type ("A"/"S")
|
||||
function Tube:encode_param2(dir1, dir2, num_conn)
|
||||
if dir1 > dir2 then
|
||||
dir1, dir2 = dir2, dir1
|
||||
end
|
||||
local param2, _type = unpack(DirToParam2[dir1 * 10 + dir2] or {0, "S"})
|
||||
return (num_conn * 32) + param2, _type
|
||||
end
|
||||
|
||||
-- Return dir1, dir2, num_conn
|
||||
function Tube:decode_param2(pos, param2)
|
||||
local val = Param2ToDir[param2 % 32]
|
||||
@ -161,23 +184,14 @@ function Tube:decode_param2(pos, param2)
|
||||
end
|
||||
|
||||
-- Return node next to pos in direction 'dir'
|
||||
function Tube:get_next_node(pos, dir)
|
||||
function Tube:get_node(pos, dir)
|
||||
local npos = vector.add(pos, Dir6dToVector[dir or 0])
|
||||
return npos, get_node_lvm(npos)
|
||||
end
|
||||
|
||||
-- Return the param2 stored tube dirs or 5,6
|
||||
function Tube:get_tube_dirs(pos)
|
||||
local node = get_node_lvm(pos)
|
||||
if self.primary_node_names[node.name] then
|
||||
return self:decode_param2(pos, node.param2)
|
||||
end
|
||||
return 5,6
|
||||
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 = self:get_next_node(pos, dir)
|
||||
local npos, node = self:get_node(pos, dir)
|
||||
if self.primary_node_names[node.name] then
|
||||
local _,_,num_conn = self:decode_param2(npos, node.param2)
|
||||
-- tube node with max one connection?
|
||||
@ -185,91 +199,6 @@ function Tube:friendly_primary_node(pos, dir)
|
||||
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_node_lvm(pos1)
|
||||
if self.primary_node_names[node.name] then
|
||||
local d1, d2, num = self:decode_param2(pos1, node.param2)
|
||||
if d1 and d2 then
|
||||
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
|
||||
end
|
||||
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)
|
||||
if not vector.equals(pos1, pos2) then
|
||||
self:update_head_tube(pos2, pos1, dir1, num_tubes)
|
||||
end
|
||||
end
|
||||
|
||||
-- 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 and self.allowed_6d_dirs[6] then -- up?
|
||||
return 6
|
||||
elseif pitch < -1.1 and self.allowed_6d_dirs[5] then -- down?
|
||||
return 5
|
||||
elseif not self.allowed_6d_dirs[1] then
|
||||
return 6
|
||||
else
|
||||
return minetest.dir_to_facedir(player:get_look_dir()) + 1
|
||||
end
|
||||
end
|
||||
|
||||
function Tube:get_player_data(placer, pointed_thing)
|
||||
if placer and pointed_thing and pointed_thing.type == "node" then
|
||||
if placer:get_player_control().sneak then
|
||||
return pointed_thing.under, self:fdir(placer)
|
||||
else
|
||||
return nil, self:fdir(placer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Check all 6 possible positions for known nodes considering preferred_pos
|
||||
-- and the players fdir and return dir1, dir2 and the number of tubes to connect to (0..2).
|
||||
function Tube:determine_tube_dirs(pos, preferred_pos, fdir)
|
||||
@ -347,18 +276,41 @@ function Tube:determine_tube_dirs(pos, preferred_pos, fdir)
|
||||
end
|
||||
end
|
||||
|
||||
function Tube:determine_next_node(pos, dir)
|
||||
local npos, node = self:get_node(pos, dir)
|
||||
if self.primary_node_names[node.name] then
|
||||
-- determine dirs on two ways
|
||||
local da1,da2,numa = self:decode_param2(npos, node.param2)
|
||||
local db1,db2,numb = self:determine_dir1_dir2_and_num_conn(npos)
|
||||
-- both identical?
|
||||
if da1 == db1 and da2 == db2 then
|
||||
return npos, da1, da2
|
||||
end
|
||||
-- test if stored dirs point to valid nodes
|
||||
if self:connected(npos, da1) and self:connected(npos, da2) then
|
||||
return npos, da1, da2
|
||||
end
|
||||
-- use and store the determined dirs
|
||||
if db1 and db2 then
|
||||
node.param2 = self:encode_param2(db1,db2,numb)
|
||||
minetest.set_node(npos, node)
|
||||
return npos, db1, db2
|
||||
end
|
||||
return npos, da1, da2
|
||||
end
|
||||
end
|
||||
|
||||
-- format and return given data as table
|
||||
function Tube:tube_data_to_table(pos, dir1, dir2, num_tubes)
|
||||
local param2, tube_type = self:encode_param2(dir1, dir2, num_tubes)
|
||||
return pos, param2, tube_type, num_tubes
|
||||
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)
|
||||
local npos, node = self:get_next_node(pos, dir)
|
||||
local npos, node = self:get_node(pos, dir)
|
||||
if self.primary_node_names[node.name] then
|
||||
local d1, d2, num = self:decode_param2(npos, node.param2)
|
||||
-- not already connected to the new tube?
|
||||
@ -383,112 +335,13 @@ 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 = self:get_next_node(pos, dir)
|
||||
local npos, node = self:get_node(pos, dir)
|
||||
if self.primary_node_names[node.name] then
|
||||
local d1, d2, num = self:decode_param2(npos, node.param2)
|
||||
return npos, d1, d2, math.max(num - 1, 0)
|
||||
end
|
||||
end
|
||||
|
||||
-- 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.pos, out_tbl.node.param2)
|
||||
if Turn180Deg[dir] == dir1 then
|
||||
out_tbl.dir = dir2
|
||||
else
|
||||
out_tbl.dir = dir1
|
||||
end
|
||||
return true
|
||||
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_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 = self:get_next_node(pos, dir)
|
||||
if self.primary_node_names[node.name] then
|
||||
local dir1, dir2, num = self:decode_param2(npos, node.param2)
|
||||
if Turn180Deg[dir] == dir1 then
|
||||
return npos, dir2
|
||||
else
|
||||
return npos, dir1
|
||||
end
|
||||
end
|
||||
|
||||
return self:get_next_teleport_node(npos)
|
||||
end
|
||||
|
||||
local cnt = 0
|
||||
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)
|
||||
if not new_dir then break end
|
||||
pos, dir = new_pos, new_dir
|
||||
cnt = cnt + 1
|
||||
end
|
||||
return pos, dir, cnt
|
||||
end
|
||||
|
||||
function Tube:determine_next_node(pos, dir)
|
||||
local npos, node = self:get_next_node(pos, dir)
|
||||
if self.primary_node_names[node.name] then
|
||||
-- determine dirs on two ways
|
||||
local da1,da2,numa = self:decode_param2(npos, node.param2)
|
||||
local db1,db2,numb = self:determine_dir1_dir2_and_num_conn(npos)
|
||||
-- both identical?
|
||||
if da1 == db1 and da2 == db2 then
|
||||
return npos, da1, da2
|
||||
end
|
||||
-- test if stored dirs point to valid nodes
|
||||
if self:connected(npos, da1) and self:connected(npos, da2) then
|
||||
return npos, da1, da2
|
||||
end
|
||||
-- use and store the determined dirs
|
||||
if db1 and db2 then
|
||||
node.param2 = self:encode_param2(db1,db2,numb)
|
||||
minetest.set_node(npos, node)
|
||||
return npos, db1, db2
|
||||
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)
|
||||
local repair_next_tube = function(self, pos, dir)
|
||||
local npos, dir1, dir2 = self:determine_next_node(pos, dir)
|
||||
if dir1 then
|
||||
M(npos):from_table(nil)
|
||||
if Turn180Deg[dir] == dir1 then
|
||||
return npos, dir2
|
||||
else
|
||||
return npos, dir1
|
||||
end
|
||||
end
|
||||
return self:get_next_teleport_node(pos, dir)
|
||||
end
|
||||
|
||||
local cnt = 0
|
||||
if not dir then return pos, cnt end
|
||||
while cnt <= self.max_tube_length do
|
||||
local new_pos, new_dir = repair_next_tube(self, pos, dir)
|
||||
if not new_dir then break end
|
||||
pos, dir = new_pos, new_dir
|
||||
cnt = cnt + 1
|
||||
end
|
||||
return pos, dir, cnt
|
||||
end
|
||||
|
||||
-- Pairing helper function
|
||||
function Tube:store_teleport_data(pos, peer_pos)
|
||||
local meta = M(pos)
|
||||
@ -499,51 +352,29 @@ function Tube:store_teleport_data(pos, peer_pos)
|
||||
return meta:get_int("tube_dir")
|
||||
end
|
||||
|
||||
function Tube:get_peer_tube_head(node_tbl, dir)
|
||||
-- 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)
|
||||
if pos2 then
|
||||
self:add_meta_data(node_tbl.pos, pos2, Turn180Deg[dir], dir2, cnt+1)
|
||||
return pos2, dir2
|
||||
-- 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
|
||||
|
||||
-- pos is the position of the removed node
|
||||
-- dir1, dir2 are the neighbor sides to be checked for meta data
|
||||
-- oldmetadata is also used to check for meta data
|
||||
-- If meta data is found (peer_pos), it is used to determine the tube head.
|
||||
function Tube:delete_tube_meta_data(pos, dir1, dir2, oldmetadata)
|
||||
-- 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
|
||||
function Tube:remove_tube(pos, sound)
|
||||
local node = get_node_lvm(pos)
|
||||
if self.primary_node_names[node.name] then
|
||||
minetest.sound_play({
|
||||
name=sound},{
|
||||
gain=1,
|
||||
max_hear_distance=5,
|
||||
loop=false})
|
||||
minetest.remove_node(pos)
|
||||
return node, {}
|
||||
end
|
||||
end
|
||||
end
|
297
tube_api.lua
297
tube_api.lua
@ -13,10 +13,11 @@
|
||||
]]--
|
||||
|
||||
-- Version for compatibility checks, see readme.md/history
|
||||
tubelib2.version = 0.3
|
||||
tubelib2.version = 0.4
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local S = minetest.pos_to_string
|
||||
|
||||
local Dir2Str = {"north", "east", "south", "west", "down", "up"}
|
||||
|
||||
@ -32,43 +33,17 @@ local function Tbl(list)
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function after_place_node(self, pos)
|
||||
-- Check all valid positions
|
||||
for dir = 1,6 do
|
||||
if self.allowed_6d_dirs[dir] then
|
||||
self:delete_tube_meta_data(pos, dir)
|
||||
local npos, d1, d2, num = self:add_tube_dir(pos, dir)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function after_dig_node(self, pos)
|
||||
-- Check all valid positions
|
||||
for dir = 1,6 do
|
||||
if self.allowed_6d_dirs[dir] then
|
||||
self:delete_tube_meta_data(pos, dir)
|
||||
local npos, d1, d2, num = self:del_tube_dir(pos, dir)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Tubelib2 Class
|
||||
tubelib2.Tube = {}
|
||||
local Tube = tubelib2.Tube
|
||||
|
||||
--
|
||||
-- API Functions
|
||||
--
|
||||
|
||||
-- Tubelib2 Class
|
||||
tubelib2.Tube = {}
|
||||
local Tube = tubelib2.Tube
|
||||
|
||||
function Tube:new(attr)
|
||||
local o = {
|
||||
allowed_6d_dirs = attr.allowed_6d_dirs or {true, true, true, true, true, true},
|
||||
dirs_to_check = attr.dirs_to_check or {1,2,3,4,5,6},
|
||||
max_tube_length = attr.max_tube_length or 1000,
|
||||
primary_node_names = Tbl(attr.primary_node_names or {}),
|
||||
secondary_node_names = Tbl(attr.secondary_node_names or {}),
|
||||
@ -77,6 +52,7 @@ function Tube:new(attr)
|
||||
clbk_after_place_tube = attr.after_place_tube,
|
||||
pairingList = {}, -- teleporting nodes
|
||||
}
|
||||
o.allowed_6d_dirs = Tbl(o.dirs_to_check)
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
@ -89,207 +65,100 @@ function Tube:add_secondary_node_names(names)
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if node at given position is a tube node
|
||||
-- If dir == nil then node_pos = pos
|
||||
-- Function returns the new pos or nil
|
||||
function Tube:primary_node(pos, dir)
|
||||
local npos, node = self:get_next_node(pos, dir)
|
||||
if self.primary_node_names[node.name] then
|
||||
return npos
|
||||
-- To be called after a secondary node is placed.
|
||||
-- dirs is a list with valid dirs, like: {1,2,3,4}
|
||||
function Tube:after_place_node(pos, dirs)
|
||||
-- [s][f]----[n] x
|
||||
-- s..secondary, f..far, n..near, x..node to be placed
|
||||
for _,dir in ipairs(self:update_after_place_node(pos, dirs)) do
|
||||
local fpos,fdir = self:get_meta(pos, dir)
|
||||
local npos, ndir = self:get_pos(pos, dir)
|
||||
self:update_secondary_node(fpos,fdir, npos,ndir)
|
||||
self:update_secondary_node(npos,ndir, fpos,fdir)
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if node at given position is a secondary node
|
||||
-- If dir == nil then node_pos = pos
|
||||
-- Function returns the new pos or nil
|
||||
function Tube:secondary_node(pos, dir)
|
||||
local npos, node = self:get_next_node(pos, dir)
|
||||
if self.secondary_node_names[node.name] then
|
||||
return npos
|
||||
-- To be called after a tube/primary node is placed.
|
||||
function Tube:after_place_tube(pos, placer, pointed_thing)
|
||||
-- [s1][f1]----[n1] x [n2]-----[f2][s2]
|
||||
-- s..secondary, f..far, n..near, x..node to be placed
|
||||
local res,dir1,dir2 = self:update_after_place_tube(pos, placer, pointed_thing)
|
||||
if res then
|
||||
local fpos1,fdir1 = self:del_meta(pos, dir1)
|
||||
local fpos2,fdir2 = self:del_meta(pos, dir2)
|
||||
self:add_meta(fpos1, fpos2,fdir2)
|
||||
self:add_meta(fpos2, fpos1,fdir1)
|
||||
self:update_secondary_node(fpos1,fdir1, fpos2,fdir2)
|
||||
self:update_secondary_node(fpos2,fdir2, fpos1,fdir1)
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
function Tube:after_dig_node(pos, dirs)
|
||||
-- [s][f]----[n] x
|
||||
-- s..secondary, f..far, n..near, x..node to be removed
|
||||
for _,dir in ipairs(self:update_after_dig_node(pos, dirs)) do
|
||||
local fpos,fdir = self:get_meta(pos, dir)
|
||||
local npos,ndir = self:get_pos(pos, dir)
|
||||
self:add_meta(npos, fpos,fdir)
|
||||
self:add_meta(fpos, npos,ndir)
|
||||
self:update_secondary_node(fpos,fdir, npos,ndir)
|
||||
end
|
||||
end
|
||||
|
||||
-- Used to determine the node side to the tube connection.
|
||||
-- Function returns the first found dir value
|
||||
-- to a primary node.
|
||||
function Tube:get_primary_dir(pos)
|
||||
-- Check all valid positions
|
||||
for dir = 1,6 do
|
||||
if self:primary_node(pos, dir) then
|
||||
return dir
|
||||
end
|
||||
function Tube:after_dig_tube(pos, oldnode, oldmetadata)
|
||||
-- [s1][f1]----[n1] x [n2]-----[f2][s2]
|
||||
-- s..secondary, f..far, n..near, x..node to be removed
|
||||
for _,dir in ipairs(self:update_after_dig_tube(pos, oldnode.param2)) do
|
||||
local fpos,fdir = self:get_oldmeta(pos, dir, oldmetadata)
|
||||
local npos,ndir = self:get_pos(pos, dir)
|
||||
self:add_meta(npos, fpos,fdir)
|
||||
self:add_meta(fpos, npos,ndir)
|
||||
self:update_secondary_node(fpos,fdir, npos,ndir)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- 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)
|
||||
local node = {}
|
||||
if self:is_tube_head(pos, dir, node) then
|
||||
local npos, ndir = self:get_peer_tube_head(node, dir)
|
||||
return vector.add(npos, tubelib2.Dir6dToVector[ndir or 0]), ndir
|
||||
end
|
||||
return vector.add(pos, tubelib2.Dir6dToVector[dir or 0]), dir
|
||||
end
|
||||
|
||||
function Tube:beside(pos1, pos2)
|
||||
local pos = vector.subtract(pos1, pos2)
|
||||
local res = pos.x + pos.y + pos.z
|
||||
return res == 1 or res == -1
|
||||
end
|
||||
|
||||
-- From tube head to tube head.
|
||||
-- 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, dir)
|
||||
end
|
||||
return pos, dir
|
||||
end
|
||||
|
||||
|
||||
-- To be called after a secondary node is placed.
|
||||
function Tube:after_place_node(pos, dir1, dir2)
|
||||
if not dir1 and not dir2 then
|
||||
after_place_node(self, pos)
|
||||
return
|
||||
end
|
||||
|
||||
self:delete_tube_meta_data(pos, dir1, dir2)
|
||||
|
||||
if dir1 then
|
||||
local npos, d1, d2, num = self:add_tube_dir(pos, dir1)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(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
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- To be called after a tube/primary node is placed.
|
||||
function Tube: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 false
|
||||
end
|
||||
|
||||
self:delete_tube_meta_data(pos, dir1, dir2)
|
||||
|
||||
self.clbk_after_place_tube(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
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
end
|
||||
|
||||
if num_tubes >= 2 then
|
||||
local npos, d1, d2, num = self:add_tube_dir(pos, dir2)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
-- To be called after a secondary node is removed.
|
||||
function Tube:after_dig_node(pos, dir1, dir2)
|
||||
if not dir1 and not dir2 then
|
||||
after_dig_node(self, pos)
|
||||
return
|
||||
end
|
||||
|
||||
self:delete_tube_meta_data(pos, dir1, dir2)
|
||||
|
||||
local npos, d1, d2, num = self:del_tube_dir(pos, dir1)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
|
||||
npos, d1, d2, num = self:del_tube_dir(pos, dir2)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
end
|
||||
|
||||
-- To be called after a tube node is removed.
|
||||
function Tube:after_dig_tube(pos, oldnode, oldmetadata)
|
||||
local dir1, dir2, num_tubes = self:decode_param2(pos, oldnode.param2)
|
||||
|
||||
self:delete_tube_meta_data(pos, dir1, dir2, oldmetadata)
|
||||
|
||||
local npos, d1, d2, num = self:del_tube_dir(pos, dir1)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
|
||||
npos, d1, d2, num = self:del_tube_dir(pos, dir2)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
local fpos,fdir = self:get_meta(pos, dir)
|
||||
local npos,ndir = self:get_pos(fpos,fdir)
|
||||
return npos, dir
|
||||
end
|
||||
|
||||
|
||||
-- To be called from a repair tool in the case of a "WorldEdit" or with
|
||||
-- legacy nodes corrupted tube line.
|
||||
function Tube:tool_repair_tubes(pos)
|
||||
-- determine the dirs from pointed pos
|
||||
local npos, d1, d2 = self:determine_next_node(pos)
|
||||
M(pos):from_table(nil) -- delete meta data
|
||||
local npos1, dir1, cnt1 = self:repair_tube_line(pos, d1)
|
||||
local npos2, dir2, cnt2 = self:repair_tube_line(pos, d2)
|
||||
self:add_meta_data(npos1, npos2, dir1, dir2, cnt1+cnt2+1)
|
||||
return npos1, npos2, d1, d2, cnt1, cnt2
|
||||
function Tube:tool_repair_tube(pos)
|
||||
local res,dir1,dir2 = self:determine_next_node(pos)
|
||||
if res then
|
||||
local fpos1,fdir1,cnt1 = self:repair_tube_line(pos, dir1)
|
||||
local fpos2,fdir2,cnt2 = self:repair_tube_line(pos, dir2)
|
||||
self:add_meta(fpos1, fpos2,fdir2)
|
||||
self:add_meta(fpos2, fpos1,fdir1)
|
||||
self:update_secondary_node(fpos1,fdir1, fpos2,fdir2)
|
||||
self:update_secondary_node(fpos2,fdir2, fpos1,fdir1)
|
||||
return dir1, dir2, fpos1, fpos2, fdir1, fdir2, cnt1 or 0, cnt2 or 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- To be called from a repair tool in the case, tube nodes are "unbreakable".
|
||||
function Tube:tool_remove_tube(pos, sound)
|
||||
local dir1, dir2 = self:get_tube_dirs(pos)
|
||||
if dir1 ~= 0 then
|
||||
minetest.sound_play({
|
||||
name=sound},{
|
||||
gain=1,
|
||||
max_hear_distance=5,
|
||||
loop=false})
|
||||
minetest.remove_node(pos)
|
||||
|
||||
self:delete_tube_meta_data(pos, dir1, dir2)
|
||||
|
||||
local npos, d1, d2, num = self:del_tube_dir(pos, dir1)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
|
||||
npos, d1, d2, num = self:del_tube_dir(pos, dir2)
|
||||
if npos then
|
||||
self.clbk_after_place_tube(self:tube_data_to_table(npos, d1, d2, num))
|
||||
end
|
||||
local oldnode, oldmeta = self:remove_tube(pos, sound)
|
||||
if oldnode then
|
||||
self:after_dig_tube(pos, oldnode, oldmeta)
|
||||
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)
|
||||
@ -299,13 +168,19 @@ 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]
|
||||
|
||||
|
||||
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:delete_tube_meta_data(pos, tube_dir1)
|
||||
--self:delete_tube_meta_data(peer_pos, tube_dir2)
|
||||
local fpos1,fdir1 = self:repair_tube_line(pos, tube_dir1)
|
||||
local fpos2,fdir2 = self:repair_tube_line(peer_pos, tube_dir2)
|
||||
self:add_meta(fpos1, fpos2,fdir2)
|
||||
self:add_meta(fpos2, fpos1,fdir1)
|
||||
self:update_secondary_node(fpos1,fdir1, fpos2,fdir2)
|
||||
self:update_secondary_node(fpos2,fdir2, fpos1,fdir1)
|
||||
|
||||
self.pairingList[channel] = nil
|
||||
return true
|
||||
else
|
||||
@ -323,16 +198,12 @@ function Tube:stop_pairing(pos, oldmetadata, sFormspec)
|
||||
local tele_pos = minetest.string_to_pos(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"))
|
||||
|
||||
self:after_place_node(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
|
||||
|
@ -23,20 +23,20 @@ local M = minetest.get_meta
|
||||
|
||||
local Tube = tubelib2.Tube:new({
|
||||
-- North, East, South, West, Down, Up
|
||||
allowed_6d_dirs = {true, true, true, true, false, false}, -- horizontal only
|
||||
-- allowed_6d_dirs = {false, false, false, false, true, true}, -- vertical only
|
||||
dirs_to_check = {1,2,3,4}, -- horizontal only
|
||||
-- dirs_to_check = {5,6}, -- vertical only
|
||||
max_tube_length = 1000,
|
||||
show_infotext = false,
|
||||
primary_node_names = {"tubelib2:tubeS", "tubelib2:tubeA"},
|
||||
secondary_node_names = {"default:chest", "default:chest_open",
|
||||
"tubelib2:source", "tubelib2:teleporter"},
|
||||
"tubelib2:source", "tubelib2:junction", "tubelib2:teleporter"},
|
||||
after_place_tube = function(pos, param2, tube_type, num_tubes, tbl)
|
||||
minetest.set_node(pos, {name = "tubelib2:tube"..tube_type, param2 = param2})
|
||||
minetest.sound_play({
|
||||
name="default_place_node_glass"},{
|
||||
gain=1,
|
||||
max_hear_distance=5,
|
||||
loop=false})
|
||||
-- minetest.sound_play({
|
||||
-- name="default_place_node_glass"},{
|
||||
-- gain=1,
|
||||
-- max_hear_distance=5,
|
||||
-- loop=false})
|
||||
end,
|
||||
})
|
||||
|
||||
@ -71,7 +71,6 @@ minetest.register_node("tubelib2:tubeS", {
|
||||
{-2/8, -2/8, -4/8, 2/8, 2/8, 4/8},
|
||||
},
|
||||
},
|
||||
node_placement_prediction = "", -- important!
|
||||
on_rotate = screwdriver.disallow, -- important!
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
@ -104,7 +103,7 @@ minetest.register_node("tubelib2:tubeA", {
|
||||
{-2/8, -2/8, -4/8, 2/8, 2/8, -2/8},
|
||||
},
|
||||
},
|
||||
--on_rotate = screwdriver.disallow, -- important!
|
||||
on_rotate = screwdriver.disallow, -- important!
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
@ -133,13 +132,13 @@ minetest.register_node("tubelib2:source", {
|
||||
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)
|
||||
Tube:after_place_node(pos, tube_dir)
|
||||
Tube:after_place_node(pos, {tube_dir})
|
||||
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)
|
||||
Tube:after_dig_node(pos, tube_dir)
|
||||
Tube:after_dig_node(pos, {tube_dir})
|
||||
end,
|
||||
|
||||
on_timer = function(pos, elapsed)
|
||||
@ -172,6 +171,42 @@ minetest.register_node("tubelib2:source", {
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("tubelib2:junction", {
|
||||
description = "Tubelib2 Junction",
|
||||
tiles = {
|
||||
'tubelib2_conn.png',
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", "Position "..S(pos))
|
||||
Tube:after_place_node(pos)
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Tube:after_dig_node(pos)
|
||||
end,
|
||||
|
||||
tubelib2_on_update = function(pos, peer_pos, peer_dir)
|
||||
if Tube:secondary_node(peer_pos) then
|
||||
local sdir = tubelib2.dir_to_string(peer_dir)
|
||||
local node = minetest.get_node(peer_pos)
|
||||
print(S(pos).." connected with "..node.name)
|
||||
else
|
||||
local sdir = tubelib2.dir_to_string(peer_dir)
|
||||
print(S(pos).." connected with "..S(peer_pos))
|
||||
end
|
||||
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 = {
|
||||
@ -188,7 +223,7 @@ minetest.register_node("tubelib2:teleporter", {
|
||||
-- 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)
|
||||
Tube:after_place_node(pos, tube_dir)
|
||||
Tube:after_place_node(pos, {tube_dir})
|
||||
end,
|
||||
|
||||
on_receive_fields = function(pos, formname, fields, player)
|
||||
@ -200,7 +235,7 @@ minetest.register_node("tubelib2:teleporter", {
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Tube:stop_pairing(pos, oldmetadata, sFormspec)
|
||||
local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0)
|
||||
Tube:after_dig_node(pos, tube_dir)
|
||||
Tube:after_dig_node(pos, {tube_dir})
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir", -- important!
|
||||
@ -220,23 +255,27 @@ local function read_param2(pos, player)
|
||||
minetest.chat_send_player(player:get_player_name(), "[Tubelib2] param2 = "..node.param2.."/"..num.."/"..axis.."/"..rot)
|
||||
end
|
||||
|
||||
local function chat_message(dir, cnt, peer_pos, peer_dir)
|
||||
local sdir = tubelib2.dir_to_string(dir)
|
||||
if Tube:secondary_node(peer_pos, peer_dir) then
|
||||
local npos, node = Tube:get_node(peer_pos, peer_dir)
|
||||
return "[Tubelib2] To the "..sdir..": "..cnt.." tube nodes to "..node.name.." at "..S(npos)
|
||||
else
|
||||
return "[Tubelib2] To the "..sdir..": "..cnt.." tube nodes to "..S(peer_pos)
|
||||
end
|
||||
end
|
||||
|
||||
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, 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 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")
|
||||
end
|
||||
local t = minetest.get_us_time()
|
||||
local dir1, dir2, fpos1, fpos2, fdir1, fdir2, cnt1, cnt2 =
|
||||
Tube:tool_repair_tube(pos, placer, pointed_thing)
|
||||
t = minetest.get_us_time() - t
|
||||
print("time", t)
|
||||
if fpos1 and fpos2 then
|
||||
minetest.chat_send_player(placer:get_player_name(), chat_message(dir1, cnt1, fpos1, fdir1))
|
||||
minetest.chat_send_player(placer:get_player_name(), chat_message(dir2, cnt2, fpos2, fdir2))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user