init.lua 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. fire_plus = {
  2. tnt_explode_radius = 1.5,
  3. }
  4. fire_plus.ignition_nodes = {
  5. "default:lava",
  6. "fire:",
  7. }
  8. fire_plus.put_outs = { -- Couldn't thnk of a better name
  9. "default:water",
  10. "default:river_water",
  11. "default:snow"
  12. }
  13. local firehud = {}
  14. local firesound = {}
  15. local callbacks = {}
  16. local function make_registration()
  17. local registerfunc = function(func)
  18. callbacks[#callbacks + 1] = func
  19. end
  20. return(registerfunc)
  21. end
  22. minetest.register_on_player_hpchange(function(player, hp_change)
  23. local pos = player:get_pos()
  24. local node = minetest.get_node(pos)
  25. for id, string in ipairs(fire_plus.ignition_nodes) do
  26. if node.name:find(string) then
  27. fire_plus.burnplayer(player)
  28. break
  29. end
  30. end
  31. end)
  32. minetest.register_on_respawnplayer(function(player)
  33. local name = player:get_player_name()
  34. if firehud[name] then
  35. player:hud_remove(firehud[name])
  36. firehud[name] = nil
  37. end
  38. if firesound[name] then
  39. minetest.sound_stop(firesound[name])
  40. firesound[name] = nil
  41. end
  42. end)
  43. fire_plus.on_burn = make_registration()
  44. function fire_plus.get_burn_dmg(player)
  45. local dmg = 1
  46. for id, func in ipairs(callbacks) do
  47. local rval = callbacks[k](player)
  48. if type(rval) == "number" then
  49. dmg = rval
  50. break
  51. end
  52. end
  53. return(dmg)
  54. end
  55. function fire_plus.burnplayer(player)
  56. if not player then return end
  57. local name = player:get_player_name()
  58. if firehud[name] then
  59. return
  60. end
  61. firehud[name] = player:hud_add({
  62. hud_elem_type = "image",
  63. position = {x = 0.5, y = 0.95},
  64. offset = {x = 0, y = 0},
  65. text = "fire_basic_flame.png",
  66. alignment = -1,
  67. scale = {x = 100, y = 32},
  68. number = 0xFFFFFF,
  69. })
  70. firesound[name] = minetest.sound_play("fire_fire", {
  71. to_player = name,
  72. gain = 1.0,
  73. loop = true,
  74. })
  75. for i=1, 4, 1 do
  76. minetest.after(i, function()
  77. if not player or firehud[player:get_player_name()] == nil then
  78. return
  79. end
  80. local pos = player:get_pos()
  81. local pname = player:get_player_name()
  82. local name = minetest.get_node(pos).name
  83. local remove_burn = false
  84. for id, string in ipairs(fire_plus.put_outs) do
  85. if name:find(string) then
  86. remove_burn = true
  87. break
  88. end
  89. end
  90. if remove_burn == true then
  91. player:hud_remove(firehud[pname])
  92. minetest.sound_stop(firesound[pname])
  93. firehud[pname] = nil
  94. firesound[pname] = nil
  95. minetest.sound_play("fire_extinguish_flame", {
  96. to_player = pname,
  97. gain = 1.0,
  98. })
  99. return
  100. end
  101. -- Detonate any nearby TNT if player is on fire
  102. local tntpos = minetest.find_node_near(player:get_pos(), fire_plus.tnt_explode_radius, {"tnt:tnt"}, true)
  103. if player:get_hp() > 0 then
  104. player:set_hp(player:get_hp()-fire_plus.get_burn_dmg(player))
  105. end
  106. if tntpos then
  107. tnt.boom(tntpos, {radius = tnt_radius, damage_radius = tnt_radius})
  108. end
  109. minetest.add_particlespawner({
  110. amount = 20,
  111. time = 0.1,
  112. minpos = vector.subtract(pos, 0.5),
  113. maxpos = vector.add(pos, 0.5),
  114. minvel = {x = -1, y = 0, z = -1},
  115. maxvel = {x = 1, y = 1, z = 1},
  116. minacc = {x = 0, y = 2, z = 0},
  117. maxacc = {x = 0, y = 3, z = 0},
  118. minexptime = 0.5,
  119. maxexptime = 1,
  120. minsize = 5 * 0.66,
  121. maxsize = 5 * 0.66,
  122. texture = "fire_basic_flame.png",
  123. collisiondetection = true,
  124. })
  125. end)
  126. end
  127. minetest.after(4.5, function()
  128. if not player then
  129. return
  130. end
  131. local name = player:get_player_name()
  132. if firehud[name] then
  133. player:hud_remove(firehud[name])
  134. firehud[name] = nil
  135. end
  136. if firesound[name] then
  137. minetest.sound_stop(firesound[name])
  138. firesound[name] = nil
  139. end
  140. end)
  141. end
  142. minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_ca, dir, dmg)
  143. if hitter:is_player() and tool_ca.damage_groups.burns == 1 and
  144. (player:get_hp()-dmg) > 0 then
  145. fire_plus.burnplayer(player)
  146. end
  147. return(false)
  148. end)