init.lua 8.2 KB

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