From 4ab5a83b283b343fef22e9b0f1f35a27d9ae06a3 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jun 2023 12:58:50 +0100 Subject: [PATCH] feat: add teleportation to the nearest spawnpoint --- .../commands/spawn/SpawnCommand.java | 8 ++- .../advancedteleport/config/NewConfig.java | 5 ++ .../advancedteleport/config/Spawn.java | 64 ++++++++++++++++++- .../listeners/SignInteractListener.java | 4 +- .../managers/TeleportTrackingManager.java | 6 +- 5 files changed, 77 insertions(+), 10 deletions(-) diff --git a/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/commands/spawn/SpawnCommand.java b/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/commands/spawn/SpawnCommand.java index e3695db97..b40316670 100644 --- a/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/commands/spawn/SpawnCommand.java +++ b/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/commands/spawn/SpawnCommand.java @@ -47,19 +47,21 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command return true; } String location = player.getWorld().getName(); + boolean specific = false; if (args.length > 0 && (player.hasPermission("at.admin.spawn") || player.hasPermission("at.member.spawn." + args[0].toLowerCase()))) { if (args[0].matches("^[0-9A-Za-z\\-_]+$")) { location = args[0]; + specific = true; } } - spawn(player, location); + spawn(player, location, specific); return true; } - public static void spawn(Player player, String name) { + public static void spawn(Player player, String name, boolean specific) { Location spawn; - spawn = Spawn.get().getSpawn(name, player, false); + spawn = Spawn.get().getSpawn(name, player, false, specific); if (spawn == null) { spawn = player.getWorld().getSpawnLocation(); } diff --git a/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/config/NewConfig.java b/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/config/NewConfig.java index b9c7c4162..2afe16e2f 100644 --- a/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/config/NewConfig.java +++ b/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/config/NewConfig.java @@ -98,6 +98,7 @@ public class NewConfig extends ATConfig { public ConfigOption TELEPORT_TO_SPAWN_FIRST; public ConfigOption FIRST_SPAWN_POINT; public ConfigOption TELEPORT_TO_SPAWN_EVERY; + public ConfigOption TELEPORT_TO_NEAREST_SPAWN; public ConfigOption DEATH_MANAGEMENT; @@ -442,6 +443,9 @@ public void loadDefaults() { "If it is blank, then it will take the main spawnpoint."); addDefault("teleport-to-spawn-on-every-join", false, "Whether the player should be teleported to the spawnpoint every time they join."); + addDefault("teleport-to-nearest-spawnpoint", false, "Whether using /spawn, joining or respawning should send the user to the closest spawnpoint they have access to.\n" + + "If the user doesn't have permission to the specified spawnpoint, then they are not sent to it." + + "Only spawns in the same dimension/world are considered. If no spawnpoint is set in the same dimension, then the normal main spawn is used."); addComment("death-management", "Determines how and where players teleport when they die.\n" + "Options include:\n" + @@ -701,6 +705,7 @@ public void postSave() { TELEPORT_TO_SPAWN_FIRST = new ConfigOption<>("teleport-to-spawn-on-first-join"); FIRST_SPAWN_POINT = new ConfigOption<>("first-spawn-point"); TELEPORT_TO_SPAWN_EVERY = new ConfigOption<>("teleport-to-spawn-on-every-join"); + TELEPORT_TO_NEAREST_SPAWN = new ConfigOption<>("teleport-to-nearest-spawnpoint"); DEATH_MANAGEMENT = new ConfigOption<>("death-management"); diff --git a/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/config/Spawn.java b/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/config/Spawn.java index 8c5f13456..dccf4707d 100644 --- a/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/config/Spawn.java +++ b/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/config/Spawn.java @@ -5,12 +5,15 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import static org.bukkit.util.NumberConversions.square; + public class Spawn extends ATConfig { private static Spawn instance; @@ -98,11 +101,21 @@ public String mirrorSpawn(String from, String to) { } public Location getSpawn(String name) { - return getSpawn(name, null, false); + return getSpawn(name, null, false, true); } - public Location getSpawn(String name, Player player, boolean bypassPermission) { - // if (get("spawns." + name) == null) return getProperMainSpawn(); + public Location getSpawn( + @NotNull String name, + @Nullable Player player, + boolean bypassPermission, + boolean forced + ) { + + // If we're going to the nearest spawnpoint instead, look around + if (player != null && NewConfig.get().TELEPORT_TO_NEAREST_SPAWN.get() && !forced) { + return getNearestLocation(player); + } + ConfigSection spawns = getConfigSection("spawns"); ConfigSection toSection = spawns.getConfigSection(name); while (true) { @@ -149,6 +162,51 @@ public Location getSpawn(String name, Player player, boolean bypassPermission) { return mainSpawn; } + private Location getNearestLocation(@NotNull Player player) { + + final Location loc = player.getLocation(); + + // Set the initial values + @Nullable String chosenSpawn = null; + double max = 0; + + ConfigSection spawns = getConfigSection("spawns"); + for (String spawnName : getSpawns()) { + ConfigSection spawn = spawns.getConfigSection(spawnName); + + // Same world? + if (!player.getWorld().getName().equals(spawn.getString("world"))) continue; + + // Not a mirror? + boolean hasCoords = spawn.contains("x") + && spawn.contains("y") + && spawn.contains("z") + && spawn.contains("yaw") + && spawn.contains("pitch") + && spawn.contains("world"); + if (!hasCoords) continue; + + // Has permission? + boolean requiresPermission = spawn.getBoolean("requires-permission", true); + if (requiresPermission && !player.hasPermission("at.member.spawn." + spawnName.toLowerCase())) continue; + + // Check the distance + double x = spawn.getDouble("x"); + double y = spawn.getDouble("y"); + double z = spawn.getDouble("z"); + double distance = square(x - loc.getX()) + square(y - loc.getY()) + square(z - loc.getZ()); + if (chosenSpawn != null && distance >= max) continue; + + // If it works out, set it! + chosenSpawn = spawnName; + max = distance; + } + + // If no spawn was chosen, use the main spawn + if (chosenSpawn == null) return mainSpawn; + return getSpawn(chosenSpawn); + } + public String setMainSpawn(String id, Location location) { mainSpawn = location; set("main-spawn", id); diff --git a/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/listeners/SignInteractListener.java b/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/listeners/SignInteractListener.java index 73c06ee5b..2e999bc43 100644 --- a/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/listeners/SignInteractListener.java +++ b/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/listeners/SignInteractListener.java @@ -110,10 +110,12 @@ public boolean canCreate(Sign sign, Player player) { @Override public void onInteract(Sign sign, Player player) { String world = player.getWorld().getName(); + boolean specific = false; if (!sign.getLine(1).isEmpty()) { world = sign.getLine(1); + specific = true; } - SpawnCommand.spawn(player, world); + SpawnCommand.spawn(player, world, specific); } @Override diff --git a/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/managers/TeleportTrackingManager.java b/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/managers/TeleportTrackingManager.java index ee05aea66..5bbb3732a 100644 --- a/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/managers/TeleportTrackingManager.java +++ b/AdvancedTeleport-Bukkit/src/main/java/io/github/niestrat99/advancedteleport/managers/TeleportTrackingManager.java @@ -37,9 +37,9 @@ public void onJoin(PlayerJoinEvent e) { if (!player.hasPermission("at.admin.bypass.teleport-on-join")) { Location loc = null; if (!player.hasPlayedBefore() && NewConfig.get().TELEPORT_TO_SPAWN_FIRST.get()) { - loc = Spawn.get().getSpawn(NewConfig.get().FIRST_SPAWN_POINT.get(), player, true); + loc = Spawn.get().getSpawn(NewConfig.get().FIRST_SPAWN_POINT.get(), player, true, false); } else if (NewConfig.get().TELEPORT_TO_SPAWN_EVERY.get()) { - loc = Spawn.get().getSpawn(e.getPlayer().getWorld().getName(), player, false); + loc = Spawn.get().getSpawn(e.getPlayer().getWorld().getName(), player, false, false); if (loc == null) loc = player.getWorld().getSpawnLocation(); } if (loc == null) return; @@ -136,7 +136,7 @@ private static boolean handleSpawn(PlayerRespawnEvent e, String spawnCommand) { switch (spawnCommand) { case "spawn": - Location spawn = Spawn.get().getSpawn(e.getPlayer().getWorld().getName(), e.getPlayer(), false); + Location spawn = Spawn.get().getSpawn(e.getPlayer().getWorld().getName(), e.getPlayer(), false, false); if (spawn != null) { CoreClass.debug("Spawn found at " + spawn.getX() + ", " + spawn.getY() + ", " + spawn.getZ()); e.setRespawnLocation(spawn);