Skip to content

Commit

Permalink
feat: add teleportation to the nearest spawnpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Thatsmusic99 committed Jun 3, 2023
1 parent 04c799e commit 4ab5a83
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 10 deletions.
Expand Up @@ -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();
}
Expand Down
Expand Up @@ -98,6 +98,7 @@ public class NewConfig extends ATConfig {
public ConfigOption<Boolean> TELEPORT_TO_SPAWN_FIRST;
public ConfigOption<String> FIRST_SPAWN_POINT;
public ConfigOption<Boolean> TELEPORT_TO_SPAWN_EVERY;
public ConfigOption<Boolean> TELEPORT_TO_NEAREST_SPAWN;

public ConfigOption<ConfigSection> DEATH_MANAGEMENT;

Expand Down Expand Up @@ -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" +
Expand Down Expand Up @@ -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");

Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
Expand Down
Expand Up @@ -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
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 4ab5a83

Please sign in to comment.