liquids_falling.lua 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. -- If the water edge is a straight line flowing has 3 neighbors,
  2. -- everything curved inwards would be more, anything outwards would be less.
  3. -- Water nodes propagate downwards to fill holes.
  4. local function count_source(pos, source)
  5. local p0 = {x=pos.x-1, y=pos.y, z=pos.z-1}
  6. local p1 = {x=pos.x+1, y=pos.y, z=pos.z+1}
  7. local ps = minetest.find_nodes_in_area(p0, p1, {source})
  8. return #ps
  9. end
  10. local source_pos = {
  11. -- First check the node directely above for falling down.
  12. {x = 0, y = 0, z = 0},
  13. -- Then check sideways to flow downsteam.
  14. {x = 1, y = 0, z = 0},
  15. {x = -1, y = 0, z = 0},
  16. {x = 0, y = 0, z = 1},
  17. {x = 0, y = 0, z = -1},
  18. -- Check diagonal
  19. {x = 1, y = 0, z = 1},
  20. {x = -1, y = 0, z = 1},
  21. {x = 1, y = 0, z = -1},
  22. {x = -1, y = 0, z = -1},
  23. }
  24. local function register_dynamic_liquid(source, flowing)
  25. minetest.register_abm({
  26. label = "Liquid physics "..source,
  27. nodenames = {flowing},
  28. neighbors = {source},
  29. interval = 1,
  30. chance = 5,
  31. catch_up = false,
  32. action = function(pos, node)
  33. -- What we check for can only be true for those two flowing types.
  34. if node.param2 == 15 then
  35. -- Flowing down
  36. local above = {x = pos.x, y = pos.y + 1, z = pos.z}
  37. for _, p in ipairs(source_pos) do
  38. local s_pos = {x = above.x + p.x, y = above.y + p.y, z = above.z + p.z}
  39. local n_checked = minetest.get_node(s_pos)
  40. if n_checked.name == source then
  41. node.name = source
  42. n_checked.name = flowing
  43. minetest.set_node(s_pos, n_checked) -- Replace with flowing to avoid air under water
  44. minetest.set_node(pos, node)
  45. return
  46. end
  47. end
  48. end
  49. if node.param2 == 0 or node.param2 == 7 then
  50. -- Renewable
  51. if count_source(pos, source) >= 5 then
  52. minetest.set_node(pos, {name = source})
  53. end
  54. end
  55. end
  56. })
  57. end
  58. register_dynamic_liquid("default:water_source", "default:water_flowing")
  59. register_dynamic_liquid("default:lava_source", "default:lava_flowing")