fire_scatter.lua 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. local math_random = math.random
  2. function fire.scatter_flame_in_area(minp, maxp, coverage)
  3. local flames = {}
  4. local targets = minetest.find_nodes_in_area(minp, maxp, "air")
  5. if #targets == 0 then
  6. return flames
  7. end
  8. for idx = 1, #targets, 1 do
  9. if math_random(0, 100) < coverage then
  10. local pos = targets[idx]
  11. minetest.set_node(pos, {name="fire:basic_flame"})
  12. flames[#flames + 1] = pos
  13. end
  14. end
  15. return flames
  16. end
  17. function fire.scatter_flame_in_area_over_ground(minp, maxp, coverage)
  18. local flames = {}
  19. -- Adjust max Y up 1 node (because we need to check node-above for each pos).
  20. maxp = vector.add(maxp, {x=0, y=1, z=0})
  21. local voxel = VoxelManip()
  22. local emin, emax = voxel:read_from_map(minp, maxp)
  23. local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax})
  24. local data = voxel:get_data()
  25. local c_air = minetest.get_content_id("air")
  26. -- Will store the positions of ground nodes.
  27. local targets = {}
  28. for x = minp.x, maxp.x, 1 do
  29. for y = minp.y, (maxp.y - 1), 1 do
  30. for z = minp.z, maxp.z, 1 do
  31. local v1 = area:index(x, y, z)
  32. local v2 = area:index(x, y + 1, z)
  33. local d1 = data[v1]
  34. local d2 = data[v2]
  35. if d1 ~= c_air and d2 == c_air then
  36. targets[#targets + 1] = {x=x, y=y+1, z=z}
  37. end
  38. end
  39. end
  40. end
  41. if #targets == 0 then
  42. return flames
  43. end
  44. for idx = 1, #targets, 1 do
  45. if math_random(0, 100) < coverage then
  46. local pos = targets[idx]
  47. minetest.set_node(pos, {name="fire:basic_flame"})
  48. flames[#flames + 1] = pos
  49. end
  50. end
  51. return flames
  52. end
  53. function fire.scatter_flame_around(pos, radius, coverage)
  54. local minp = vector.add(pos, {x=-radius, y=-radius, z=-radius})
  55. local maxp = vector.add(pos, {x=radius, y=radius, z=radius})
  56. return fire.scatter_flame_in_area(minp, maxp, coverage)
  57. end
  58. function fire.scatter_flame_around_over_ground(pos, radius, coverage)
  59. local minp = vector.add(pos, {x=-radius, y=-radius, z=-radius})
  60. local maxp = vector.add(pos, {x=radius, y=radius, z=radius})
  61. return fire.scatter_flame_in_area_over_ground(minp, maxp, coverage)
  62. end