fireworks_arrows.lua 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. local function throwing_register_fireworks(color, desc)
  2. minetest.register_craftitem("throwing:arrow_fireworks_" .. color, {
  3. description = desc .. " Fireworks Arrow",
  4. inventory_image = "throwing_arrow_fireworks_" .. color .. ".png",
  5. })
  6. minetest.register_node("throwing:arrow_fireworks_" .. color .. "_box", {
  7. drawtype = "nodebox",
  8. node_box = {
  9. type = "fixed",
  10. fixed = {
  11. -- Shaft
  12. {-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17},
  13. --Spitze
  14. {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17},
  15. {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17},
  16. --Federn
  17. {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17},
  18. {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17},
  19. {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17},
  20. {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17},
  21. {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17},
  22. {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17},
  23. {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17},
  24. {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17},
  25. }
  26. },
  27. tiles = {"throwing_arrow_fireworks_" .. color .. ".png", "throwing_arrow_fireworks_" .. color .. ".png", "throwing_arrow_fireworks_" .. color .. "_back.png", "throwing_arrow_fireworks_" .. color .. "_front.png", "throwing_arrow_fireworks_" .. color .. "_2.png", "throwing_arrow_fireworks_" .. color .. ".png"},
  28. groups = {not_in_creative_inventory=1},
  29. })
  30. local THROWING_ARROW_ENTITY={
  31. _name = "throwing:arrow_fireworks_" .. color,
  32. physical = false,
  33. timer=0,
  34. visual = "wielditem",
  35. visual_size = {x=0.1, y=0.1},
  36. textures = {"throwing:arrow_fireworks_" .. color .. "_box"},
  37. lastpos={},
  38. collisionbox = {0,0,0,0,0,0},
  39. }
  40. local radius = 0.5
  41. local function add_effects(pos, radius)
  42. minetest.add_particlespawner({
  43. amount = 256,
  44. time = 0.2,
  45. minpos = vector.subtract(pos, radius / 2),
  46. maxpos = vector.add(pos, radius / 2),
  47. minvel = {x=-5, y=-5, z=-5},
  48. maxvel = {x=5, y=5, z=5},
  49. minacc = {x=0, y=-8, z=0},
  50. --~ maxacc = {x=-20, y=-50, z=-50},
  51. minexptime = 2.5,
  52. maxexptime = 3,
  53. minsize = 1,
  54. maxsize = 2.5,
  55. texture = "throwing_sparkle_" .. color .. ".png",
  56. })
  57. end
  58. local function boom(pos)
  59. minetest.sound_play("throwing_firework_boom", {pos=pos, gain=1, max_hear_distance=2*64}, true)
  60. if minetest.get_node(pos).name == 'air' or minetest.get_node(pos).name == 'throwing:firework_trail' then
  61. minetest.add_node(pos, {name="throwing:firework_boom"})
  62. minetest.get_node_timer(pos):start(0.2)
  63. end
  64. add_effects(pos, radius)
  65. end
  66. -- Back to the arrow
  67. THROWING_ARROW_ENTITY.on_step = function(self, dtime)
  68. self.timer=self.timer+dtime
  69. local pos = self.object:get_pos()
  70. local node = minetest.get_node(pos)
  71. if not self.played_launch_sound then
  72. ambiance.sound_play("throwing_firework_launch", pos, 0.8, 2*64)
  73. self.played_launch_sound = true
  74. end
  75. minetest.add_particlespawner({
  76. amount = 16,
  77. time = 0.1,
  78. minpos = pos,
  79. maxpos = pos,
  80. minvel = {x=-5, y=-5, z=-5},
  81. maxvel = {x=5, y=5, z=5},
  82. minacc = vector.new(),
  83. maxacc = vector.new(),
  84. minexptime = 0.3,
  85. maxexptime = 0.5,
  86. minsize = 0.5,
  87. maxsize = 1,
  88. texture = "throwing_sparkle.png",
  89. })
  90. if self.timer>0.2 then
  91. local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 2)
  92. for k, obj in pairs(objs) do
  93. if obj:get_luaentity() ~= nil then
  94. local oname = obj:get_luaentity().name
  95. if not throwing.entity_blocks_arrow(oname) then
  96. local damage = 2
  97. throwing_arrow_punch_entity(obj, self, damage)
  98. self.object:remove()
  99. boom(pos)
  100. end
  101. elseif obj:is_player() then
  102. local damage = 2
  103. throwing_arrow_punch_entity(obj, self, damage)
  104. self.object:remove()
  105. boom(pos)
  106. end
  107. end
  108. end
  109. if self.timer > 2 then
  110. self.object:remove()
  111. boom(self.lastpos)
  112. end
  113. if self.lastpos.x~=nil then
  114. if throwing_node_should_block_arrow(node.name) then
  115. self.object:remove()
  116. boom(self.lastpos)
  117. end
  118. end
  119. if node.name == 'air' then
  120. minetest.add_node(pos, {name="throwing:firework_trail"})
  121. minetest.get_node_timer(pos):start(0.1)
  122. end
  123. self.lastpos={x=pos.x, y=pos.y, z=pos.z}
  124. end
  125. minetest.register_entity("throwing:arrow_fireworks_" .. color .. "_entity", THROWING_ARROW_ENTITY)
  126. minetest.register_craft({
  127. output = 'throwing:arrow_fireworks_' .. color .. ' 8',
  128. recipe = {
  129. {'default:stick', 'tnt:gunpowder', 'dye:' .. color},
  130. }
  131. })
  132. minetest.register_craft({
  133. output = 'throwing:arrow_fireworks_' .. color .. ' 8',
  134. recipe = {
  135. {'dye:' .. color, 'tnt:gunpowder', 'default:stick'},
  136. }
  137. })
  138. end
  139. --~ Arrows
  140. if not DISABLE_FIREWORKS_BLUE_ARROW then
  141. throwing_register_fireworks('blue', 'Blue')
  142. end
  143. if not DISABLE_FIREWORKS_RED_ARROW then
  144. throwing_register_fireworks('red', 'Red')
  145. end
  146. --~ Nodes
  147. minetest.register_node("throwing:firework_trail", {
  148. drawtype = "airlike",
  149. light_source = 9,
  150. walkable = false,
  151. pointable = false,
  152. buildable_to = true,
  153. drop = "",
  154. groups = utility.dig_groups("item"),
  155. on_timer = function(pos, elapsed)
  156. minetest.remove_node(pos)
  157. end,
  158. })
  159. minetest.register_node("throwing:firework_boom", {
  160. drawtype = "plantlike",
  161. tiles = {"throwing_sparkle.png"},
  162. light_source = default.LIGHT_MAX - 1,
  163. walkable = false,
  164. drop = "",
  165. groups = utility.dig_groups("item"),
  166. on_timer = function(pos, elapsed)
  167. minetest.remove_node(pos)
  168. end,
  169. after_destruct = function(pos, oldnode)
  170. minetest.set_node(pos, {name="throwing:firework_light"})
  171. minetest.get_node_timer(pos):start(3)
  172. end,
  173. })
  174. minetest.register_node("throwing:firework_light", {
  175. drawtype = "airlike",
  176. light_source = default.LIGHT_MAX - 1,
  177. pointable = false,
  178. buildable_to = true,
  179. walkable = false,
  180. drop = "",
  181. groups = utility.dig_groups("item"),
  182. on_timer = function(pos, elapsed)
  183. minetest.remove_node(pos)
  184. end,
  185. })