autoplace_tubes.lua 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. -- autorouting for pneumatic tubes
  2. local function is_tube(nodename)
  3. return pipeworks.table_contains(pipeworks.tubenodes, nodename)
  4. end
  5. --a function for determining which side of the node we are on
  6. local function nodeside(node, tubedir)
  7. if node.param2 < 0 or node.param2 > 23 then
  8. node.param2 = 0
  9. end
  10. local backdir = minetest.facedir_to_dir(node.param2)
  11. local back = pipeworks.vector_dot(backdir, tubedir)
  12. if back == 1 then
  13. return "back"
  14. elseif back == -1 then
  15. return "front"
  16. end
  17. local topdir = pipeworks.facedir_to_top_dir(node.param2)
  18. local top = pipeworks.vector_dot(topdir, tubedir)
  19. if top == 1 then
  20. return "top"
  21. elseif top == -1 then
  22. return "bottom"
  23. end
  24. local rightdir = pipeworks.facedir_to_right_dir(node.param2)
  25. local right = pipeworks.vector_dot(rightdir, tubedir)
  26. if right == 1 then
  27. return "right"
  28. else
  29. return "left"
  30. end
  31. end
  32. local vts = {0, 3, 1, 4, 2, 5}
  33. 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}
  34. 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}
  35. local function tube_autoroute(pos)
  36. local active = {0, 0, 0, 0, 0, 0}
  37. local nctr = minetest.get_node(pos)
  38. if not is_tube(nctr.name) then return end
  39. local adjustments = {
  40. {x = -1, y = 0, z = 0},
  41. {x = 1, y = 0, z = 0},
  42. {x = 0, y = -1, z = 0},
  43. {x = 0, y = 1, z = 0},
  44. {x = 0, y = 0, z = -1},
  45. {x = 0, y = 0, z = 1}
  46. }
  47. -- xm = 1, xp = 2, ym = 3, yp = 4, zm = 5, zp = 6
  48. local adjlist = {} -- this will be used in item_transport
  49. for i, adj in ipairs(adjustments) do
  50. local position = vector.add(pos, adj)
  51. local node = minetest.get_node(position)
  52. local idef = minetest.registered_nodes[node.name]
  53. -- handle the tubes themselves
  54. if is_tube(node.name) then
  55. active[i] = 1
  56. table.insert(adjlist, adj)
  57. -- handle new style connectors
  58. elseif idef and idef.tube and idef.tube.connect_sides then
  59. if idef.tube.connect_sides[nodeside(node, vector.multiply(adj, -1))] then
  60. active[i] = 1
  61. table.insert(adjlist, adj)
  62. end
  63. end
  64. end
  65. minetest.get_meta(pos):set_string("adjlist", minetest.serialize(adjlist))
  66. -- all sides checked, now figure which tube to use.
  67. local nodedef = minetest.registered_nodes[nctr.name]
  68. local basename = nodedef.basename
  69. if nodedef.style == "old" then
  70. local nsurround = ""
  71. for i, n in ipairs(active) do
  72. nsurround = nsurround..n
  73. end
  74. nctr.name = basename.."_"..nsurround
  75. elseif nodedef.style == "6d" then
  76. local s = 0
  77. for i, n in ipairs(active) do
  78. if n == 1 then
  79. s = s + 2^vts[i]
  80. end
  81. end
  82. nctr.name = basename.."_"..tube_table[s]
  83. nctr.param2 = tube_table_facedirs[s]
  84. end
  85. minetest.swap_node(pos, nctr)
  86. end
  87. function pipeworks.scan_for_tube_objects(pos)
  88. for side = 0, 6 do
  89. tube_autoroute(vector.add(pos, pipeworks.directions.side_to_dir(side)))
  90. end
  91. end
  92. function pipeworks.after_place(pos)
  93. pipeworks.scan_for_tube_objects(pos)
  94. end
  95. function pipeworks.after_dig(pos)
  96. pipeworks.scan_for_tube_objects(pos)
  97. end
  98. -- Screwdriver calls this function before rotating a node.
  99. -- However, connections must be updated *after* the node is rotated
  100. -- So, this function does the rotation itself and returns `true`.
  101. -- (Note: screwdriver already checks for protected areas.)
  102. -- This should only be used for tubes that don't autoconnect.
  103. -- (For example, one-way tubes.)
  104. -- Autoconnecting tubes will just revert back to their original state
  105. -- when they are updated.
  106. function pipeworks.on_rotate(pos, node, user, mode, new_param2)
  107. node.param2 = new_param2
  108. minetest.swap_node(pos, node)
  109. pipeworks.scan_for_tube_objects(pos)
  110. return true
  111. end
  112. if minetest.get_modpath("mesecons_mvps") then
  113. mesecon.register_on_mvps_move(function(moved_nodes)
  114. for _, n in ipairs(moved_nodes) do
  115. pipeworks.scan_for_tube_objects(n.pos)
  116. pipeworks.scan_for_tube_objects(n.oldpos)
  117. end
  118. end)
  119. end