abm.lua 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. -- LUALOCALS < ---------------------------------------------------------
  2. local ipairs, math, minetest, nodecore, pairs, string, vector
  3. = ipairs, math, minetest, nodecore, pairs, string, vector
  4. local math_random, string_format
  5. = math.random, string.format
  6. -- LUALOCALS > ---------------------------------------------------------
  7. local modname = minetest.get_current_modname()
  8. do
  9. local flamedirs = nodecore.dirs()
  10. local embers = {}
  11. minetest.after(0, function()
  12. for k, v in pairs(minetest.registered_items) do
  13. if v.groups.ember then
  14. embers[k] = true
  15. end
  16. end
  17. end)
  18. nodecore.register_limited_abm({
  19. label = "fire consume",
  20. interval = 1,
  21. chance = 1,
  22. nodenames = {modname .. ":fire"},
  23. action = function(pos)
  24. if math_random(1, 5) == 1 then
  25. minetest.add_particlespawner({
  26. amount = math_random(1, 3),
  27. time = 1,
  28. minpos = vector.subtract(pos, 0.5),
  29. maxpos = vector.add(pos, 0.5),
  30. minvel = {x = -1, y = 2, z = -1},
  31. maxvel = {x = 1, y = 2.5, z = 1},
  32. minacc = {x = -0.1, y = 0, z = -0.1},
  33. maxacc = {x = 0.1, y = 0, z = 0.1},
  34. minxeptime = 1,
  35. maxexptime = 3,
  36. minsize = 0.1,
  37. maxsize = 0.2,
  38. collisiondetection = true,
  39. collision_removal = true,
  40. texture = "nc_fire_spark.png",
  41. glow = math_random(5, 9)
  42. })
  43. end
  44. local found = {}
  45. for _, dp in ipairs(flamedirs) do
  46. local npos = vector.add(pos, dp)
  47. local node = minetest.get_node_or_nil(npos)
  48. if (not node) or embers[node.name] then
  49. found[#found + 1] = npos
  50. end
  51. end
  52. if #found < 1 then
  53. return minetest.remove_node(pos)
  54. end
  55. local picked = nodecore.pickrand(found)
  56. return nodecore.fire_check_expend(picked)
  57. end
  58. })
  59. end
  60. local poshash = minetest.hash_node_position
  61. local ignitemax = 250
  62. local ignition
  63. nodecore.register_globalstep("fire ignition", function()
  64. if not ignition then return end
  65. nodecore.log("info", string_format("fire ignition: %d (%d/%d)",
  66. ignition.qty, #ignition.queue, ignitemax))
  67. for _, pos in ipairs(ignition.queue) do
  68. nodecore.fire_check_ignite(pos)
  69. end
  70. ignition = nil
  71. end)
  72. nodecore.register_limited_abm({
  73. label = "flammables ignite",
  74. interval = 5,
  75. chance = 1,
  76. nodenames = {"group:igniter"},
  77. neighbors = {"group:flammable"},
  78. action = function(pos)
  79. for _, p in pairs(nodecore.find_nodes_around(pos, "group:flammable")) do
  80. local key = poshash(p)
  81. if not ignition then
  82. ignition = {
  83. queue = {},
  84. seen = {},
  85. qty = 0
  86. }
  87. end
  88. local seen = ignition.seen
  89. if not seen[key] then
  90. seen[key] = true
  91. local qty = ignition.qty + 1
  92. ignition.qty = qty
  93. if qty > ignitemax then
  94. local i = math_random(1, qty)
  95. if i <= ignitemax then
  96. ignition.queue[i] = p
  97. end
  98. else
  99. ignition.queue[qty] = p
  100. end
  101. end
  102. end
  103. end
  104. })
  105. nodecore.register_limited_abm({
  106. label = "ember consume",
  107. interval = 1,
  108. chance = 1,
  109. nodenames = {"group:ember"},
  110. action = function(pos, node)
  111. local snuff, vents = nodecore.fire_check_snuff(pos, node)
  112. if snuff or not vents then return end
  113. for i = 1, #vents do
  114. if vents[i].q < 1 then
  115. minetest.set_node(vents[i], {name = modname .. ":fire"})
  116. end
  117. end
  118. end
  119. })
  120. nodecore.register_ambiance({
  121. label = "flame ambiance",
  122. nodenames = {"group:flame_ambiance"},
  123. interval = 1,
  124. chance = 1,
  125. sound_name = "nc_fire_flamy",
  126. sound_gain = 0.1
  127. })
  128. nodecore.register_item_ambiance({
  129. label = "flame ambiance",
  130. itemnames = {"group:flame_ambiance"},
  131. interval = 1,
  132. chance = 1,
  133. sound_name = "nc_fire_flamy",
  134. sound_gain = 0.1
  135. })