init.lua 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. -- minetest/fire/init.lua
  2. -- Global namespace for functions
  3. fire = {}
  4. fire.modpath = minetest.get_modpath("fire")
  5. -- Localize for performance.
  6. local math_random = math.random
  7. reload.register_file("fire:fire_scatter", fire.modpath .. "/fire_scatter.lua")
  8. -- Register flame nodes
  9. minetest.register_node("fire:basic_flame", {
  10. drawtype = "firelike",
  11. tiles = {
  12. {
  13. name = "fire_basic_flame_animated.png",
  14. animation = {
  15. type = "vertical_frames",
  16. aspect_w = 16,
  17. aspect_h = 16,
  18. length = 1
  19. },
  20. },
  21. },
  22. inventory_image = "fire_basic_flame.png",
  23. paramtype = "light",
  24. light_source = 13,
  25. walkable = false,
  26. buildable_to = false, -- Player must remove fire before building.
  27. not_buildable_against = true,
  28. sunlight_propagates = true,
  29. damage_per_second = 4,
  30. drop = "",
  31. groups = utility.dig_groups("bigitem", {
  32. igniter = 2,
  33. not_in_creative_inventory = 1,
  34. melt_around = 3,
  35. flame = 1,
  36. flame_sound = 1,
  37. notify_construct = 1,
  38. fire = 1,
  39. }),
  40. on_timer = function(pos)
  41. local f = minetest.find_node_near(pos, 1, {"group:flammable"})
  42. if f then
  43. if minetest.test_protection(f, "") then
  44. minetest.remove_node(pos)
  45. return
  46. end
  47. end
  48. if not f then
  49. minetest.remove_node(pos)
  50. return
  51. end
  52. -- restart timer
  53. local time = math_random(30, 60)
  54. minetest.get_node_timer(pos):start(time)
  55. --ambiance.fire_particles(pos, time)
  56. end,
  57. on_construct = function(pos)
  58. fireambiance.on_flame_addremove(pos)
  59. particles.add_flame_spawner(pos)
  60. local time = math_random(30, 60)
  61. minetest.get_node_timer(pos):start(time)
  62. --ambiance.fire_particles(pos, time)
  63. torchmelt.start_melting(pos)
  64. end,
  65. after_destruct = function(pos)
  66. particles.del_flame_spawner(pos)
  67. fireambiance.on_flame_addremove(pos)
  68. end,
  69. on_dig = function(pos, node, player)
  70. local pname = player and player:get_player_name() or ""
  71. if not heatdamage.is_immune(pname) then
  72. minetest.after(0, function()
  73. local player = minetest.get_player_by_name(pname)
  74. if player and player:get_hp() > 0 then
  75. player:set_hp(player:get_hp() - 1)
  76. end
  77. end)
  78. end
  79. return minetest.node_dig(pos, node, player)
  80. end,
  81. --on_blast = function()
  82. --end, -- unaffected by explosions
  83. })
  84. minetest.register_node("fire:permanent_flame", {
  85. description = "Permanent Flame",
  86. drawtype = "firelike",
  87. tiles = {
  88. {
  89. name = "fire_basic_flame_animated.png",
  90. animation = {
  91. type = "vertical_frames",
  92. aspect_w = 16,
  93. aspect_h = 16,
  94. length = 1
  95. },
  96. },
  97. },
  98. inventory_image = "fire_basic_flame.png",
  99. paramtype = "light",
  100. light_source = 13,
  101. walkable = false,
  102. buildable_to = false, -- Player must remove fire before building.
  103. not_buildable_against = true,
  104. sunlight_propagates = true,
  105. damage_per_second = 4,
  106. groups = {igniter = 2, dig_immediate = 2, melt_around = 3, flame = 1, flame_sound = 1, fire = 1, notify_construct = 1},
  107. drop = "",
  108. on_construct = function(pos)
  109. fireambiance.on_flame_addremove(pos)
  110. particles.add_flame_spawner(pos)
  111. torchmelt.start_melting(pos)
  112. end,
  113. after_destruct = function(pos)
  114. fireambiance.on_flame_addremove(pos)
  115. particles.del_flame_spawner(pos)
  116. end,
  117. on_dig = function(pos, node, player)
  118. local pname = player and player:get_player_name() or ""
  119. if not heatdamage.is_immune(pname) then
  120. minetest.after(0, function()
  121. local player = minetest.get_player_by_name(pname)
  122. if player and player:get_hp() > 0 then
  123. player:set_hp(player:get_hp() - 1)
  124. end
  125. end)
  126. end
  127. return minetest.node_dig(pos, node, player)
  128. end,
  129. --on_blast = function()
  130. --end,
  131. })
  132. minetest.register_node("fire:nether_flame", {
  133. description = "Nether Flame",
  134. drawtype = "firelike",
  135. tiles = {
  136. {
  137. name = "fire_nether_flame_animated.png",
  138. animation = {
  139. type = "vertical_frames",
  140. aspect_w = 16,
  141. aspect_h = 16,
  142. length = 1
  143. },
  144. },
  145. },
  146. inventory_image = "fire_basic_flame.png",
  147. paramtype = "light",
  148. light_source = 14,
  149. walkable = false,
  150. buildable_to = false,
  151. not_buildable_against = true,
  152. sunlight_propagates = true,
  153. damage_per_second = 4,
  154. groups = utility.dig_groups("bigitem", {igniter = 2, melt_around = 3, flame = 1, fire = 1, flame_sound = 1, notify_construct = 1}),
  155. drop = "",
  156. on_construct = function(pos)
  157. fireambiance.on_flame_addremove(pos)
  158. particles.add_flame_spawner(pos)
  159. torchmelt.start_melting(pos)
  160. end,
  161. -- The fireportal takes care of this.
  162. --after_destruct = function(pos) fireambiance.on_flame_addremove(pos) end,
  163. on_dig = function(pos, node, player)
  164. local pname = player and player:get_player_name() or ""
  165. if not heatdamage.is_immune(pname) then
  166. minetest.after(0, function()
  167. local player = minetest.get_player_by_name(pname)
  168. if player and player:get_hp() > 0 then
  169. player:set_hp(player:get_hp() - 1)
  170. end
  171. end)
  172. end
  173. return minetest.node_dig(pos, node, player)
  174. end,
  175. --on_blast = function()
  176. --end,
  177. })
  178. -- Override coalblock to enable permanent flame above
  179. minetest.override_item("default:coalblock", {
  180. after_destruct = function(pos, oldnode)
  181. pos.y = pos.y + 1
  182. if minetest.get_node(pos).name == "fire:permanent_flame" then
  183. minetest.remove_node(pos)
  184. end
  185. end,
  186. })
  187. -- Extinguish all flames quickly with water, snow, ice
  188. minetest.register_abm({
  189. label = "Extinguish flame",
  190. nodenames = {"group:flame"},
  191. neighbors = {"group:puts_out_fire"},
  192. interval = 3 * default.ABM_TIMER_MULTIPLIER,
  193. chance = 1 * default.ABM_CHANCE_MULTIPLIER,
  194. catch_up = false,
  195. action = function(pos, node, active_object_count, active_object_count_wider)
  196. minetest.remove_node(pos)
  197. minetest.sound_play("fire_extinguish_flame",
  198. {pos = pos, max_hear_distance = 16, gain = 0.25}, true)
  199. end,
  200. })
  201. -- Enable the following ABMs according to 'enable fire' setting
  202. minetest.register_abm({
  203. label = "Ignite flame",
  204. nodenames = {"group:flammable"},
  205. neighbors = {"group:igniter"},
  206. interval = 3 * default.ABM_TIMER_MULTIPLIER,--7/2,
  207. chance = 6 * default.ABM_CHANCE_MULTIPLIER,--12/2,
  208. catch_up = false,
  209. action = function(pos, node, active_object_count, active_object_count_wider)
  210. -- If there is water or stuff like that around node, don't ignite
  211. if minetest.find_node_near(pos, 1, {"group:puts_out_fire"}) then
  212. return
  213. end
  214. local p
  215. local def = minetest.reg_ns_nodes[node.name]
  216. or minetest.registered_nodes[node.name]
  217. if def and def.buildable_to then
  218. -- Flame replaces flammable node itself if node is buildable to.
  219. p = pos
  220. else
  221. p = minetest.find_node_near(pos, 1, {"air"})
  222. end
  223. if p then
  224. if minetest.test_protection(p, "") then
  225. return
  226. end
  227. minetest.add_node(p, {name = "fire:basic_flame"})
  228. end
  229. end,
  230. })
  231. -- Remove flammable nodes
  232. minetest.register_abm({
  233. label = "Remove flammable nodes",
  234. nodenames = {"fire:basic_flame", "fire:nether_flame"},
  235. neighbors = "group:flammable",
  236. interval = 3 * default.ABM_TIMER_MULTIPLIER,
  237. chance = 10 * default.ABM_CHANCE_MULTIPLIER,
  238. catch_up = false,
  239. action = function(pos, node, active_object_count, active_object_count_wider)
  240. local p = minetest.find_node_near(pos, 1, {"group:flammable"})
  241. if p then
  242. if minetest.test_protection(p, "") then
  243. return
  244. end
  245. -- remove flammable nodes around flame
  246. local flammable_node = minetest.get_node(p)
  247. local def = minetest.reg_ns_nodes[flammable_node.name]
  248. or minetest.registered_nodes[flammable_node.name]
  249. if def.on_burn then
  250. def.on_burn(p)
  251. else
  252. minetest.remove_node(p)
  253. minetest.check_for_falling(p)
  254. end
  255. end
  256. end,
  257. })