init.lua 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. --localize functions for better performance
  2. local string_byte = string.byte
  3. local string_sub = string.sub
  4. local get_item_group = minetest.get_item_group
  5. local add_particlespawner = minetest.add_particlespawner
  6. local add_item = minetest.add_item
  7. local get_node = minetest.get_node
  8. local add_entity = minetest.add_entity
  9. local modpath = minetest.get_modpath("hot_air_balloons")
  10. local set_rescue, mark_for_deletion_if_piloted = dofile(modpath .. "/absent_ballooner_rescuing.lua")
  11. local handle_movement = dofile(modpath .. "/movement.lua")
  12. local is_in_creative = function(name)
  13. return creative and creative.is_enabled_for
  14. and creative.is_enabled_for(name)
  15. end
  16. local get_fire_particle = function (pos)
  17. pos.y = pos.y + 3
  18. return {
  19. amount = 3,
  20. time = 1,
  21. minpos = pos,
  22. maxpos = pos,
  23. minvel = {x = 0, y = 1, z = 0},
  24. maxvel = {x = 0, y = 1, z = 0},
  25. minexptime = 1,
  26. maxexptime = 1,
  27. minsize = 10,
  28. maxsize = 5,
  29. collisiondetection = false,
  30. vertical = false,
  31. texture = "hot_air_balloons_flame.png"
  32. }
  33. end
  34. local add_heat = function(self, player)
  35. local item_stack = player:get_wielded_item()
  36. local item_name = item_stack:get_name()
  37. local group_coal = get_item_group(item_name, "coal")
  38. if group_coal == 0
  39. then
  40. return false
  41. end
  42. local heat = self.heat
  43. heat = heat + 1200 * group_coal --1 min until heat is back to original
  44. if heat < 12000 --cap heat at 12000 (10 min)
  45. then
  46. self.heat = heat
  47. --adding particle effect
  48. local pos = self.object:get_pos()
  49. add_particlespawner(get_fire_particle(pos))
  50. if not is_in_creative(player:get_player_name())
  51. then
  52. item_stack:take_item()
  53. player:set_wielded_item(item_stack)
  54. end
  55. end
  56. return true
  57. end
  58. local hot_air_balloon_entity_def =
  59. {
  60. initial_properties =
  61. {
  62. hp_max = 20, --higher health so accidental death isn't as easy
  63. physical = true,
  64. weight = 5,
  65. collisionbox = {-0.65, -0.01, -0.65, 0.65, 1.11, 0.65},
  66. visual = "mesh",
  67. mesh = "hot_air_balloons_balloon.obj",
  68. textures = {"hot_air_balloons_balloon_model.png"},
  69. is_visible = true,
  70. makes_footstep_sound = false,
  71. automatic_rotate = false,
  72. backface_culling = false,
  73. },
  74. heat = 0,
  75. is_hot_air_balloon = true,
  76. on_step = function(self, dtime)
  77. --decrease heat, move
  78. if self.heat > 0
  79. then
  80. self.heat = self.heat - 1
  81. end
  82. handle_movement(self)
  83. end,
  84. on_rightclick = function (self, clicker)
  85. --if hoding coal, increase heat, else mount/dismount
  86. if not clicker or not clicker:is_player()
  87. then
  88. return
  89. end
  90. --checking if clicker is holding coal
  91. --heating balloon and returning if yes
  92. if add_heat(self, clicker)
  93. then
  94. return
  95. end
  96. --if not holding coal:
  97. local playername = clicker:get_player_name()
  98. if self.pilot and self.pilot == playername
  99. then
  100. self.pilot = nil
  101. clicker:set_detach()
  102. elseif not self.pilot
  103. then
  104. --attach
  105. self.pilot = playername
  106. clicker:set_attach(self.object, "",
  107. {x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0})
  108. end
  109. end,
  110. --if pilot leaves start sinking and prepare for next pilot
  111. on_detach_child = function(self, child)
  112. self.heat = 0
  113. self.object:setvelocity({x = 0, y = 0, z = 0})
  114. end,
  115. on_activate = function(self, staticdata, dtime_s)
  116. --so balloons don't get lost
  117. self.object:setvelocity({x = 0, y = 0, z = 0})
  118. --checking if balloon was spawned from item or unloaded without pilot
  119. if staticdata == ""
  120. then
  121. return
  122. end
  123. --checking if balloon should despawn when pilot logged off
  124. local first_char = string_byte(staticdata)
  125. --ballooner logged off, balloon will respawn when ballooner logs back in
  126. if first_char == 82 --chr 82 = R
  127. then
  128. self.object:remove()
  129. return
  130. --absent ballooner logged back in
  131. elseif first_char == 80 --chr 80 = P
  132. then
  133. set_rescue(self, string_sub(staticdata, 2))
  134. end
  135. end,
  136. get_staticdata = mark_for_deletion_if_piloted,
  137. on_punch = function(self, puncher) --drop balloon item
  138. if not (puncher and puncher:is_player())
  139. then
  140. return
  141. end
  142. local inv = puncher:get_inventory()
  143. if not is_in_creative(puncher:get_player_name())
  144. or not inv:contains_item("main", "hot_air_balloons:item")
  145. then
  146. local leftover = inv:add_item("main", "hot_air_balloons:item")
  147. if not leftover:is_empty()
  148. then
  149. add_item(self.object:get_pos(), leftover)
  150. end
  151. end
  152. end,
  153. }
  154. minetest.register_entity("hot_air_balloons:balloon", hot_air_balloon_entity_def)
  155. --Defining and registering hot air balloon item
  156. local hot_air_balloon_item_def =
  157. {
  158. description = "Hot Air Balloon",
  159. inventory_image = "hot_air_balloons_balloon.png",
  160. stack_max = 1,
  161. liquids_pointable = true,
  162. groups = {flammable = 2},
  163. on_place =
  164. function (itemstack, placer, pointed_thing)
  165. --places balloon if the clicked thing is a node and the above node is air
  166. if pointed_thing.type == "node"
  167. and get_node (pointed_thing.above).name == "air"
  168. then
  169. if not is_in_creative(placer:get_player_name())
  170. then
  171. itemstack:take_item()
  172. end
  173. local pos_to_place = pointed_thing.above
  174. pos_to_place.y = pos_to_place.y - 0.5 --subtracting 0.5 to place on ground
  175. add_entity(pointed_thing.above, "hot_air_balloons:balloon")
  176. end
  177. --add remaining items to inventory
  178. return itemstack
  179. end
  180. }
  181. minetest.register_craftitem("hot_air_balloons:item", hot_air_balloon_item_def)
  182. minetest.register_craft(
  183. {
  184. output = "hot_air_balloons:item",
  185. recipe = {
  186. {"default:paper", "default:paper", "default:paper"},
  187. {"default:paper", "bucket:bucket_lava", "default:paper"},
  188. {"", "group:wood", "" },
  189. },
  190. })
  191. minetest.register_craft(
  192. {
  193. type = "fuel",
  194. recipe = "hot_air_balloons:item",
  195. burntime = 20,
  196. })
  197. --[[
  198. minetest.register_craft(
  199. {
  200. type = "aircraft"
  201. }
  202. ]]