Pipeworks
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

746 lines
23 KiB

  1. local S = minetest.get_translator("pipeworks")
  2. local new_flow_logic_register = pipeworks.flowables.register
  3. local polys = ""
  4. if pipeworks.enable_lowpoly then polys = "_lowpoly" end
  5. -- rotation handlers
  6. function pipeworks.fix_after_rotation(pos, node, user, mode, new_param2)
  7. if string.find(node.name, "spigot") then new_param2 = new_param2 % 4 end
  8. newnode = string.gsub(node.name, "_on", "_off")
  9. minetest.swap_node(pos, { name = newnode, param2 = new_param2 })
  10. pipeworks.scan_for_pipe_objects(pos)
  11. return true
  12. end
  13. function pipeworks.rotate_on_place(itemstack, placer, pointed_thing)
  14. local playername = placer:get_player_name()
  15. if not minetest.is_protected(pointed_thing.under, playername)
  16. and not minetest.is_protected(pointed_thing.above, playername) then
  17. local node = minetest.get_node(pointed_thing.under)
  18. if (not placer:get_player_control().sneak)
  19. and minetest.registered_nodes[node.name]
  20. and minetest.registered_nodes[node.name].on_rightclick then
  21. minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack)
  22. else
  23. local pitch = placer:get_look_pitch()
  24. local above = pointed_thing.above
  25. local under = pointed_thing.under
  26. local fdir = minetest.dir_to_facedir(placer:get_look_dir())
  27. local undernode = minetest.get_node(under)
  28. local abovenode = minetest.get_node(above)
  29. local uname = undernode.name
  30. local aname = abovenode.name
  31. local isabove = (above.x == under.x) and (above.z == under.z) and (pitch > 0)
  32. local pos1 = above
  33. -- check if the object should be turned vertically
  34. if above.x == under.x
  35. and above.z == under.z
  36. and (
  37. string.find(uname, "pipeworks:pipe_")
  38. or string.find(uname, "pipeworks:storage_")
  39. or string.find(uname, "pipeworks:expansion_")
  40. or ( string.find(uname, "pipeworks:grating") and not isabove )
  41. or ( string.find(uname, "pipeworks:pump_") and not isabove )
  42. or (
  43. ( string.find(uname, "pipeworks:valve")
  44. or string.find(uname, "pipeworks:entry_panel")
  45. or string.find(uname, "pipeworks:flow_sensor") )
  46. and minetest.facedir_to_dir(undernode.param2).y ~= 0 )
  47. )
  48. then
  49. fdir = 17
  50. end
  51. if minetest.registered_nodes[uname]
  52. and minetest.registered_nodes[uname]["buildable_to"] then
  53. pos1 = under
  54. end
  55. if minetest.registered_nodes[minetest.get_node(pos1).name]
  56. and not minetest.registered_nodes[minetest.get_node(pos1).name]["buildable_to"] then return end
  57. local placednode = string.gsub(itemstack:get_name(), "_loaded", "_empty")
  58. placednode = string.gsub(placednode, "_on", "_off")
  59. minetest.swap_node(pos1, {name = placednode, param2 = fdir })
  60. pipeworks.scan_for_pipe_objects(pos1)
  61. if not pipeworks.expect_infinite_stacks then
  62. itemstack:take_item()
  63. end
  64. end
  65. end
  66. return itemstack
  67. end
  68. -- List of devices that should participate in the autoplace algorithm
  69. local pipereceptor_on = nil
  70. local pipereceptor_off = nil
  71. if minetest.get_modpath("mesecons") then
  72. pipereceptor_on = {
  73. receptor = {
  74. state = mesecon.state.on,
  75. rules = pipeworks.mesecons_rules
  76. }
  77. }
  78. pipereceptor_off = {
  79. receptor = {
  80. state = mesecon.state.off,
  81. rules = pipeworks.mesecons_rules
  82. }
  83. }
  84. end
  85. local pipes_devicelist = {
  86. "pump",
  87. "valve",
  88. "storage_tank_0",
  89. "storage_tank_1",
  90. "storage_tank_2",
  91. "storage_tank_3",
  92. "storage_tank_4",
  93. "storage_tank_5",
  94. "storage_tank_6",
  95. "storage_tank_7",
  96. "storage_tank_8",
  97. "storage_tank_9",
  98. "storage_tank_10"
  99. }
  100. -- Now define the nodes.
  101. local states = { "on", "off" }
  102. local dgroups = ""
  103. for s in ipairs(states) do
  104. if states[s] == "off" then
  105. dgroups = {snappy=3, pipe=1}
  106. else
  107. dgroups = {snappy=3, pipe=1, not_in_creative_inventory=1}
  108. end
  109. local pumpname = "pipeworks:pump_"..states[s]
  110. minetest.register_node(pumpname, {
  111. description = S("Pump/Intake Module"),
  112. drawtype = "mesh",
  113. mesh = "pipeworks_pump"..polys..".obj",
  114. tiles = { "pipeworks_pump_"..states[s]..".png" },
  115. paramtype = "light",
  116. paramtype2 = "facedir",
  117. groups = dgroups,
  118. sounds = default.node_sound_metal_defaults(),
  119. walkable = true,
  120. pipe_connections = { top = 1 },
  121. after_place_node = function(pos)
  122. pipeworks.scan_for_pipe_objects(pos)
  123. end,
  124. after_dig_node = function(pos)
  125. pipeworks.scan_for_pipe_objects(pos)
  126. end,
  127. drop = "pipeworks:pump_off",
  128. mesecons = {effector = {
  129. action_on = function (pos, node)
  130. minetest.swap_node(pos,{name="pipeworks:pump_on", param2 = node.param2})
  131. end,
  132. action_off = function (pos, node)
  133. minetest.swap_node(pos,{name="pipeworks:pump_off", param2 = node.param2})
  134. end
  135. }},
  136. on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
  137. local fdir = node.param2
  138. minetest.swap_node(pos, { name = "pipeworks:pump_"..states[3-s], param2 = fdir })
  139. end,
  140. on_rotate = screwdriver.rotate_simple
  141. })
  142. -- FIXME: this currently assumes that pumps can only rotate around the fixed axis pointing Y+.
  143. new_flow_logic_register.directional_vertical_fixed(pumpname, true)
  144. local pump_drive = 4
  145. if states[s] ~= "off" then
  146. new_flow_logic_register.intake_simple(pumpname, pump_drive)
  147. end
  148. local nodename_valve_empty = "pipeworks:valve_"..states[s].."_empty"
  149. minetest.register_node(nodename_valve_empty, {
  150. description = S("Valve"),
  151. drawtype = "mesh",
  152. mesh = "pipeworks_valve_"..states[s]..polys..".obj",
  153. tiles = { "pipeworks_valve.png" },
  154. sunlight_propagates = true,
  155. paramtype = "light",
  156. paramtype2 = "facedir",
  157. selection_box = {
  158. type = "fixed",
  159. fixed = { -5/16, -4/16, -8/16, 5/16, 5/16, 8/16 }
  160. },
  161. collision_box = {
  162. type = "fixed",
  163. fixed = { -5/16, -4/16, -8/16, 5/16, 5/16, 8/16 }
  164. },
  165. groups = dgroups,
  166. sounds = default.node_sound_metal_defaults(),
  167. walkable = true,
  168. on_place = pipeworks.rotate_on_place,
  169. after_dig_node = function(pos)
  170. pipeworks.scan_for_pipe_objects(pos)
  171. end,
  172. drop = "pipeworks:valve_off_empty",
  173. mesecons = {effector = {
  174. action_on = function (pos, node)
  175. minetest.swap_node(pos,{name="pipeworks:valve_on_empty", param2 = node.param2})
  176. end,
  177. action_off = function (pos, node)
  178. minetest.swap_node(pos,{name="pipeworks:valve_off_empty", param2 = node.param2})
  179. end
  180. }},
  181. on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
  182. local fdir = node.param2
  183. minetest.swap_node(pos, { name = "pipeworks:valve_"..states[3-s].."_empty", param2 = fdir })
  184. end,
  185. on_rotate = pipeworks.fix_after_rotation
  186. })
  187. -- only register flow logic for the "on" ABM.
  188. -- this means that the off state automatically blocks flow by not participating in the balancing operation.
  189. if states[s] ~= "off" then
  190. new_flow_logic_register.directional_horizonal_rotate(nodename_valve_empty, true)
  191. end
  192. end
  193. local nodename_valve_loaded = "pipeworks:valve_on_loaded"
  194. minetest.register_node(nodename_valve_loaded, {
  195. description = S("Valve"),
  196. drawtype = "mesh",
  197. mesh = "pipeworks_valve_on"..polys..".obj",
  198. tiles = { "pipeworks_valve.png" },
  199. sunlight_propagates = true,
  200. paramtype = "light",
  201. paramtype2 = "facedir",
  202. selection_box = {
  203. type = "fixed",
  204. fixed = { -5/16, -4/16, -8/16, 5/16, 5/16, 8/16 }
  205. },
  206. collision_box = {
  207. type = "fixed",
  208. fixed = { -5/16, -4/16, -8/16, 5/16, 5/16, 8/16 }
  209. },
  210. groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
  211. sounds = default.node_sound_metal_defaults(),
  212. walkable = true,
  213. on_place = pipeworks.rotate_on_place,
  214. after_dig_node = function(pos)
  215. pipeworks.scan_for_pipe_objects(pos)
  216. end,
  217. drop = "pipeworks:valve_off_empty",
  218. mesecons = {effector = {
  219. action_on = function (pos, node)
  220. minetest.swap_node(pos,{name="pipeworks:valve_on_empty", param2 = node.param2})
  221. end,
  222. action_off = function (pos, node)
  223. minetest.swap_node(pos,{name="pipeworks:valve_off_empty", param2 = node.param2})
  224. end
  225. }},
  226. on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
  227. local fdir = node.param2
  228. minetest.swap_node(pos, { name = "pipeworks:valve_off_empty", param2 = fdir })
  229. end,
  230. on_rotate = pipeworks.fix_after_rotation
  231. })
  232. -- register this the same as the on-but-empty variant, so existing nodes of this type work also.
  233. -- note that as new_flow_logic code does not distinguish empty/full in node states,
  234. -- right-clicking a "loaded" valve (becoming an off valve) then turning it on again will yield a on-but-empty valve,
  235. -- but the flow logic will still function.
  236. -- thus under new_flow_logic this serves as a kind of migration.
  237. new_flow_logic_register.directional_horizonal_rotate(nodename_valve_loaded, true)
  238. -- grating
  239. -- FIXME: should this do anything useful in the new flow logic?
  240. minetest.register_node("pipeworks:grating", {
  241. description = S("Decorative grating"),
  242. tiles = {
  243. "pipeworks_grating_top.png",
  244. "pipeworks_grating_sides.png",
  245. "pipeworks_grating_sides.png",
  246. "pipeworks_grating_sides.png",
  247. "pipeworks_grating_sides.png",
  248. "pipeworks_grating_sides.png"
  249. },
  250. drawtype = "nodebox",
  251. node_box = {
  252. type = "fixed",
  253. fixed = { -0.49, -0.49, -0.49, 0.49, 0.5, 0.49 }
  254. },
  255. sunlight_propagates = true,
  256. paramtype = "light",
  257. groups = {snappy=3, pipe=1},
  258. sounds = default.node_sound_metal_defaults(),
  259. walkable = true,
  260. pipe_connections = { top = 1 },
  261. after_place_node = function(pos)
  262. pipeworks.scan_for_pipe_objects(pos)
  263. end,
  264. after_dig_node = function(pos)
  265. pipeworks.scan_for_pipe_objects(pos)
  266. end,
  267. on_rotate = false
  268. })
  269. -- outlet spigot
  270. local nodename_spigot_empty = "pipeworks:spigot"
  271. minetest.register_node(nodename_spigot_empty, {
  272. description = S("Spigot outlet"),
  273. drawtype = "mesh",
  274. mesh = "pipeworks_spigot"..polys..".obj",
  275. tiles = { "pipeworks_spigot.png" },
  276. sunlight_propagates = true,
  277. paramtype = "light",
  278. paramtype2 = "facedir",
  279. groups = {snappy=3, pipe=1},
  280. sounds = default.node_sound_metal_defaults(),
  281. walkable = true,
  282. pipe_connections = { left=1, right=1, front=1, back=1,
  283. left_param2 = 3, right_param2 = 1, front_param2 = 2, back_param2 = 0 },
  284. after_place_node = function(pos)
  285. pipeworks.scan_for_pipe_objects(pos)
  286. end,
  287. after_dig_node = function(pos)
  288. pipeworks.scan_for_pipe_objects(pos)
  289. end,
  290. selection_box = {
  291. type = "fixed",
  292. fixed = { -2/16, -6/16, -2/16, 2/16, 2/16, 8/16 }
  293. },
  294. collision_box = {
  295. type = "fixed",
  296. fixed = { -2/16, -6/16, -2/16, 2/16, 2/16, 8/16 }
  297. },
  298. on_rotate = pipeworks.fix_after_rotation
  299. })
  300. local nodename_spigot_loaded = "pipeworks:spigot_pouring"
  301. minetest.register_node(nodename_spigot_loaded, {
  302. description = S("Spigot outlet"),
  303. drawtype = "mesh",
  304. mesh = "pipeworks_spigot_pouring"..polys..".obj",
  305. tiles = {
  306. {
  307. name = "default_water_flowing_animated.png",
  308. animation = {
  309. type = "vertical_frames",
  310. aspect_w = 16,
  311. aspect_h = 16,
  312. length = 0.8,
  313. },
  314. },
  315. { name = "pipeworks_spigot.png" }
  316. },
  317. sunlight_propagates = true,
  318. paramtype = "light",
  319. paramtype2 = "facedir",
  320. groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
  321. sounds = default.node_sound_metal_defaults(),
  322. walkable = true,
  323. pipe_connections = { left=1, right=1, front=1, back=1,
  324. left_param2 = 3, right_param2 = 1, front_param2 = 2, back_param2 = 0 },
  325. after_place_node = function(pos)
  326. minetest.set_node(pos, { name = "pipeworks:spigot", param2 = minetest.get_node(pos).param2 })
  327. pipeworks.scan_for_pipe_objects(pos)
  328. end,
  329. after_dig_node = function(pos)
  330. pipeworks.scan_for_pipe_objects(pos)
  331. end,
  332. selection_box = {
  333. type = "fixed",
  334. fixed = { -2/16, -6/16, -2/16, 2/16, 2/16, 8/16 }
  335. },
  336. collision_box = {
  337. type = "fixed",
  338. fixed = { -2/16, -6/16, -2/16, 2/16, 2/16, 8/16 }
  339. },
  340. drop = "pipeworks:spigot",
  341. on_rotate = pipeworks.fix_after_rotation
  342. })
  343. -- new flow logic does not currently distinguish between these two visual states.
  344. -- register both so existing flowing spigots continue to work (even if the visual doesn't match the spigot's behaviour).
  345. new_flow_logic_register.directional_horizonal_rotate(nodename_spigot_empty, false)
  346. new_flow_logic_register.directional_horizonal_rotate(nodename_spigot_loaded, false)
  347. local spigot_upper = 1.0
  348. local spigot_lower = 1.0
  349. local spigot_neighbours={{x=0, y=-1, z=0}}
  350. new_flow_logic_register.output_simple(nodename_spigot_empty, spigot_upper, spigot_lower, spigot_neighbours)
  351. new_flow_logic_register.output_simple(nodename_spigot_loaded, spigot_upper, spigot_lower, spigot_neighbours)
  352. -- sealed pipe entry/exit (horizontal pipe passing through a metal
  353. -- wall, for use in places where walls should look like they're airtight)
  354. local panel_cbox = {
  355. type = "fixed",
  356. fixed = {
  357. { -2/16, -2/16, -8/16, 2/16, 2/16, 8/16 },
  358. { -8/16, -8/16, -1/16, 8/16, 8/16, 1/16 }
  359. }
  360. }
  361. local nodename_panel_empty = "pipeworks:entry_panel_empty"
  362. minetest.register_node(nodename_panel_empty, {
  363. description = S("Airtight Pipe entry/exit"),
  364. drawtype = "mesh",
  365. mesh = "pipeworks_entry_panel"..polys..".obj",
  366. tiles = { "pipeworks_entry_panel.png" },
  367. paramtype = "light",
  368. paramtype2 = "facedir",
  369. groups = {snappy=3, pipe=1},
  370. sounds = default.node_sound_metal_defaults(),
  371. walkable = true,
  372. on_place = pipeworks.rotate_on_place,
  373. after_dig_node = function(pos)
  374. pipeworks.scan_for_pipe_objects(pos)
  375. end,
  376. selection_box = panel_cbox,
  377. collision_box = panel_cbox,
  378. on_rotate = pipeworks.fix_after_rotation
  379. })
  380. local nodename_panel_loaded = "pipeworks:entry_panel_loaded"
  381. minetest.register_node(nodename_panel_loaded, {
  382. description = S("Airtight Pipe entry/exit"),
  383. drawtype = "mesh",
  384. mesh = "pipeworks_entry_panel"..polys..".obj",
  385. tiles = { "pipeworks_entry_panel.png" },
  386. paramtype = "light",
  387. paramtype2 = "facedir",
  388. groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
  389. sounds = default.node_sound_metal_defaults(),
  390. walkable = true,
  391. on_place = pipeworks.rotate_on_place,
  392. after_dig_node = function(pos)
  393. pipeworks.scan_for_pipe_objects(pos)
  394. end,
  395. selection_box = panel_cbox,
  396. collision_box = panel_cbox,
  397. drop = "pipeworks:entry_panel_empty",
  398. on_rotate = pipeworks.fix_after_rotation
  399. })
  400. -- TODO: AFAIK the two panels have no visual difference, so are redundant under new flow logic - alias?
  401. new_flow_logic_register.directional_horizonal_rotate(nodename_panel_empty, true)
  402. new_flow_logic_register.directional_horizonal_rotate(nodename_panel_loaded, true)
  403. local nodename_sensor_empty = "pipeworks:flow_sensor_empty"
  404. minetest.register_node(nodename_sensor_empty, {
  405. description = S("Flow Sensor"),
  406. drawtype = "mesh",
  407. mesh = "pipeworks_flow_sensor"..polys..".obj",
  408. tiles = { "pipeworks_flow_sensor_off.png" },
  409. sunlight_propagates = true,
  410. paramtype = "light",
  411. paramtype2 = "facedir",
  412. groups = {snappy=3, pipe=1},
  413. sounds = default.node_sound_metal_defaults(),
  414. walkable = true,
  415. on_place = pipeworks.rotate_on_place,
  416. after_dig_node = function(pos)
  417. pipeworks.scan_for_pipe_objects(pos)
  418. end,
  419. on_construct = function(pos)
  420. if mesecon then
  421. mesecon.receptor_off(pos, rules)
  422. end
  423. end,
  424. selection_box = {
  425. type = "fixed",
  426. fixed = {
  427. { -2/16, -2/16, -8/16, 2/16, 2/16, 8/16 },
  428. { -3/16, -3/16, -4/16, 3/16, 3/16, 4/16 },
  429. }
  430. },
  431. collision_box = {
  432. type = "fixed",
  433. fixed = {
  434. { -2/16, -2/16, -8/16, 2/16, 2/16, 8/16 },
  435. { -3/16, -3/16, -4/16, 3/16, 3/16, 4/16 },
  436. }
  437. },
  438. mesecons = pipereceptor_off,
  439. on_rotate = pipeworks.fix_after_rotation
  440. })
  441. local nodename_sensor_loaded = "pipeworks:flow_sensor_loaded"
  442. minetest.register_node(nodename_sensor_loaded, {
  443. description = S("Flow sensor (on)"),
  444. drawtype = "mesh",
  445. mesh = "pipeworks_flow_sensor"..polys..".obj",
  446. tiles = { "pipeworks_flow_sensor_on.png" },
  447. sunlight_propagates = true,
  448. paramtype = "light",
  449. paramtype2 = "facedir",
  450. groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
  451. sounds = default.node_sound_metal_defaults(),
  452. walkable = true,
  453. on_place = pipeworks.rotate_on_place,
  454. after_dig_node = function(pos)
  455. pipeworks.scan_for_pipe_objects(pos)
  456. end,
  457. on_construct = function(pos)
  458. if mesecon then
  459. mesecon.receptor_on(pos, rules)
  460. end
  461. end,
  462. selection_box = {
  463. type = "fixed",
  464. fixed = {
  465. { -2/16, -2/16, -8/16, 2/16, 2/16, 8/16 },
  466. { -3/16, -3/16, -4/16, 3/16, 3/16, 4/16 },
  467. }
  468. },
  469. collision_box = {
  470. type = "fixed",
  471. fixed = {
  472. { -2/16, -2/16, -8/16, 2/16, 2/16, 8/16 },
  473. { -3/16, -3/16, -4/16, 3/16, 3/16, 4/16 },
  474. }
  475. },
  476. drop = "pipeworks:flow_sensor_empty",
  477. mesecons = pipereceptor_on,
  478. on_rotate = pipeworks.fix_after_rotation
  479. })
  480. new_flow_logic_register.directional_horizonal_rotate(nodename_sensor_empty, true)
  481. new_flow_logic_register.directional_horizonal_rotate(nodename_sensor_loaded, true)
  482. -- activate flow sensor at roughly half the pressure pumps drive pipes
  483. local sensor_pressure_set = { { nodename_sensor_empty, 0.0 }, { nodename_sensor_loaded, 1.0 } }
  484. new_flow_logic_register.transition_simple_set(sensor_pressure_set, { mesecons=pipeworks.mesecons_rules })
  485. -- tanks
  486. -- TODO flow-logic-stub: these don't currently do anything under the new flow logic.
  487. for fill = 0, 10 do
  488. local filldesc=S("empty")
  489. local sgroups = {snappy=3, pipe=1, tankfill=fill+1}
  490. local image = nil
  491. if fill ~= 0 then
  492. filldesc=S("@1% full", 10*fill)
  493. sgroups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1}
  494. image = "pipeworks_storage_tank_fittings.png"
  495. end
  496. minetest.register_node("pipeworks:expansion_tank_"..fill, {
  497. description = S("Expansion Tank (@1)", filldesc),
  498. tiles = {
  499. "pipeworks_storage_tank_fittings.png",
  500. "pipeworks_storage_tank_fittings.png",
  501. "pipeworks_storage_tank_back.png",
  502. "pipeworks_storage_tank_back.png",
  503. "pipeworks_storage_tank_back.png",
  504. pipeworks.liquid_texture.."^pipeworks_storage_tank_front_"..fill..".png"
  505. },
  506. inventory_image = image,
  507. paramtype = "light",
  508. paramtype2 = "facedir",
  509. groups = {snappy=3, pipe=1, tankfill=fill+1, not_in_creative_inventory=1},
  510. sounds = default.node_sound_metal_defaults(),
  511. walkable = true,
  512. drop = "pipeworks:storage_tank_0",
  513. pipe_connections = { top = 1, bottom = 1},
  514. after_place_node = function(pos)
  515. pipeworks.look_for_stackable_tanks(pos)
  516. pipeworks.scan_for_pipe_objects(pos)
  517. end,
  518. after_dig_node = function(pos)
  519. pipeworks.scan_for_pipe_objects(pos)
  520. end,
  521. on_rotate = false
  522. })
  523. minetest.register_node("pipeworks:storage_tank_"..fill, {
  524. description = S("Fluid Storage Tank (@1)", filldesc),
  525. tiles = {
  526. "pipeworks_storage_tank_fittings.png",
  527. "pipeworks_storage_tank_fittings.png",
  528. "pipeworks_storage_tank_back.png",
  529. "pipeworks_storage_tank_back.png",
  530. "pipeworks_storage_tank_back.png",
  531. pipeworks.liquid_texture.."^pipeworks_storage_tank_front_"..fill..".png"
  532. },
  533. inventory_image = image,
  534. paramtype = "light",
  535. paramtype2 = "facedir",
  536. groups = sgroups,
  537. sounds = default.node_sound_metal_defaults(),
  538. walkable = true,
  539. drop = "pipeworks:storage_tank_0",
  540. pipe_connections = { top = 1, bottom = 1},
  541. after_place_node = function(pos)
  542. pipeworks.look_for_stackable_tanks(pos)
  543. pipeworks.scan_for_pipe_objects(pos)
  544. end,
  545. after_dig_node = function(pos)
  546. pipeworks.scan_for_pipe_objects(pos)
  547. end,
  548. on_rotate = false
  549. })
  550. end
  551. -- fountainhead
  552. local nodename_fountain_empty = "pipeworks:fountainhead"
  553. minetest.register_node(nodename_fountain_empty, {
  554. description = S("Fountainhead"),
  555. drawtype = "mesh",
  556. mesh = "pipeworks_fountainhead"..polys..".obj",
  557. tiles = { "pipeworks_fountainhead.png" },
  558. sunlight_propagates = true,
  559. paramtype = "light",
  560. groups = {snappy=3, pipe=1},
  561. sounds = default.node_sound_metal_defaults(),
  562. walkable = true,
  563. pipe_connections = { bottom = 1 },
  564. after_place_node = function(pos)
  565. pipeworks.scan_for_pipe_objects(pos)
  566. end,
  567. after_dig_node = function(pos)
  568. pipeworks.scan_for_pipe_objects(pos)
  569. end,
  570. on_construct = function(pos)
  571. if mesecon then
  572. mesecon.receptor_on(pos, rules)
  573. end
  574. end,
  575. selection_box = {
  576. type = "fixed",
  577. fixed = { -2/16, -8/16, -2/16, 2/16, 8/16, 2/16 }
  578. },
  579. collision_box = {
  580. type = "fixed",
  581. fixed = { -2/16, -8/16, -2/16, 2/16, 8/16, 2/16 }
  582. },
  583. on_rotate = false
  584. })
  585. local nodename_fountain_loaded = "pipeworks:fountainhead_pouring"
  586. minetest.register_node(nodename_fountain_loaded, {
  587. description = S("Fountainhead"),
  588. drawtype = "mesh",
  589. mesh = "pipeworks_fountainhead"..polys..".obj",
  590. tiles = { "pipeworks_fountainhead.png" },
  591. sunlight_propagates = true,
  592. paramtype = "light",
  593. groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
  594. sounds = default.node_sound_metal_defaults(),
  595. walkable = true,
  596. pipe_connections = { bottom = 1 },
  597. after_place_node = function(pos)
  598. minetest.set_node(pos, { name = "pipeworks:fountainhead", param2 = minetest.get_node(pos).param2 })
  599. pipeworks.scan_for_pipe_objects(pos)
  600. end,
  601. after_dig_node = function(pos)
  602. pipeworks.scan_for_pipe_objects(pos)
  603. end,
  604. on_construct = function(pos)
  605. if mesecon then
  606. mesecon.receptor_on(pos, rules)
  607. end
  608. end,
  609. selection_box = {
  610. type = "fixed",
  611. fixed = { -2/16, -8/16, -2/16, 2/16, 8/16, 2/16 }
  612. },
  613. collision_box = {
  614. type = "fixed",
  615. fixed = { -2/16, -8/16, -2/16, 2/16, 8/16, 2/16 }
  616. },
  617. drop = "pipeworks:fountainhead",
  618. on_rotate = false
  619. })
  620. new_flow_logic_register.directional_vertical_fixed(nodename_fountain_empty, false)
  621. new_flow_logic_register.directional_vertical_fixed(nodename_fountain_loaded, false)
  622. local fountain_upper = 1.0
  623. local fountain_lower = 1.0
  624. local fountain_neighbours={{x=0, y=1, z=0}}
  625. new_flow_logic_register.output_simple(nodename_fountain_empty, fountain_upper, fountain_lower, fountain_neighbours)
  626. new_flow_logic_register.output_simple(nodename_fountain_loaded, fountain_upper, fountain_lower, fountain_neighbours)
  627. local sp_cbox = {
  628. type = "fixed",
  629. fixed = {
  630. { -2/16, -2/16, -8/16, 2/16, 2/16, 8/16 }
  631. }
  632. }
  633. local nodename_sp_empty = "pipeworks:straight_pipe_empty"
  634. minetest.register_node(nodename_sp_empty, {
  635. description = S("Straight-only Pipe"),
  636. drawtype = "mesh",
  637. mesh = "pipeworks_straight_pipe"..polys..".obj",
  638. tiles = { "pipeworks_straight_pipe_empty.png" },
  639. paramtype = "light",
  640. paramtype2 = "facedir",
  641. groups = {snappy=3, pipe=1},
  642. sounds = default.node_sound_metal_defaults(),
  643. walkable = true,
  644. on_place = pipeworks.rotate_on_place,
  645. after_dig_node = function(pos)
  646. pipeworks.scan_for_pipe_objects(pos)
  647. end,
  648. selection_box = sp_cbox,
  649. collision_box = sp_cbox,
  650. on_rotate = pipeworks.fix_after_rotation,
  651. check_for_pole = pipeworks.check_for_vert_pipe,
  652. check_for_horiz_pole = pipeworks.check_for_horiz_pipe
  653. })
  654. local nodename_sp_loaded = "pipeworks:straight_pipe_loaded"
  655. minetest.register_node(nodename_sp_loaded, {
  656. description = S("Straight-only Pipe"),
  657. drawtype = "mesh",
  658. mesh = "pipeworks_straight_pipe"..polys..".obj",
  659. tiles = { "pipeworks_straight_pipe_loaded.png" },
  660. paramtype = "light",
  661. paramtype2 = "facedir",
  662. groups = {snappy=3, pipe=1, not_in_creative_inventory=1},
  663. sounds = default.node_sound_metal_defaults(),
  664. walkable = true,
  665. on_place = pipeworks.rotate_on_place,
  666. after_dig_node = function(pos)
  667. pipeworks.scan_for_pipe_objects(pos)
  668. end,
  669. selection_box = sp_cbox,
  670. collision_box = sp_cbox,
  671. drop = "pipeworks:straight_pipe_empty",
  672. on_rotate = pipeworks.fix_after_rotation,
  673. check_for_pole = pipeworks.check_for_vert_pipe,
  674. check_for_horiz_pole = pipeworks.check_for_horiz_pipe
  675. })
  676. new_flow_logic_register.directional_horizonal_rotate(nodename_sp_empty, true)
  677. new_flow_logic_register.directional_horizonal_rotate(nodename_sp_loaded, true)
  678. -- Other misc stuff
  679. minetest.register_alias("pipeworks:valve_off_loaded", "pipeworks:valve_off_empty")
  680. minetest.register_alias("pipeworks:entry_panel", "pipeworks:entry_panel_empty")