445 lines
13 KiB
Lua
445 lines
13 KiB
Lua
--[[
|
|
|
|
Tube Library 2
|
|
==============
|
|
|
|
Copyright (C) 2017-2020 Joachim Stolberg
|
|
|
|
LGPLv2.1+
|
|
See LICENSE.txt for more information
|
|
|
|
tube_test.lua
|
|
|
|
THIS FILE IS ONLY FOR TESTING PURPOSES
|
|
|
|
]]--
|
|
|
|
-- for lazy programmers
|
|
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
|
local S2P = minetest.string_to_pos
|
|
local M = minetest.get_meta
|
|
|
|
|
|
-- Marker entities for debugging purposes
|
|
local function debug_info(pos, text)
|
|
local marker = minetest.add_entity(pos, "tubelib2:marker_cube")
|
|
if marker ~= nil then
|
|
if text == "add" then
|
|
marker:set_nametag_attributes({color = "#FF0000", text = "add__________"})
|
|
elseif text == "del" then
|
|
marker:set_nametag_attributes({color = "#00FF00", text = "_____del_____"})
|
|
elseif text == "noc" then
|
|
marker:set_nametag_attributes({color = "#0000FF", text = "__________noc"})
|
|
end
|
|
minetest.after(6, marker.remove, marker)
|
|
end
|
|
end
|
|
|
|
minetest.register_entity(":tubelib2:marker_cube", {
|
|
initial_properties = {
|
|
visual = "cube",
|
|
textures = {
|
|
"tubelib2_marker_cube.png",
|
|
"tubelib2_marker_cube.png",
|
|
"tubelib2_marker_cube.png",
|
|
"tubelib2_marker_cube.png",
|
|
"tubelib2_marker_cube.png",
|
|
"tubelib2_marker_cube.png",
|
|
},
|
|
physical = false,
|
|
visual_size = {x = 1.1, y = 1.1},
|
|
collisionbox = {-0.55,-0.55,-0.55, 0.55,0.55,0.55},
|
|
glow = 8,
|
|
},
|
|
on_punch = function(self)
|
|
self.object:remove()
|
|
end,
|
|
})
|
|
|
|
-- Test tubes
|
|
local Tube = tubelib2.Tube:new({
|
|
-- North, East, South, West, Down, Up
|
|
-- dirs_to_check = {1,2,3,4}, -- horizontal only
|
|
-- dirs_to_check = {5,6}, -- vertical only
|
|
dirs_to_check = {1,2,3,4,5,6},
|
|
max_tube_length = 10,
|
|
show_infotext = true,
|
|
primary_node_names = {"tubelib2:tubeS", "tubelib2:tubeA"},
|
|
secondary_node_names = {"default:chest", "default:chest_open",
|
|
"tubelib2:source", "tubelib2:junction", "tubelib2:teleporter"},
|
|
after_place_tube = function(pos, param2, tube_type, num_tubes, tbl)
|
|
minetest.swap_node(pos, {name = "tubelib2:tube"..tube_type, param2 = param2})
|
|
end,
|
|
--debug_info = debug_info,
|
|
})
|
|
|
|
Tube:set_valid_sides("tubelib2:source", {"F"})
|
|
Tube:set_valid_sides("tubelib2:teleporter", {"F"})
|
|
|
|
Tube:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir)
|
|
local sdir = tubelib2.dir_to_string(out_dir)
|
|
if not peer_pos then
|
|
print(P2S(pos).." to the "..sdir..": Not connected")
|
|
elseif Tube:is_secondary_node(peer_pos) then
|
|
local node = minetest.get_node(peer_pos)
|
|
print(P2S(pos).." to the "..sdir..": Connected to "..node.name.." at "..P2S(peer_pos).."/"..peer_in_dir)
|
|
else
|
|
print(P2S(pos).." to the "..sdir..": Connected to "..P2S(peer_pos).."/"..peer_in_dir)
|
|
for i, pos, node in Tube:get_tube_line(pos, out_dir) do
|
|
print("walk", P2S(pos), node.name)
|
|
end
|
|
end
|
|
end)
|
|
|
|
|
|
minetest.register_node("tubelib2:tubeS", {
|
|
description = "Tubelib2 Test tube",
|
|
tiles = { -- Top, base, right, left, front, back
|
|
"tubelib2_tube.png",
|
|
"tubelib2_tube.png",
|
|
"tubelib2_tube.png",
|
|
"tubelib2_tube.png",
|
|
"tubelib2_hole.png",
|
|
"tubelib2_hole.png",
|
|
},
|
|
|
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
|
--local t = minetest.get_us_time()
|
|
if not Tube:after_place_tube(pos, placer, pointed_thing) then
|
|
minetest.remove_node(pos)
|
|
return true
|
|
end
|
|
--print("place time", minetest.get_us_time() - t)
|
|
return false
|
|
end,
|
|
|
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
|
Tube:after_dig_tube(pos, oldnode, oldmetadata)
|
|
end,
|
|
|
|
paramtype2 = "facedir", -- important!
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-2/8, -2/8, -4/8, 2/8, 2/8, 4/8},
|
|
},
|
|
},
|
|
on_rotate = screwdriver.disallow, -- important!
|
|
paramtype = "light",
|
|
use_texture_alpha = "clip",
|
|
sunlight_propagates = true,
|
|
is_ground_content = false,
|
|
groups = {crumbly = 3, cracky = 3, snappy = 3},
|
|
sounds = default.node_sound_glass_defaults(),
|
|
})
|
|
|
|
minetest.register_node("tubelib2:tubeA", {
|
|
description = "Tubelib2 Test tube",
|
|
tiles = { -- Top, base, right, left, front, back
|
|
"tubelib2_tube.png",
|
|
"tubelib2_hole.png",
|
|
"tubelib2_tube.png",
|
|
"tubelib2_tube.png",
|
|
"tubelib2_tube.png",
|
|
"tubelib2_hole.png",
|
|
},
|
|
|
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
|
Tube:after_dig_tube(pos, oldnode, oldmetadata)
|
|
end,
|
|
|
|
paramtype2 = "facedir", -- important!
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-2/8, -4/8, -2/8, 2/8, 2/8, 2/8},
|
|
{-2/8, -2/8, -4/8, 2/8, 2/8, -2/8},
|
|
},
|
|
},
|
|
on_rotate = screwdriver.disallow, -- important!
|
|
paramtype = "light",
|
|
use_texture_alpha = "clip",
|
|
sunlight_propagates = true,
|
|
is_ground_content = false,
|
|
groups = {crumbly = 3, cracky = 3, snappy = 3, not_in_creative_inventory=1},
|
|
sounds = default.node_sound_glass_defaults(),
|
|
drop = "tubelib2:tubeS",
|
|
})
|
|
|
|
local function push_item(pos)
|
|
local tube_dir = M(pos):get_int("tube_dir")
|
|
local dest_pos, dest_dir = Tube:get_connected_node_pos(pos, tube_dir)
|
|
local dest_node = minetest.get_node(dest_pos)
|
|
local on_push_item = minetest.registered_nodes[dest_node.name].on_push_item
|
|
--print("on_timer: dest_pos="..S(dest_pos).." dest_dir="..dest_dir)
|
|
local inv = minetest.get_inventory({type="node", pos=dest_pos})
|
|
local stack = ItemStack("default:dirt")
|
|
|
|
if on_push_item then
|
|
return on_push_item(dest_pos, dest_dir, stack)
|
|
elseif inv then
|
|
local leftover = inv:add_item("main", stack)
|
|
if leftover:get_count() == 0 then
|
|
return true
|
|
end
|
|
elseif dest_node.name == "air" then
|
|
minetest.add_item(dest_pos, stack)
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
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)
|
|
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})
|
|
end,
|
|
|
|
on_timer = function(pos, elapsed)
|
|
if not push_item(pos) then
|
|
print("push_item error")
|
|
end
|
|
return true
|
|
end,
|
|
|
|
paramtype2 = "facedir", -- important!
|
|
on_rotate = screwdriver.disallow, -- important!
|
|
is_ground_content = false,
|
|
groups = {crumbly = 3, cracky = 3, snappy = 3},
|
|
sounds = default.node_sound_glass_defaults(),
|
|
})
|
|
|
|
-- Can't be used for item transport (hyperloop test node)
|
|
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 "..P2S(pos))
|
|
Tube:after_place_node(pos)
|
|
end,
|
|
|
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
|
Tube:after_dig_node(pos)
|
|
end,
|
|
|
|
paramtype2 = "facedir", -- important!
|
|
on_rotate = screwdriver.disallow, -- important!
|
|
is_ground_content = false,
|
|
groups = {crumbly = 3, cracky = 3, snappy = 3},
|
|
sounds = default.node_sound_glass_defaults(),
|
|
})
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Teleporter
|
|
-------------------------------------------------------------------------------
|
|
local pairingList = {}
|
|
|
|
local sFormspec = "size[7.5,3]"..
|
|
"field[0.5,1;7,1;channel;Enter channel string;]" ..
|
|
"button_exit[2,2;3,1;exit;Save]"
|
|
|
|
local function store_connection(pos, peer_pos)
|
|
local meta = M(pos)
|
|
meta:set_string("peer_pos", P2S(peer_pos))
|
|
meta:set_string("channel", "")
|
|
meta:set_string("formspec", "")
|
|
meta:set_string("infotext", "Connected to "..P2S(peer_pos))
|
|
end
|
|
|
|
local function prepare_pairing(pos)
|
|
local meta = M(pos)
|
|
meta:set_string("peer_pos", "")
|
|
meta:set_string("channel", "")
|
|
meta:set_string("formspec", sFormspec)
|
|
meta:set_string("infotext", "Pairing is missing")
|
|
end
|
|
|
|
local function pairing(pos, channel)
|
|
if pairingList[channel] and not vector.equals(pos, pairingList[channel]) then
|
|
-- store peer position on both nodes
|
|
local peer_pos = pairingList[channel]
|
|
store_connection(pos, peer_pos)
|
|
store_connection(peer_pos, pos)
|
|
pairingList[channel] = nil
|
|
return true
|
|
else
|
|
pairingList[channel] = pos
|
|
prepare_pairing(pos)
|
|
return false
|
|
end
|
|
end
|
|
|
|
local function stop_pairing(pos, oldmetadata)
|
|
-- unpair peer node
|
|
if oldmetadata and oldmetadata.fields then
|
|
if oldmetadata.fields.peer_pos then
|
|
local peer_pos = S2P(oldmetadata.fields.peer_pos)
|
|
prepare_pairing(peer_pos)
|
|
elseif oldmetadata.fields.channel then
|
|
pairingList[oldmetadata.fields.channel] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
minetest.register_node("tubelib2:teleporter", {
|
|
description = "Tubelib2 Teleporter",
|
|
tiles = {
|
|
-- up, down, right, left, back, front
|
|
'tubelib2_tele.png',
|
|
'tubelib2_tele.png',
|
|
'tubelib2_tele.png',
|
|
'tubelib2_tele.png',
|
|
'tubelib2_tele.png',
|
|
'tubelib2_conn.png',
|
|
},
|
|
|
|
after_place_node = function(pos, placer)
|
|
-- 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
|
|
M(pos):set_int("tube_dir", tube_dir)
|
|
Tube:after_place_node(pos, {tube_dir})
|
|
prepare_pairing(pos)
|
|
end,
|
|
|
|
on_receive_fields = function(pos, formname, fields, player)
|
|
if fields.channel ~= nil then
|
|
pairing(pos, fields.channel)
|
|
end
|
|
end,
|
|
|
|
on_push_item = function(pos, dir, item)
|
|
local tube_dir = M(pos):get_int("tube_dir")
|
|
if dir == tubelib2.Turn180Deg[tube_dir] then
|
|
local s = M(pos):get_string("peer_pos")
|
|
if s and s ~= "" then
|
|
push_item(S2P(s))
|
|
return true
|
|
end
|
|
end
|
|
end,
|
|
|
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
|
stop_pairing(pos, oldmetadata)
|
|
local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0)
|
|
Tube:after_dig_node(pos, {tube_dir})
|
|
end,
|
|
|
|
paramtype2 = "facedir", -- important!
|
|
on_rotate = screwdriver.disallow, -- important!
|
|
is_ground_content = false,
|
|
groups = {crumbly = 3, cracky = 3, snappy = 3},
|
|
sounds = default.node_sound_glass_defaults(),
|
|
})
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Tool
|
|
-------------------------------------------------------------------------------
|
|
local function read_param2(pos, player)
|
|
local node = minetest.get_node(pos)
|
|
local dir1, dir2, num_tubes = Tube:decode_param2(pos, node.param2)
|
|
minetest.chat_send_player(player:get_player_name(), "[Tubelib2] pos="..P2S(pos)..", dir1="..dir1..", dir2="..dir2..", num_tubes="..num_tubes)
|
|
end
|
|
|
|
local function remove_tube(itemstack, placer, pointed_thing)
|
|
if pointed_thing.type == "node" then
|
|
local pos = pointed_thing.under
|
|
if placer:get_player_control().sneak then
|
|
read_param2(pos, placer)
|
|
else
|
|
Tube:tool_remove_tube(pos, "default_break_glass")
|
|
end
|
|
else
|
|
local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1
|
|
minetest.chat_send_player(placer:get_player_name(),
|
|
"[Tool Help] dir="..dir.."\n"..
|
|
" left: remove node\n"..
|
|
" right: repair tube line\n")
|
|
end
|
|
end
|
|
|
|
--local function walk(itemstack, placer, pointed_thing)
|
|
-- if pointed_thing.type == "node" then
|
|
-- local pos = pointed_thing.under
|
|
-- local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1
|
|
-- local t = minetest.get_us_time()
|
|
-- local pos1, outdir1, pos2, outdir2, cnt = Tube:walk(pos, dir)
|
|
-- t = minetest.get_us_time() - t
|
|
-- print("time", t)
|
|
-- if pos1 then
|
|
-- local s = "[Tubelib2] pos1="..P2S(pos1)..", outdir1="..outdir1..", pos2="..P2S(pos2)..", outdir2="..outdir2..", cnt="..cnt
|
|
-- minetest.chat_send_player(placer:get_player_name(), s)
|
|
-- end
|
|
-- else
|
|
-- local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1
|
|
-- minetest.chat_send_player(placer:get_player_name(),
|
|
-- "[Tool Help] dir="..dir.."\n"..
|
|
-- " left: remove node\n"..
|
|
-- " right: repair tube line\n")
|
|
-- end
|
|
--end
|
|
|
|
local function repair_tube(itemstack, placer, pointed_thing)
|
|
if pointed_thing.type == "node" then
|
|
local pos = pointed_thing.under
|
|
local _, _, fpos1, fpos2, _, _, cnt1, cnt2 = Tube:tool_repair_tube(pos)
|
|
local length = cnt1 + cnt2
|
|
|
|
local s = "Tube from " .. P2S(fpos1) .. " to " .. P2S(fpos2) .. ". Lenght = " .. length
|
|
minetest.chat_send_player(placer:get_player_name(), s)
|
|
|
|
if length > Tube.max_tube_length then
|
|
local s = string.char(0x1b) .. "(c@#ff0000)" .. "Tube length error!"
|
|
minetest.chat_send_player(placer:get_player_name(), s)
|
|
end
|
|
|
|
minetest.sound_play("carts_cart_new", {
|
|
pos = pos,
|
|
gain = 1,
|
|
max_hear_distance = 5})
|
|
else
|
|
local dir = (minetest.dir_to_facedir(placer:get_look_dir()) % 4) + 1
|
|
minetest.chat_send_player(placer:get_player_name(),
|
|
"[Tool Help] dir="..dir.."\n"..
|
|
" left: remove node\n"..
|
|
" right: repair tube line\n")
|
|
end
|
|
end
|
|
|
|
-- Tool for tube workers to crack a protected tube line
|
|
minetest.register_node("tubelib2:tool", {
|
|
description = "Tubelib2 Tool",
|
|
inventory_image = "tubelib2_tool.png",
|
|
wield_image = "tubelib2_tool.png",
|
|
use_texture_alpha = "clip",
|
|
groups = {cracky=1, book=1},
|
|
on_use = remove_tube,
|
|
on_place = repair_tube,
|
|
node_placement_prediction = "",
|
|
stack_max = 1,
|
|
})
|
|
|