techpack/tubelib/tubes2.lua
2018-06-21 20:38:56 +02:00

215 lines
5.3 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 function 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
-- 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
npos, ndir = remote_node(npos, ndir)
return npos, dir-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 res
local pitch = placer:get_look_pitch()
if pitch > 1 then
res = tubelib.update_tubes(pos, 6)
elseif pitch < -1 then
res = tubelib.update_tubes(pos, 5)
else
local dir = placer:get_look_dir()
local facedir = minetest.dir_to_facedir(dir)
res = tubelib.update_tubes(pos, facedir + 1)
end
if res == false 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"},
},
})