pipeworks/autoplace_tubes.lua

140 lines
4.0 KiB
Lua
Raw Permalink Normal View History

-- autorouting for pneumatic tubes
2013-12-15 11:35:11 +01:00
local function is_tube(nodename)
return pipeworks.table_contains(pipeworks.tubenodes, nodename)
Multiple updates: 1) Refactor autoplace, There was a lot of redundant code and like a dozen unneccessary string scans for every node next to every tube placed! I put it all into indexed tables and loops instead of bizarre and unexplainable variable names and copy and pasted code. There was also no support for notifying a chest when an item has been taken from it by a filter, so I added something for that. I also thought it prudent to fall back on the allow_metadata_inventory_take function should a special can_remove not exist. In fact if can_insert doesn't exist, it calls allow_metadata_inventory_put instead. I also added a thing for allowing pipes to attach to nodes of other modules, without having to hard code type all those node names into autoplace.lua. Basically node.tube.collects(i,param2) and i is the direction from the pipe and param2 is the param2 of what it's pointing at. I also abstracted the inscrutable correlation between i and param2 by trial and error (and the paramwand mod) into understandable functions. There was no pipeworks namespace so I created it, and put these functions into pipeworks.collects (as distinguished from a node.tube.collects function, which uses those functions) And now it's too late to cart my old clothes to the thrift store, dangit. 2) My "node.tube.collects" idea might be redundant with the node.tube.connect_sides thing, though possibly more versatile so I'll leave it in. 3) I was using node.tube.connects and fancy functions for checking if it's the sides or top or whatnot, and this connect_side thing came in. This should make both my way and the way using connect_side work. Also removed some debugging cruft
2013-10-15 05:45:07 +02:00
end
--a function for determining which side of the node we are on
Multiple updates: 1) Refactor autoplace, There was a lot of redundant code and like a dozen unneccessary string scans for every node next to every tube placed! I put it all into indexed tables and loops instead of bizarre and unexplainable variable names and copy and pasted code. There was also no support for notifying a chest when an item has been taken from it by a filter, so I added something for that. I also thought it prudent to fall back on the allow_metadata_inventory_take function should a special can_remove not exist. In fact if can_insert doesn't exist, it calls allow_metadata_inventory_put instead. I also added a thing for allowing pipes to attach to nodes of other modules, without having to hard code type all those node names into autoplace.lua. Basically node.tube.collects(i,param2) and i is the direction from the pipe and param2 is the param2 of what it's pointing at. I also abstracted the inscrutable correlation between i and param2 by trial and error (and the paramwand mod) into understandable functions. There was no pipeworks namespace so I created it, and put these functions into pipeworks.collects (as distinguished from a node.tube.collects function, which uses those functions) And now it's too late to cart my old clothes to the thrift store, dangit. 2) My "node.tube.collects" idea might be redundant with the node.tube.connect_sides thing, though possibly more versatile so I'll leave it in. 3) I was using node.tube.connects and fancy functions for checking if it's the sides or top or whatnot, and this connect_side thing came in. This should make both my way and the way using connect_side work. Also removed some debugging cruft
2013-10-15 05:45:07 +02:00
local function nodeside(node, tubedir)
2014-08-14 16:22:03 +02:00
if node.param2 < 0 or node.param2 > 23 then
node.param2 = 0
end
local backdir = minetest.facedir_to_dir(node.param2)
local back = pipeworks.vector_dot(backdir, tubedir)
2014-08-14 16:22:03 +02:00
if back == 1 then
return "back"
2014-08-14 16:22:03 +02:00
elseif back == -1 then
return "front"
end
local topdir = pipeworks.facedir_to_top_dir(node.param2)
local top = pipeworks.vector_dot(topdir, tubedir)
2014-08-14 16:22:03 +02:00
if top == 1 then
return "top"
2014-08-14 16:22:03 +02:00
elseif top == -1 then
return "bottom"
end
local rightdir = pipeworks.facedir_to_right_dir(node.param2)
local right = pipeworks.vector_dot(rightdir, tubedir)
2014-08-14 16:22:03 +02:00
if right == 1 then
return "right"
2014-08-14 16:22:03 +02:00
else
return "left"
end
Multiple updates: 1) Refactor autoplace, There was a lot of redundant code and like a dozen unneccessary string scans for every node next to every tube placed! I put it all into indexed tables and loops instead of bizarre and unexplainable variable names and copy and pasted code. There was also no support for notifying a chest when an item has been taken from it by a filter, so I added something for that. I also thought it prudent to fall back on the allow_metadata_inventory_take function should a special can_remove not exist. In fact if can_insert doesn't exist, it calls allow_metadata_inventory_put instead. I also added a thing for allowing pipes to attach to nodes of other modules, without having to hard code type all those node names into autoplace.lua. Basically node.tube.collects(i,param2) and i is the direction from the pipe and param2 is the param2 of what it's pointing at. I also abstracted the inscrutable correlation between i and param2 by trial and error (and the paramwand mod) into understandable functions. There was no pipeworks namespace so I created it, and put these functions into pipeworks.collects (as distinguished from a node.tube.collects function, which uses those functions) And now it's too late to cart my old clothes to the thrift store, dangit. 2) My "node.tube.collects" idea might be redundant with the node.tube.connect_sides thing, though possibly more versatile so I'll leave it in. 3) I was using node.tube.connects and fancy functions for checking if it's the sides or top or whatnot, and this connect_side thing came in. This should make both my way and the way using connect_side work. Also removed some debugging cruft
2013-10-15 05:45:07 +02:00
end
2013-12-31 07:36:04 +01:00
local vts = {0, 3, 1, 4, 2, 5}
local tube_table = {[0] = 1, 2, 2, 4, 2, 4, 4, 5, 2, 3, 4, 6, 4, 6, 5, 7, 2, 4, 3, 6, 4, 5, 6, 7, 4, 6, 6, 8, 5, 7, 7, 9, 2, 4, 4, 5, 3, 6, 6, 7, 4, 6, 5, 7, 6, 8, 7, 9, 4, 5, 6, 7, 6, 7, 8, 9, 5, 7, 7, 9, 7, 9, 9, 10}
local tube_table_facedirs = {[0] = 0, 0, 5, 0, 3, 4, 3, 0, 2, 0, 2, 0, 6, 4, 3, 0, 7, 12, 5, 12, 7, 4, 5, 5, 18, 20, 16, 0, 7, 4, 7, 0, 1, 8, 1, 1, 1, 13, 1, 1, 10, 8, 2, 2, 17, 4, 3, 6, 9, 9, 9, 9, 21, 13, 1, 1, 10, 10, 11, 2, 19, 4, 3, 0}
2013-12-15 11:35:11 +01:00
local function tube_autoroute(pos)
Multiple updates: 1) Refactor autoplace, There was a lot of redundant code and like a dozen unneccessary string scans for every node next to every tube placed! I put it all into indexed tables and loops instead of bizarre and unexplainable variable names and copy and pasted code. There was also no support for notifying a chest when an item has been taken from it by a filter, so I added something for that. I also thought it prudent to fall back on the allow_metadata_inventory_take function should a special can_remove not exist. In fact if can_insert doesn't exist, it calls allow_metadata_inventory_put instead. I also added a thing for allowing pipes to attach to nodes of other modules, without having to hard code type all those node names into autoplace.lua. Basically node.tube.collects(i,param2) and i is the direction from the pipe and param2 is the param2 of what it's pointing at. I also abstracted the inscrutable correlation between i and param2 by trial and error (and the paramwand mod) into understandable functions. There was no pipeworks namespace so I created it, and put these functions into pipeworks.collects (as distinguished from a node.tube.collects function, which uses those functions) And now it's too late to cart my old clothes to the thrift store, dangit. 2) My "node.tube.collects" idea might be redundant with the node.tube.connect_sides thing, though possibly more versatile so I'll leave it in. 3) I was using node.tube.connects and fancy functions for checking if it's the sides or top or whatnot, and this connect_side thing came in. This should make both my way and the way using connect_side work. Also removed some debugging cruft
2013-10-15 05:45:07 +02:00
local active = {0, 0, 0, 0, 0, 0}
local nctr = minetest.get_node(pos)
if not is_tube(nctr.name) then return end
local adjustments = {
2014-08-14 16:22:03 +02:00
{x = -1, y = 0, z = 0},
{x = 1, y = 0, z = 0},
{x = 0, y = -1, z = 0},
{x = 0, y = 1, z = 0},
{x = 0, y = 0, z = -1},
{x = 0, y = 0, z = 1}
}
-- xm = 1, xp = 2, ym = 3, yp = 4, zm = 5, zp = 6
local adjlist = {} -- this will be used in item_transport
2014-08-14 16:22:03 +02:00
for i, adj in ipairs(adjustments) do
local position = vector.add(pos, adj)
local node = minetest.get_node(position)
local idef = minetest.registered_nodes[node.name]
-- handle the tubes themselves
if is_tube(node.name) then
active[i] = 1
table.insert(adjlist, adj)
-- handle new style connectors
elseif idef and idef.tube and idef.tube.connect_sides then
if idef.tube.connect_sides[nodeside(node, vector.multiply(adj, -1))] then
2014-08-14 16:22:03 +02:00
active[i] = 1
table.insert(adjlist, adj)
2014-08-14 16:22:03 +02:00
end
end
end
minetest.get_meta(pos):set_string("adjlist", minetest.serialize(adjlist))
-- all sides checked, now figure which tube to use.
Multiple updates: 1) Refactor autoplace, There was a lot of redundant code and like a dozen unneccessary string scans for every node next to every tube placed! I put it all into indexed tables and loops instead of bizarre and unexplainable variable names and copy and pasted code. There was also no support for notifying a chest when an item has been taken from it by a filter, so I added something for that. I also thought it prudent to fall back on the allow_metadata_inventory_take function should a special can_remove not exist. In fact if can_insert doesn't exist, it calls allow_metadata_inventory_put instead. I also added a thing for allowing pipes to attach to nodes of other modules, without having to hard code type all those node names into autoplace.lua. Basically node.tube.collects(i,param2) and i is the direction from the pipe and param2 is the param2 of what it's pointing at. I also abstracted the inscrutable correlation between i and param2 by trial and error (and the paramwand mod) into understandable functions. There was no pipeworks namespace so I created it, and put these functions into pipeworks.collects (as distinguished from a node.tube.collects function, which uses those functions) And now it's too late to cart my old clothes to the thrift store, dangit. 2) My "node.tube.collects" idea might be redundant with the node.tube.connect_sides thing, though possibly more versatile so I'll leave it in. 3) I was using node.tube.connects and fancy functions for checking if it's the sides or top or whatnot, and this connect_side thing came in. This should make both my way and the way using connect_side work. Also removed some debugging cruft
2013-10-15 05:45:07 +02:00
2013-12-31 07:36:04 +01:00
local nodedef = minetest.registered_nodes[nctr.name]
local basename = nodedef.basename
if nodedef.style == "old" then
local nsurround = ""
for _, n in ipairs(active) do
2014-08-14 16:22:03 +02:00
nsurround = nsurround..n
2013-12-31 07:36:04 +01:00
end
nctr.name = basename.."_"..nsurround
elseif nodedef.style == "6d" then
local s = 0
2014-08-14 16:22:03 +02:00
for i, n in ipairs(active) do
2013-12-31 07:36:04 +01:00
if n == 1 then
2014-08-14 16:22:03 +02:00
s = s + 2^vts[i]
2013-12-31 07:36:04 +01:00
end
end
nctr.name = basename.."_"..tube_table[s]
nctr.param2 = tube_table_facedirs[s]
end
minetest.swap_node(pos, nctr)
end
2013-12-15 11:35:11 +01:00
function pipeworks.scan_for_tube_objects(pos)
2014-08-14 16:22:03 +02:00
for side = 0, 6 do
tube_autoroute(vector.add(pos, pipeworks.directions.side_to_dir(side)))
2014-08-14 16:22:03 +02:00
end
2013-12-15 11:35:11 +01:00
end
function pipeworks.after_place(pos)
pipeworks.scan_for_tube_objects(pos)
end
function pipeworks.after_dig(pos)
pipeworks.scan_for_tube_objects(pos)
end
-- Screwdriver calls this function before rotating a node.
-- However, connections must be updated *after* the node is rotated
-- So, this function does the rotation itself and returns `true`.
-- (Note: screwdriver already checks for protected areas.)
-- This should only be used for tubes that don't autoconnect.
-- (For example, one-way tubes.)
-- Autoconnecting tubes will just revert back to their original state
-- when they are updated.
function pipeworks.on_rotate(pos, node, user, mode, new_param2)
node.param2 = new_param2
minetest.swap_node(pos, node)
pipeworks.scan_for_tube_objects(pos)
return true
end
2014-08-14 16:22:03 +02:00
if minetest.get_modpath("mesecons_mvps") then
mesecon.register_on_mvps_move(function(moved_nodes)
2014-01-03 13:29:38 +01:00
for _, n in ipairs(moved_nodes) do
pipeworks.scan_for_tube_objects(n.pos)
pipeworks.scan_for_tube_objects(n.oldpos)
end
end)
end