init.lua 4.1 KB

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