init.lua 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. jaunt = jaunt or {}
  2. jaunt.modpath = minetest.get_modpath("jaunt")
  3. -- Localize for performance.
  4. local vector_distance = vector.distance
  5. local vector_round = vector.round
  6. -- private: assemble a formspec string
  7. function jaunt.get_formspec(player)
  8. local formspec = "size[4.5,5.5]" ..
  9. default.gui_bg ..
  10. default.gui_bg_img ..
  11. default.gui_slots
  12. formspec = formspec ..
  13. "item_image[0,0;1,1;passport:passport_adv]" ..
  14. "label[1,0;Key: Teleport to player beacon.]" ..
  15. "label[1,0.4;Requires teleport for anchor.]" ..
  16. "field[0.3,1.3;2.9,1;player;;]" ..
  17. "button[3.0,1.0;1.5,1;go;Jaunt]" ..
  18. "field_close_on_enter[player;true]" ..
  19. "button[1.25,2.0;2.25,1;cancel;Abort]" ..
  20. "label[0,3;Jaunt range is influenced by the status\nof the target's beacon. Marked players can\nbe found from farther.]" ..
  21. "item_image[1.25,4.5;1,1;command_tokens:mark_player]" ..
  22. "item_image[2.25,4.5;1,1;player_labels:show]"
  23. return formspec
  24. end
  25. -- api: show formspec to player
  26. function jaunt.show_formspec(player)
  27. local formspec = jaunt.get_formspec(player)
  28. minetest.show_formspec(player, "jaunt:fs", formspec)
  29. end
  30. -- Find nearby teleport, and return its range.
  31. function jaunt.valid_teleport(pos)
  32. local tar = minetest.find_node_near(pos, 2, "teleports:teleport", true)
  33. if tar then
  34. -- Range is halved because when we're jaunting, there is no teleport at the
  35. -- other end to receive us! Also, this means that when using a nyan TP, the
  36. -- range is more-or-less the same as the original, hard-coded jaunt range.
  37. local range = teleports.calculate_range(tar)
  38. return true, (range * 0.5)
  39. end
  40. end
  41. jaunt.on_receive_fields = function(player, formname, fields)
  42. if formname ~= "jaunt:fs" then return end
  43. local pname = player:get_player_name()
  44. -- security check to make sure player can use this feature
  45. if not passport.player_has_key(pname) then
  46. return true
  47. end
  48. if not survivalist.player_beat_cave_challenge(pname) then
  49. return true
  50. end
  51. -- Jaunt ability is revoked for cheaters.
  52. if sheriff.is_cheater(pname) then
  53. return true
  54. end
  55. if fields.cancel then
  56. passport.show_formspec(pname)
  57. return true
  58. end
  59. if fields.quit then
  60. return true
  61. end
  62. local uspos = vector_round(player:get_pos())
  63. if fields.key_enter_field == "player" or fields.go then
  64. local success, tp_range = jaunt.valid_teleport(uspos)
  65. if success then -- Teleport was found.
  66. local target = rename.grn((fields.player or ""):trim())
  67. if target ~= pname then
  68. local other = minetest.get_player_by_name(target)
  69. if other and other:is_player() and not cloaking.is_cloaked(target) then
  70. local marked = command_tokens.mark.player_marked(target)
  71. local beacon = player_labels.query_nametag_onoff(target)
  72. -- a player can be located if either they're marked or their beacon (nametag) is activated
  73. if marked or beacon then
  74. if passport.player_has_key(target) then
  75. -- if a player is marked, but their beacon is off, then the range at which
  76. -- they can be detected is halved
  77. local range = tp_range
  78. if marked and not beacon then
  79. range = range * 0.5
  80. elseif marked and beacon then
  81. range = range * 1.5
  82. end
  83. local tarpos = other:get_pos()
  84. tarpos.y = tarpos.y + 1
  85. tarpos = vector_round(tarpos)
  86. if rc.current_realm_at_pos(tarpos) == rc.current_realm_at_pos(uspos) then
  87. if vector_distance(tarpos, uspos) < range then
  88. -- Alert player that someone's coming to them.
  89. local RED = core.get_color_escape_sequence("#ff0000")
  90. minetest.chat_send_player(target,
  91. RED .. "# Server: Alert! Incoming jaunt from <" ..
  92. rename.gpn(pname) .. ">.")
  93. chat_core.alert_player_sound(target)
  94. -- Teleport player to chosen location.
  95. preload_tp.execute({
  96. player_name = pname,
  97. target_position = tarpos,
  98. send_blocks = true,
  99. particle_effects = true,
  100. -- Pre-teleport callback.
  101. pre_teleport_callback = function()
  102. -- Abort teleport if target player cloaked themselves.
  103. if cloaking.is_cloaked(target) then
  104. minetest.chat_send_player(pname, "# Server: Lost link to target beacon.")
  105. return true -- Abort transport.
  106. end
  107. end,
  108. -- Post-teleport callback.
  109. post_teleport_callback = function()
  110. portal_sickness.on_use_portal(pname)
  111. end,
  112. })
  113. -- don't reshow the formspec
  114. minetest.close_formspec(pname, "jaunt:fs")
  115. return true
  116. else
  117. minetest.chat_send_player(pname, "# Server: Target Key's signal origin is too weak to accurately triangulate!")
  118. end
  119. else
  120. minetest.chat_send_player(pname, "# Server: Target's Key is not located in this realm!")
  121. end
  122. else
  123. minetest.chat_send_player(pname, "# Server: Target's beacon signal does not originate from an authentic Key device.")
  124. end
  125. else
  126. minetest.chat_send_player(pname, "# Server: Could not detect evidence of a Key's beacon signal.")
  127. end
  128. else
  129. minetest.chat_send_player(pname, "# Server: Could not detect evidence of a Key's beacon signal.")
  130. end
  131. else
  132. minetest.chat_send_player(pname, "# Server: Cleverly refusing to scan for your own Key's beacon signal.")
  133. end
  134. else
  135. minetest.chat_send_player(pname, "# Server: Your Key requires access to a proximate teleport to deploy this function.")
  136. end
  137. end
  138. jaunt.show_formspec(pname)
  139. return true
  140. end
  141. if not jaunt.registered then
  142. minetest.register_on_player_receive_fields(function(...)
  143. return jaunt.on_receive_fields(...)
  144. end)
  145. local c = "jaunt:core"
  146. local f = jaunt.modpath .. "/init.lua"
  147. reload.register_file(c, f, false)
  148. jaunt.registered = true
  149. end