teleport.lua 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. -- Localize for performance.
  2. local vector_round = vector.round
  3. function serveressentials.do_teleport(name, param)
  4. name = name:trim()
  5. param = param:trim()
  6. -- Returns (pos, true) if found, otherwise (pos, false)
  7. local function find_free_position_near(pos)
  8. pos = vector_round(pos)
  9. local tries = {
  10. {x=1,y=0,z=0},
  11. {x=-1,y=0,z=0},
  12. {x=0,y=0,z=1},
  13. {x=0,y=0,z=-1},
  14. }
  15. for _, d in ipairs(tries) do
  16. local p = {x = pos.x+d.x, y = pos.y+d.y, z = pos.z+d.z}
  17. local n = core.get_node_or_nil(p)
  18. if n and n.name then
  19. local def = core.registered_nodes[n.name]
  20. if def and not def.walkable then
  21. if rc.is_valid_realm_pos(p) then
  22. return p, true
  23. end
  24. end
  25. end
  26. end
  27. return pos, false
  28. end
  29. local teleportee = nil
  30. local p = {}
  31. p.x, p.y, p.z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
  32. p.x = tonumber(p.x)
  33. p.y = tonumber(p.y)
  34. p.z = tonumber(p.z)
  35. if p.x and p.y and p.z then
  36. p = vector_round(p)
  37. local lm = 31000
  38. if p.x < -lm or p.x > lm or p.y < -lm or p.y > lm or p.z < -lm or p.z > lm then
  39. return false, "Cannot teleport out of map bounds."
  40. end
  41. if not rc.is_valid_realm_pos(p) then
  42. return false, "Cannot teleport outside of any realm."
  43. end
  44. teleportee = core.get_player_by_name(name)
  45. if teleportee then
  46. local o = vector_round(teleportee:get_pos())
  47. rc.notify_realm_update(teleportee:get_player_name(), p)
  48. teleportee:set_pos(p)
  49. return true, "Teleporting from " .. rc.pos_to_namestr(o) .. " to " .. core.pos_to_string(p) .. ", which is @ " .. rc.pos_to_namestr(p) .. "."
  50. end
  51. end
  52. local teleportee = nil
  53. local p = {}
  54. local realm = nil
  55. --minetest.chat_send_player(name, param)
  56. realm, p.x, p.y, p.z = string.match(param, "^([^ ]+) *: *([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
  57. p.x = tonumber(p.x)
  58. p.y = tonumber(p.y)
  59. p.z = tonumber(p.z)
  60. --minetest.chat_send_player(name, "Got: " .. realm .. ":" .. p.x .. "," .. p.y .. "," .. p.z)
  61. if realm and p.x and p.y and p.z then
  62. p = rc.realmpos_to_pos(realm, p)
  63. if not p then
  64. return false, "Cannot interpret realm coordinates."
  65. end
  66. local lm = 31000
  67. if p.x < -lm or p.x > lm or p.y < -lm or p.y > lm or p.z < -lm or p.z > lm then
  68. return false, "Cannot teleport out of map bounds."
  69. end
  70. if not rc.is_valid_realm_pos(p) then
  71. return false, "Cannot teleport outside of any realm."
  72. end
  73. teleportee = core.get_player_by_name(name)
  74. if teleportee then
  75. local o = vector_round(teleportee:get_pos())
  76. rc.notify_realm_update(teleportee:get_player_name(), p)
  77. teleportee:set_pos(p)
  78. return true, "Teleporting from " .. rc.pos_to_namestr(o) .. " to " .. rc.pos_to_namestr(p) .. "."
  79. end
  80. end
  81. local teleportee = nil
  82. local p = nil
  83. local target_name = nil
  84. target_name = param:match("^([^ ]+)$")
  85. teleportee = core.get_player_by_name(name)
  86. if target_name then
  87. local target = core.get_player_by_name(target_name)
  88. if target then
  89. p = vector_round(target:get_pos())
  90. end
  91. end
  92. if teleportee and p then
  93. p = find_free_position_near(p)
  94. if not rc.is_valid_realm_pos(p) then
  95. return false, "Cannot teleport outside of any realm."
  96. end
  97. local o = vector_round(teleportee:get_pos())
  98. rc.notify_realm_update(teleportee:get_player_name(), p)
  99. teleportee:set_pos(p)
  100. return true, "Teleporting from " .. rc.pos_to_namestr(o) .. " to <" .. rename.gpn(target_name) .. "> at " .. rc.pos_to_namestr(p) .. "."
  101. end
  102. if not core.check_player_privs(name, {bring=true}) then
  103. return false, "You don't have permission to teleport other players (missing bring privilege)."
  104. end
  105. local teleportee = nil
  106. local p = {}
  107. local teleportee_name = nil
  108. teleportee_name, p.x, p.y, p.z = param:match("^([^ ]+) +([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
  109. p.x, p.y, p.z = tonumber(p.x), tonumber(p.y), tonumber(p.z)
  110. if teleportee_name then
  111. teleportee = core.get_player_by_name(teleportee_name)
  112. end
  113. if teleportee and p.x and p.y and p.z then
  114. p = vector_round(p)
  115. if not rc.is_valid_realm_pos(p) then
  116. return false, "Cannot teleport players outside realm boundaries."
  117. end
  118. local o = vector_round(teleportee:get_pos())
  119. rc.notify_realm_update(teleportee:get_player_name(), p)
  120. teleportee:set_pos(p)
  121. return true, "Teleporting <" .. rename.gpn(teleportee_name) .. "> from " .. rc.pos_to_namestr(o) .. " to " .. core.pos_to_string(p) .. ", which is @ " .. rc.pos_to_namestr(p) .. "."
  122. end
  123. local teleportee = nil
  124. local p = {}
  125. local teleportee_name = nil
  126. local realm = nil
  127. teleportee_name, realm, p.x, p.y, p.z = param:match("^([^ ]+) +([^ ]+) *: *([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
  128. p.x, p.y, p.z = tonumber(p.x), tonumber(p.y), tonumber(p.z)
  129. if teleportee_name then
  130. teleportee = core.get_player_by_name(teleportee_name)
  131. end
  132. if teleportee and realm and p.x and p.y and p.z then
  133. p = rc.realmpos_to_pos(realm, p)
  134. if not p then
  135. return false, "Cannot interpret realm coordinates."
  136. end
  137. if not rc.is_valid_realm_pos(p) then
  138. return false, "Cannot teleport players outside realm boundaries."
  139. end
  140. local o = vector_round(teleportee:get_pos())
  141. rc.notify_realm_update(teleportee:get_player_name(), p)
  142. teleportee:set_pos(p)
  143. return true, "Teleporting <" .. rename.gpn(teleportee_name) .. "> from " .. rc.pos_to_namestr(o) .. " to " .. rc.pos_to_namestr(p) .. "."
  144. end
  145. local teleportee = nil
  146. local p = nil
  147. local teleportee_name = nil
  148. local target_name = nil
  149. teleportee_name, target_name = string.match(param, "^([^ ]+) +([^ ]+)$")
  150. if teleportee_name then
  151. teleportee = core.get_player_by_name(teleportee_name)
  152. end
  153. if target_name then
  154. local target = core.get_player_by_name(target_name)
  155. if target then
  156. p = target:get_pos()
  157. end
  158. end
  159. if teleportee and p then
  160. p = vector_round(p)
  161. if not rc.is_valid_realm_pos(p) then
  162. return false, "Cannot teleport players outside realm boundaries."
  163. end
  164. p = find_free_position_near(p)
  165. local o = vector_round(teleportee:get_pos())
  166. rc.notify_realm_update(teleportee:get_player_name(), p)
  167. teleportee:set_pos(p)
  168. return true, "Teleporting <" .. rename.gpn(teleportee_name) .. "> from " .. rc.pos_to_namestr(o) .. " to <" .. rename.gpn(target_name) .. "> at " .. rc.pos_to_namestr(p) .. "."
  169. end
  170. return false, 'Invalid parameters or player not found (see /help teleport).'
  171. end