absent_ballooner_rescuing.lua 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. --localize things for better performance
  2. local serialize = minetest.serialize
  3. local add_entity = minetest.add_entity
  4. local after = minetest.after
  5. --for storing which players left while in a balloon
  6. local storage = minetest.get_mod_storage()
  7. local absent_ballooners = minetest.deserialize(storage:get_string("absent_ballooners")) or {}
  8. --putting leaving people into storage
  9. local leave_while_ballooning = function(player)
  10. local parent = player:get_attach()
  11. if parent and not parent:is_player()
  12. then
  13. local balloon_type = parent:get_luaentity().balloon_type
  14. if balloon_type
  15. then
  16. --remove() only works if someone else is in the area,
  17. --hence the need for mark_for_deletion
  18. parent:remove()
  19. absent_ballooners[player:get_player_name()] = balloon_type
  20. end
  21. end
  22. end
  23. --same as on_leave but for all players at once
  24. local on_shutdown = function()
  25. local connected_players = minetest.get_connected_players()
  26. for i, p in ipairs(connected_players)
  27. do
  28. leave_while_ballooning(p)
  29. end
  30. storage:set_string("absent_ballooners", serialize(absent_ballooners))
  31. end
  32. --putting leaving people into storage and saving storage
  33. local on_leave = function(player)
  34. leave_while_ballooning(player)
  35. storage:set_string("absent_ballooners", serialize(absent_ballooners))
  36. end
  37. minetest.register_on_leaveplayer(on_leave)
  38. minetest.register_on_shutdown(on_shutdown)
  39. --checking if player who joined was ballooning when they left
  40. --if so spawn a new balloon and set them as attachment
  41. local on_join = function(player)
  42. if player
  43. then
  44. local name = player:get_player_name()
  45. if absent_ballooners[name]
  46. then
  47. local pos = player:get_pos()
  48. --for compatibility with version 1.1 of the mod
  49. if absent_ballooners[name] == true
  50. then
  51. absent_ballooners[name] = "hot_air_balloons:balloon"
  52. end
  53. --minetest doesn't seem to like add_entity on init so a minetest.after is used
  54. --player is set as pilot in on_activate
  55. after(2,
  56. function()
  57. --concatenating "P" with name signals that player should be set as attach
  58. add_entity(pos, absent_ballooners[name], "P" .. name)
  59. end)
  60. end
  61. end
  62. end
  63. minetest.register_on_joinplayer(on_join)
  64. --called in on_activate if balloon was spawned to rescue an absent ballooner
  65. local set_rescue = function(self, playername)
  66. local player = minetest.get_player_by_name(playername)
  67. self.pilot = playername
  68. if not player --player logged off right away
  69. then
  70. self.object:remove()
  71. return
  72. end
  73. player:set_attach(self.object, "",
  74. {x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0})
  75. absent_ballooners[playername] = nil
  76. end
  77. --set as get_staticdata
  78. local mark_for_deletion = function(self)
  79. if self.pilot
  80. then
  81. --pilot logged off while ballooning, deleting balloon on next activation
  82. return "R"
  83. else
  84. --normally save and load balloon
  85. return ""
  86. end
  87. end
  88. return set_rescue, mark_for_deletion