init.lua 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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 function get_fuel_value(item)
  35. input = {
  36. method = "fuel",
  37. items = {item},
  38. }
  39. return minetest.get_craft_result(input).time or 0
  40. end
  41. local add_heat = function(self, player)
  42. local item_stack = player:get_wielded_item()
  43. local fuelval = get_fuel_value(item_stack)
  44. if not fuelval or fuelval == 0 then
  45. return false
  46. end
  47. local heat = self.heat
  48. heat = heat + 30 * fuelval --for coal lump 1 min until heat is back to original
  49. if heat < 12000 --cap heat at 12000 (10 min)
  50. then
  51. self.heat = heat
  52. --adding particle effect
  53. local pos = self.object:get_pos()
  54. add_particlespawner(get_fire_particle(pos))
  55. if not is_in_creative(player:get_player_name())
  56. then
  57. item_stack:take_item()
  58. player:set_wielded_item(item_stack)
  59. end
  60. end
  61. return true
  62. end
  63. --global table, has fields get_entity_def and get_item_def
  64. --custom balloons right now turn into normal ones when the pilot leaves
  65. hot_air_balloons = {}
  66. hot_air_balloons.get_entity = function(name, mesh_name, texture_name)
  67. return
  68. name,
  69. {
  70. initial_properties =
  71. {
  72. hp_max = 1,
  73. physical = true,
  74. weight = 5,
  75. collisionbox = {-0.65, -0.01, -0.65, 0.65, 1.11, 0.65},
  76. visual = "mesh",
  77. mesh = "hot_air_balloons_balloon.obj",
  78. textures = {"hot_air_balloons_balloon_model.png"},
  79. is_visible = true,
  80. makes_footstep_sound = false,
  81. backface_culling = false,
  82. },
  83. heat = 0,
  84. balloon_type = name,
  85. on_step = function(self, dtime)
  86. --decrease heat, move
  87. if self.heat > 0
  88. then
  89. self.heat = self.heat - 1
  90. end
  91. handle_movement(self)
  92. end,
  93. on_rightclick = function (self, clicker)
  94. --if hoding coal, increase heat, else mount/dismount
  95. if not clicker or not clicker:is_player()
  96. then
  97. return
  98. end
  99. --checking if clicker is holding coal
  100. --heating balloon and returning if yes
  101. if add_heat(self, clicker)
  102. then
  103. return
  104. end
  105. --if not holding coal:
  106. local playername = clicker:get_player_name()
  107. if self.pilot and self.pilot == playername
  108. then
  109. self.pilot = nil
  110. clicker:set_detach()
  111. elseif not self.pilot
  112. then
  113. --attach
  114. self.pilot = playername
  115. clicker:set_attach(self.object, "",
  116. {x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0})
  117. end
  118. end,
  119. --if pilot leaves start sinking and prepare for next pilot
  120. on_detach_child = function(self, child)
  121. self.heat = 0
  122. self.object:setvelocity({x = 0, y = 0, z = 0})
  123. end,
  124. on_activate = function(self, staticdata, dtime_s)
  125. self.object:set_armor_groups({punch_operable = 1})
  126. --so balloons don't get lost
  127. self.object:setvelocity({x = 0, y = 0, z = 0})
  128. --checking if balloon was spawned from item or unloaded without pilot
  129. if staticdata == ""
  130. then
  131. return
  132. end
  133. --checking if balloon should despawn when pilot logged off
  134. local first_char = string_byte(staticdata)
  135. --ballooner logged off, balloon will respawn when ballooner logs back in
  136. if first_char == 82 --chr 82 = R
  137. then
  138. self.object:remove()
  139. return
  140. --absent ballooner logged back in
  141. elseif first_char == 80 --chr 80 = P
  142. then
  143. set_rescue(self, string_sub(staticdata, 2))
  144. end
  145. end,
  146. get_staticdata = mark_for_deletion_if_piloted,
  147. on_punch = function(self, puncher) --drop balloon item
  148. if self.pilot
  149. then
  150. return
  151. elseif not (puncher and puncher:is_player())
  152. then
  153. return
  154. else
  155. self.object:remove()
  156. local inv = puncher:get_inventory()
  157. if not is_in_creative(puncher:get_player_name())
  158. or not inv:contains_item("main", "hot_air_balloons:item")
  159. then
  160. local leftover = inv:add_item("main", "hot_air_balloons:item")
  161. if not leftover:is_empty()
  162. then
  163. add_item(self.object:get_pos(), leftover)
  164. end
  165. end
  166. end
  167. end,
  168. }
  169. end
  170. hot_air_balloons.get_item = function(name, description, texture, object_name)
  171. return
  172. name,
  173. {
  174. description = description,
  175. inventory_image = texture,
  176. stack_max = 1,
  177. liquids_pointable = true,
  178. groups = {flammable = 2},
  179. on_place =
  180. function (itemstack, placer, pointed_thing)
  181. --places balloon if the clicked thing is a node and the above node is air
  182. if pointed_thing.type == "node"
  183. and get_node (pointed_thing.above).name == "air"
  184. then
  185. if not is_in_creative(placer:get_player_name())
  186. then
  187. itemstack:take_item()
  188. end
  189. local pos_to_place = pointed_thing.above
  190. pos_to_place.y = pos_to_place.y - 0.5 --subtracting 0.5 to place on ground
  191. add_entity(pointed_thing.above, object_name)
  192. end
  193. --add remaining items to inventory
  194. return itemstack
  195. end
  196. }
  197. end
  198. --registering the balloon entity, item and recepies
  199. minetest.register_entity(hot_air_balloons.get_entity(
  200. "hot_air_balloons:balloon",
  201. "hot_air_balloons_balloon.obj",
  202. "hot_air_balloons_balloon_model.png"))
  203. minetest.register_craftitem(hot_air_balloons.get_item(
  204. "hot_air_balloons:item",
  205. minetest.translate("hot_air_balloons", "Hot Air Balloon"),
  206. "hot_air_balloons_balloon.png",
  207. "hot_air_balloons:balloon"))
  208. dofile(modpath .. "/craft.lua")