mirror of
https://github.com/joe7575/techpack.git
synced 2024-12-26 15:37:30 +01:00
231 lines
5.8 KiB
Lua
231 lines
5.8 KiB
Lua
--[[
|
|
|
|
Tube Library
|
|
============
|
|
|
|
Copyright (C) 2017-2018 Joachim Stolberg
|
|
|
|
LGPLv2.1+
|
|
See LICENSE.txt for more information
|
|
|
|
History:
|
|
see init.lua
|
|
|
|
tubes2.lua: Node registration and API functions to move items via tubes
|
|
|
|
]]--
|
|
|
|
-- Convertion of contact side to facedir
|
|
local SideToFacedir = {B=0, R=1, F=2, L=3, D=4, U=5}
|
|
|
|
-- Calculate the facedir to the other node, based on both node positions
|
|
local function dir_to_facedir(my_pos, other_pos)
|
|
if my_pos.z ~= other_pos.z then return my_pos.z - other_pos.z + 1 end
|
|
if my_pos.x ~= other_pos.x then return my_pos.x - other_pos.x + 2 end
|
|
if my_pos.y > other_pos.y then return 5 else return 4 end
|
|
end
|
|
|
|
local function remote_node(pos, dir)
|
|
local meta = minetest.get_meta(pos)
|
|
local cnt
|
|
|
|
-- legacy tube?
|
|
if meta:get_string("dest_pos2") ~= "" then
|
|
meta:from_table(nil)
|
|
end
|
|
|
|
-- data available
|
|
local dest_pos = meta:get_string("dest_pos")
|
|
if dest_pos ~= "" then
|
|
local npos = minetest.string_to_pos(dest_pos)
|
|
local facedir = meta:get_int("facedir")
|
|
return npos, facedir+1
|
|
end
|
|
|
|
-- determine data and store as meta
|
|
cnt, pos, dir = tubelib.walk_to_peer(pos, dir)
|
|
local pos1,_ = tubelib.get_next_tube(pos, dir)
|
|
meta:set_string("dest_pos", minetest.pos_to_string(pos1))
|
|
meta:set_int("facedir", dir - 1)
|
|
|
|
return pos1, dir
|
|
end
|
|
|
|
local function is_known_node(pointed_thing)
|
|
if pointed_thing.type == "node" then
|
|
local node = minetest.get_node(pointed_thing.under)
|
|
if tubelib.KnownNodes[node.name] then
|
|
return pointed_thing.under
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
-- Determine neighbor position and own facedir to the node.
|
|
-- based on own pos and contact side 'B' - 'U'.
|
|
-- Function considers also tube connections.
|
|
function tubelib.get_neighbor_pos(pos, side)
|
|
local facedir = SideToFacedir[side]
|
|
local dir
|
|
if facedir < 4 then
|
|
local node = minetest.get_node(pos)
|
|
dir = ((facedir + node.param2) % 4) + 1
|
|
end
|
|
local npos, ndir = tubelib.get_next_tube(pos, dir)
|
|
local node = minetest.get_node(npos)
|
|
if tubelib.TubeNames[node.name] then
|
|
if ndir then
|
|
npos, ndir = remote_node(npos, ndir)
|
|
end
|
|
return npos, (ndir or 1) -1
|
|
end
|
|
return npos, facedir
|
|
end
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Node registration
|
|
-------------------------------------------------------------------------------
|
|
|
|
local DefNodeboxes = {
|
|
-- x1 y1 z1 x2 y2 z2
|
|
{ -1/4, -1/4, -1/4, 1/4, 1/4, 1/4 },
|
|
{ -1/4, -1/4, -1/4, 1/4, 1/4, 1/4 },
|
|
}
|
|
|
|
local DirCorrections = {
|
|
{3, 6}, {2, 5}, -- standard tubes
|
|
{3, 1}, {3, 2}, {3, 5}, -- knees from front to..
|
|
}
|
|
|
|
local SelectBoxes = {
|
|
{ -1/4, -1/4, -1/2, 1/4, 1/4, 1/2 },
|
|
{ -1/4, -1/2, -1/4, 1/4, 1/2, 1/4 },
|
|
{ -1/2, -1/4, -1/2, 1/4, 1/4, 1/4 },
|
|
{ -1/4, -1/2, -1/2, 1/4, 1/4, 1/4 },
|
|
{ -1/4, -1/4, -1/2, 1/4, 1/2, 1/4 },
|
|
}
|
|
|
|
local TilesData = {
|
|
-- up, down, right, left, back, front
|
|
{
|
|
"tubelib_tube.png^[transformR90",
|
|
"tubelib_tube.png^[transformR90",
|
|
"tubelib_tube.png",
|
|
"tubelib_tube.png",
|
|
"tubelib_hole.png",
|
|
"tubelib_hole.png",
|
|
},
|
|
{
|
|
"tubelib_hole.png",
|
|
"tubelib_hole.png",
|
|
"tubelib_tube.png^[transformR90",
|
|
"tubelib_tube.png^[transformR90",
|
|
"tubelib_tube.png^[transformR90",
|
|
"tubelib_tube.png^[transformR90",
|
|
},
|
|
{
|
|
"tubelib_knee.png^[transformR270",
|
|
"tubelib_knee.png^[transformR180",
|
|
"tubelib_knee2.png^[transformR270",
|
|
"tubelib_hole2.png^[transformR90",
|
|
"tubelib_knee2.png^[transformR90",
|
|
"tubelib_hole2.png^[transformR270",
|
|
},
|
|
{
|
|
"tubelib_knee2.png",
|
|
"tubelib_hole2.png^[transformR180",
|
|
"tubelib_knee.png^[transformR270",
|
|
"tubelib_knee.png",
|
|
"tubelib_knee2.png",
|
|
"tubelib_hole2.png",
|
|
},
|
|
{
|
|
"tubelib_hole2.png",
|
|
"tubelib_knee2.png^[transformR180",
|
|
"tubelib_knee.png^[transformR180",
|
|
"tubelib_knee.png^[transformR90",
|
|
"tubelib_knee2.png^[transformR180",
|
|
"tubelib_hole2.png^[transformR180",
|
|
},
|
|
}
|
|
|
|
|
|
for idx,pos in ipairs(DirCorrections) do
|
|
local node_box_data = table.copy(DefNodeboxes)
|
|
node_box_data[1][pos[1]] = node_box_data[1][pos[1]] * 2
|
|
node_box_data[2][pos[2]] = node_box_data[2][pos[2]] * 2
|
|
|
|
local tiles_data = TilesData[idx]
|
|
local hidden
|
|
|
|
if idx == 1 then
|
|
hidden = 0
|
|
else
|
|
hidden = 1
|
|
end
|
|
minetest.register_node("tubelib:tube"..idx, {
|
|
description = "Tubelib Tube",
|
|
tiles = tiles_data,
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = node_box_data,
|
|
},
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = SelectBoxes[idx],
|
|
},
|
|
collision_box = {
|
|
type = "fixed",
|
|
fixed = SelectBoxes[idx],
|
|
},
|
|
|
|
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
|
local dir1 = nil
|
|
local dir2 = nil
|
|
local pitch = placer:get_look_pitch()
|
|
local known_pos = is_known_node(pointed_thing)
|
|
local straight_ahead = placer:get_player_control().sneak and not known_pos
|
|
if known_pos and placer:get_player_control().sneak then -- placer pointed to a known node (chest)
|
|
dir2 = dir_to_facedir(pos, known_pos) + 1
|
|
end
|
|
if pitch > 1 then -- up?
|
|
dir1 = 6
|
|
elseif pitch < -1 then -- down?
|
|
dir1 = 5
|
|
else
|
|
dir1 = minetest.dir_to_facedir(placer:get_look_dir()) + 1
|
|
end
|
|
if not tubelib.update_tubes(pos, dir1, dir2, straight_ahead) then
|
|
tubelib.delete_meta_data(pos, minetest.get_node(pos))
|
|
minetest.remove_node(pos)
|
|
return itemstack
|
|
end
|
|
end,
|
|
|
|
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
|
tubelib.delete_meta_data(pos, oldnode)
|
|
end,
|
|
|
|
on_rotate = screwdriver.disallow,
|
|
paramtype2 = "facedir",
|
|
paramtype = "light",
|
|
sunlight_propagates = true,
|
|
is_ground_content = false,
|
|
groups = {choppy=2, cracky=3, stone=1, not_in_creative_inventory=hidden},
|
|
drop = "tubelib:tube1",
|
|
sounds = default.node_sound_wood_defaults(),
|
|
})
|
|
end
|
|
|
|
|
|
minetest.register_craft({
|
|
output = "tubelib:tube1 4",
|
|
recipe = {
|
|
{"default:steel_ingot", "", "group:wood"},
|
|
{"", "group:wood", ""},
|
|
{"group:wood", "", "default:tin_ingot"},
|
|
},
|
|
})
|