init.lua 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. jail = jail or {}
  2. jail.modpath = minetest.get_modpath("jail")
  3. jail.noclip_radius = 15 -- Max distance of player from jail.
  4. local function jailposition(player)
  5. local pos = {x=0, y=-50, z=0}
  6. if player:get_pos().y < -25000 then
  7. pos.y = -30765
  8. end
  9. return pos
  10. end
  11. -- This function shall be called only when player escapes jail via hack, etc.
  12. -- Shall return the player to the nearest jail within their current dimension.
  13. function jail.on_player_escaped_jail(pref)
  14. local jp = jailposition(pref)
  15. default.detach_player_if_attached(pref) -- Otherwise teleport could fail.
  16. local pname = pref:get_player_name()
  17. local cb = function(pname)
  18. local pref = minetest.get_player_by_name(pname)
  19. if pref then
  20. -- AFTER player has been teleported back, damage them.
  21. pref:set_pos(jp)
  22. pref:set_hp(pref:get_hp() - 1)
  23. end
  24. end
  25. preload_tp.preload_and_teleport(pname, jp, 8, nil, cb, pname, true)
  26. end
  27. function jail.is_player_in_jail(pref)
  28. local jp = jailposition(pref) -- Get position of jail.
  29. local pp = pref:get_pos() -- Position of player.
  30. local dt = vector.distance(jp, pp) -- Distance between points.
  31. if dt > jail.noclip_radius then
  32. return false -- Player is NOT in jail!
  33. end
  34. return true -- Player is in jail.
  35. end
  36. function jail.check_player_in_jail(pname)
  37. local pref = minetest.get_player_by_name(pname)
  38. if pref then
  39. local meta = pref:get_meta()
  40. if meta:get_int("should_be_in_jail") == 1 then
  41. -- Here we check to make sure player actually is still in jail!
  42. if not jail.is_player_in_jail(pref) then
  43. jail.on_player_escaped_jail(pref)
  44. end
  45. -- Check again in 1 second.
  46. minetest.after(1, jail.check_player_in_jail, pname)
  47. end
  48. end -- Else player has logged out.
  49. -- Checks will resume when player (any player) logs in again.
  50. end
  51. function jail.go_to_jail(player, bcb)
  52. local pname = player:get_player_name()
  53. local fwrap = function(...)
  54. local pref = minetest.get_player_by_name(pname)
  55. if pref then
  56. jail.notify_sent_to_jail(pref)
  57. end
  58. if bcb then
  59. bcb(...)
  60. end
  61. end
  62. local jailpos = jailposition(player)
  63. preload_tp.preload_and_teleport(pname, jailpos, 32, nil, fwrap, nil, true)
  64. end
  65. function jail.notify_sent_to_jail(pref)
  66. -- Set key on player indicating that they should currently be in jail.
  67. -- This key should be cleared only if they leave jail through legit means!
  68. local meta = pref:get_meta()
  69. meta:set_int("should_be_in_jail", 1)
  70. minetest.after(1, jail.check_player_in_jail, pref:get_player_name())
  71. end
  72. function jail.notify_player_death(pref)
  73. local meta = pref:get_meta()
  74. meta:set_int("should_be_in_jail", 0)
  75. end
  76. local jail_data = {
  77. name = "Colony Jail",
  78. codename = "jail:jail",
  79. position = jailposition,
  80. min_dist = 30,
  81. }
  82. jail_data.on_success = function(name)
  83. local pref = minetest.get_player_by_name(name)
  84. if pref then
  85. jail.notify_sent_to_jail(pref)
  86. local dname = rename.gpn(name)
  87. minetest.chat_send_all("# Server: <" .. dname .. "> sent to jail for no particular reason.")
  88. end
  89. end
  90. jail_data.suppress = function(name)
  91. local player = minetest.get_player_by_name(name)
  92. if player and player:is_player() then
  93. if vector.distance(player:getpos(), jail_data.position(player)) < jail_data.min_dist then
  94. minetest.chat_send_player(name, "# Server: Error: security override. Recall is disabled within convict re-education block.")
  95. easyvend.sound_error(name)
  96. return true -- Too close to jail.
  97. end
  98. end
  99. end
  100. jail.suppress = jail_data.suppress
  101. passport.register_recall(jail_data)
  102. minetest.register_on_joinplayer(function(pref)
  103. minetest.after(5, jail.check_player_in_jail, pref:get_player_name())
  104. end)