tube_registration.lua 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. -- This file supplies the various kinds of pneumatic tubes
  2. local S = minetest.get_translator("pipeworks")
  3. local tubenodes = {}
  4. pipeworks.tubenodes = tubenodes
  5. minetest.register_alias("pipeworks:tube", "pipeworks:tube_000000")
  6. -- now, a function to define the tubes
  7. local REGISTER_COMPATIBILITY = true
  8. local vti = {4, 3, 2, 1, 6, 5}
  9. local default_noctrs = { "pipeworks_tube_noctr.png" }
  10. local default_plain = { "pipeworks_tube_plain.png" }
  11. local default_ends = { "pipeworks_tube_end.png" }
  12. local texture_mt = {
  13. __index = function(table, key)
  14. local size, idx = #table, tonumber(key)
  15. if size > 0 then -- avoid endless loops with empty tables
  16. while idx > size do idx = idx - size end
  17. return table[idx]
  18. end
  19. end
  20. }
  21. local register_one_tube = function(name, tname, dropname, desc, plain, noctrs, ends, short, inv, special, connects, style)
  22. noctrs = noctrs or default_noctrs
  23. setmetatable(noctrs, texture_mt)
  24. plain = plain or default_plain
  25. setmetatable(plain, texture_mt)
  26. ends = ends or default_ends
  27. setmetatable(ends, texture_mt)
  28. short = short or "pipeworks_tube_short.png"
  29. inv = inv or "pipeworks_tube_inv.png"
  30. local outboxes = {}
  31. local outsel = {}
  32. local outimgs = {}
  33. for i = 1, 6 do
  34. outimgs[vti[i]] = plain[i]
  35. end
  36. for _, v in ipairs(connects) do
  37. pipeworks.table_extend(outboxes, pipeworks.tube_boxes[v])
  38. table.insert(outsel, pipeworks.tube_selectboxes[v])
  39. outimgs[vti[v]] = noctrs[v]
  40. end
  41. if #connects == 1 then
  42. local v = connects[1]
  43. v = v-1 + 2*(v%2) -- Opposite side
  44. outimgs[vti[v]] = ends[v]
  45. end
  46. local tgroups = {snappy = 3, tube = 1, tubedevice = 1, not_in_creative_inventory = 1}
  47. local tubedesc = string.format("%s %s", desc, dump(connects))
  48. local iimg = type(plain[1]) == "table" and plain[1].name or plain[1]
  49. local wscale = {x = 1, y = 1, z = 1}
  50. if #connects == 0 then
  51. tgroups = {snappy = 3, tube = 1, tubedevice = 1}
  52. tubedesc = desc
  53. iimg=inv
  54. outimgs = {
  55. short, short,
  56. ends[3],ends[4],
  57. short, short
  58. }
  59. outboxes = { -24/64, -9/64, -9/64, 24/64, 9/64, 9/64 }
  60. outsel = { -24/64, -10/64, -10/64, 24/64, 10/64, 10/64 }
  61. wscale = {x = 1, y = 1, z = 0.01}
  62. end
  63. local rname = string.format("%s_%s", name, tname)
  64. table.insert(tubenodes, rname)
  65. local nodedef = {
  66. description = tubedesc,
  67. drawtype = "nodebox",
  68. tiles = outimgs,
  69. sunlight_propagates = true,
  70. inventory_image = iimg,
  71. wield_image = iimg,
  72. wield_scale = wscale,
  73. paramtype = "light",
  74. selection_box = {
  75. type = "fixed",
  76. fixed = outsel
  77. },
  78. node_box = {
  79. type = "fixed",
  80. fixed = outboxes
  81. },
  82. groups = tgroups,
  83. sounds = default.node_sound_wood_defaults(),
  84. walkable = true,
  85. stack_max = 99,
  86. basename = name,
  87. style = style,
  88. drop = string.format("%s_%s", name, dropname),
  89. tubelike = 1,
  90. tube = {
  91. connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1},
  92. priority = 50
  93. },
  94. after_place_node = pipeworks.after_place,
  95. after_dig_node = pipeworks.after_dig,
  96. on_rotate = false,
  97. on_blast = function(pos, intensity)
  98. if not intensity or intensity > 1 + 3^0.5 then
  99. minetest.remove_node(pos)
  100. return {string.format("%s_%s", name, dropname)}
  101. end
  102. minetest.swap_node(pos, {name = "pipeworks:broken_tube_1"})
  103. pipeworks.scan_for_tube_objects(pos)
  104. end,
  105. check_for_pole = pipeworks.check_for_vert_tube,
  106. check_for_horiz_pole = pipeworks.check_for_horiz_tube,
  107. tubenumber = tonumber(tname)
  108. }
  109. if style == "6d" then
  110. nodedef.paramtype2 = "facedir"
  111. end
  112. if special == nil then special = {} end
  113. for key, value in pairs(special) do
  114. --if key == "after_dig_node" or key == "after_place_node" then
  115. -- nodedef[key.."_"] = value
  116. if key == "groups" then
  117. for group, val in pairs(value) do
  118. nodedef.groups[group] = val
  119. end
  120. elseif key == "tube" then
  121. for key, val in pairs(value) do
  122. nodedef.tube[key] = val
  123. end
  124. else
  125. nodedef[key] = pipeworks.table_recursive_replace(value, "#id", tname)
  126. end
  127. end
  128. minetest.register_node(rname, nodedef)
  129. end
  130. local register_all_tubes = function(name, desc, plain, noctrs, ends, short, inv, special, old_registration)
  131. if old_registration then
  132. for xm = 0, 1 do
  133. for xp = 0, 1 do
  134. for ym = 0, 1 do
  135. for yp = 0, 1 do
  136. for zm = 0, 1 do
  137. for zp = 0, 1 do
  138. local connects = {}
  139. if xm == 1 then
  140. connects[#connects+1] = 1
  141. end
  142. if xp == 1 then
  143. connects[#connects+1] = 2
  144. end
  145. if ym == 1 then
  146. connects[#connects+1] = 3
  147. end
  148. if yp == 1 then
  149. connects[#connects+1] = 4
  150. end
  151. if zm == 1 then
  152. connects[#connects+1] = 5
  153. end
  154. if zp == 1 then
  155. connects[#connects+1] = 6
  156. end
  157. local tname = xm..xp..ym..yp..zm..zp
  158. register_one_tube(name, tname, "000000", desc, plain, noctrs, ends, short, inv, special, connects, "old")
  159. end
  160. end
  161. end
  162. end
  163. end
  164. end
  165. else
  166. -- 6d tubes: uses only 10 nodes instead of 64, but the textures must be rotated
  167. local cconnects = {{}, {1}, {1, 2}, {1, 3}, {1, 3, 5}, {1, 2, 3}, {1, 2, 3, 5}, {1, 2, 3, 4}, {1, 2, 3, 4, 5}, {1, 2, 3, 4, 5, 6}}
  168. for index, connects in ipairs(cconnects) do
  169. register_one_tube(name, tostring(index), "1", desc, plain, noctrs, ends, short, inv, special, connects, "6d")
  170. end
  171. if REGISTER_COMPATIBILITY then
  172. local cname = name.."_compatibility"
  173. minetest.register_node(cname, {
  174. drawtype = "airlike",
  175. style = "6d",
  176. basename = name,
  177. inventory_image = inv,
  178. wield_image = inv,
  179. paramtype = "light",
  180. sunlight_propagates = true,
  181. description = S("Pneumatic tube segment (legacy)"),
  182. after_place_node = pipeworks.after_place,
  183. groups = {not_in_creative_inventory = 1, tube_to_update = 1, tube = 1},
  184. tube = {connect_sides = {front = 1, back = 1, left = 1, right = 1, top = 1, bottom = 1}},
  185. drop = name.."_1",
  186. })
  187. table.insert(tubenodes, cname)
  188. for xm = 0, 1 do
  189. for xp = 0, 1 do
  190. for ym = 0, 1 do
  191. for yp = 0, 1 do
  192. for zm = 0, 1 do
  193. for zp = 0, 1 do
  194. local tname = xm..xp..ym..yp..zm..zp
  195. minetest.register_alias(name.."_"..tname, cname)
  196. end
  197. end
  198. end
  199. end
  200. end
  201. end
  202. end
  203. end
  204. end
  205. pipeworks.register_tube = function(name, def, ...)
  206. if type(def) == "table" then
  207. register_all_tubes(name, def.description,
  208. def.plain, def.noctr, def.ends, def.short,
  209. def.inventory_image, def.node_def, def.no_facedir)
  210. else
  211. -- we assert to be the old function with the second parameter being the description
  212. -- function(name, desc, plain, noctrs, ends, short, inv, special, old_registration)
  213. assert(type(def) == "string", "invalid arguments to pipeworks.register_tube")
  214. register_all_tubes(name, def, ...)
  215. end
  216. end
  217. if REGISTER_COMPATIBILITY then
  218. minetest.register_abm({
  219. nodenames = {"group:tube_to_update"},
  220. interval = 1,
  221. chance = 1,
  222. action = function(pos, node, active_object_count, active_object_count_wider)
  223. local minp = vector.subtract(pos, 1)
  224. local maxp = vector.add(pos, 1)
  225. if table.getn(minetest.find_nodes_in_area(minp, maxp, "ignore")) == 0 then
  226. pipeworks.scan_for_tube_objects(pos)
  227. end
  228. end
  229. })
  230. end