coffer_dam.lua 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. local function drop_column(pos, node, maxdrop)
  2. local maxd = pos.y - maxdrop
  3. local p = {x=pos.x, y=pos.y, z=pos.z}
  4. while p.y >= maxd do
  5. local n = minetest.get_node(p)
  6. local def = minetest.registered_nodes[n.name]
  7. if def.groups.liquid then
  8. minetest.set_node(p, {name=node})
  9. else
  10. break
  11. end
  12. p.y = p.y - 1
  13. end
  14. end
  15. local function drop_wall(start, length, dir, node, maxdrop)
  16. local p = {x=start.x, y=start.y, z=start.z}
  17. for i = 1,length do
  18. drop_column(p, node, maxdrop)
  19. p = vector.add(p, dir)
  20. end
  21. end
  22. local function drop_octagon(center, rad)
  23. drop_wall(vector.add(center, {x=rad*2, y=0, z=rad}), rad*2+1, {x=0,y=0,z=-1}, "default:cobble", 10)
  24. drop_wall(vector.add(center, {x=-rad*2, y=0, z=-rad}), rad*2+1, {x=0,y=0,z=1}, "default:cobble", 10)
  25. drop_wall(vector.add(center, {x=rad, y=0, z=rad*2}), rad*2+1, {x=-1,y=0,z=0}, "default:cobble", 10)
  26. drop_wall(vector.add(center, {x=-rad, y=0, z=-rad*2}), rad*2+1, {x=1,y=0,z=0}, "default:cobble", 10)
  27. drop_wall(vector.add(center, {x=rad, y=0, z=-rad*2}), rad, {x=1,y=0,z=1}, "default:cobble", 10)
  28. drop_wall(vector.add(center, {x=-rad, y=0, z=rad*2}), rad, {x=-1,y=0,z=-1}, "default:cobble", 10)
  29. drop_wall(vector.add(center, {x=-rad, y=0, z=-rad*2}), rad, {x=-1,y=0,z=1}, "default:cobble", 10)
  30. drop_wall(vector.add(center, {x=rad, y=0, z=rad*2}), rad, {x=1,y=0,z=-1}, "default:cobble", 10)
  31. -- drop_wall(vector.add(center, {x=-rad, y=0, z=rad/2}), rad/2, {x=1,y=0,z=-1}, "default:cobble", 10)
  32. end
  33. local function freeze_top(pos, max_nodes, cb)
  34. local stack = {}
  35. local out = {}
  36. table.insert(stack, pos)
  37. local function process()
  38. local i = 0
  39. while #stack > 0 do
  40. local nn = math.random(#stack)
  41. -- print("index "..nn .. " of "..#stack)
  42. local p = table.remove(stack, nn)
  43. -- print(dump(p))
  44. local n = minetest.get_node(p)
  45. if n.name == "default:water_source" then
  46. table.insert(out, p)
  47. minetest.set_node(p, {name="default:ice"})
  48. table.insert(stack, vector.add(p, {x=1, y=0, z=0}))
  49. table.insert(stack, vector.add(p, {x=-1, y=0, z=0}))
  50. table.insert(stack, vector.add(p, {x=0, y=0, z=1}))
  51. table.insert(stack, vector.add(p, {x=0, y=0, z=-1}))
  52. if #out > max_nodes then
  53. cb(out)
  54. return
  55. end
  56. if #stack > 0 and i > 5 then
  57. minetest.after(1, process)
  58. return
  59. elseif #stack == 0 then
  60. cb(out)
  61. end
  62. i = i + 1
  63. end
  64. end
  65. cb(out)
  66. end
  67. process()
  68. end
  69. local function clear_water(pts, maxd, top_off)
  70. for _,p in ipairs(pts) do
  71. drop_column({x=p.x, y=p.y-top_off, z=p.z}, "air", maxd - top_off)
  72. end
  73. end
  74. local function remove_points(pts, lvl)
  75. for _,p in ipairs(pts) do
  76. minetest.set_node({x=p.x, y=p.y-lvl, z=p.z}, {name="air"})
  77. end
  78. end
  79. minetest.register_node("potions:coffer_dam_seed", {
  80. description = "Coffer Dam Seed",
  81. drawtype = "node",
  82. tiles = {"default_stone_brick.png"},
  83. groups = {cracky=3,},
  84. liquids_pointable=true,
  85. on_construct = function(pos)
  86. minetest.set_node(pos, {name="default:water_source"})
  87. drop_octagon(pos, 3)
  88. freeze_top(pos, 12*12, function(pts)
  89. -- print("points "..#pts)
  90. clear_water(pts, 10, 1)
  91. minetest.add_particlespawner({
  92. amount = 800,
  93. time = 4,
  94. minpos = vector.subtract(pos, 3+2),
  95. maxpos = vector.add(pos, 3+2),
  96. minvel = {x=-0.1, y=1, z=-0.1},
  97. maxvel = {x=0.1, y=.6, z=0.1},
  98. minacc = {x=-02.1, y=0.1, z=-02.1},
  99. maxacc = {x=02.1, y=1.3, z=02.1},
  100. minexptime = 1.5,
  101. maxexptime = 1.5,
  102. -- collisiondetection = true,
  103. -- collision_removal = true,
  104. minsize = 2.2,
  105. maxsize = 2.2,
  106. texture = "potions_particle.png^[colorize:blue:110",
  107. -- animation = tileanimation
  108. glow = 1
  109. })
  110. minetest.after(2.5, remove_points, pts, 0)
  111. end)
  112. end
  113. })