absent_ballooner_rescuing.lua 2.6 KB

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