diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/BetterRTP.java b/src/main/java/me/SuperRonanCraft/BetterRTP/BetterRTP.java index 7d2fee3..def3548 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/BetterRTP.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/BetterRTP.java @@ -38,7 +38,7 @@ public class BetterRTP extends JavaPlugin { @Getter private final PlayerDataManager playerDataManager = new PlayerDataManager(); private final Settings settings = new Settings(); @Getter private final CooldownHandler cooldowns = new CooldownHandler(); - private final QueueHandler queue = new QueueHandler(); + @Getter private final QueueHandler queue = new QueueHandler(); @Getter private final DatabaseHandler databaseHandler = new DatabaseHandler(); @Getter private final WarningHandler warningHandler = new WarningHandler(); diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdEdit.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdEdit.java index c957ea7..b6d84d0 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdEdit.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdEdit.java @@ -48,7 +48,7 @@ public class CmdEdit implements RTPCommand, RTPCommandHelpable { //Edit a worlds return; case LOCATION: if (args.length >= 5) { - for (Map.Entry location : BetterRTP.getInstance().getRTP().worldLocations.entrySet()) { + for (Map.Entry location : BetterRTP.getInstance().getRTP().RTPworldLocations.entrySet()) { if (location.getKey().equals(args[2])) { for (RTP_CMD_EDIT_SUB sub_cmd : RTP_CMD_EDIT_SUB.values()) if (sub_cmd.name().equalsIgnoreCase(args[3])) { @@ -66,7 +66,7 @@ public class CmdEdit implements RTPCommand, RTPCommandHelpable { //Edit a worlds return; case PERMISSION_GROUP: if (BetterRTP.getInstance().getSettings().isPermissionGroupEnabled() && args.length >= 6) { - for (String group : BetterRTP.getInstance().getRTP().worldPermissionGroups.keySet()) { + for (String group : BetterRTP.getInstance().getRTP().permissionGroups.keySet()) { if (group.equals(args[2])) { for (World world : Bukkit.getWorlds()) { if (world.getName().equals(args[3])) { @@ -156,12 +156,12 @@ public class CmdEdit implements RTPCommand, RTPCommandHelpable { //Edit a worlds list.add(world.getName()); break; case PERMISSION_GROUP: - for (String group : BetterRTP.getInstance().getRTP().worldPermissionGroups.keySet()) + for (String group : BetterRTP.getInstance().getRTP().permissionGroups.keySet()) if (group.toLowerCase().startsWith(args[2].toLowerCase())) list.add(group); break; case LOCATION: - for (String location : BetterRTP.getInstance().getRTP().worldLocations.keySet()) + for (String location : BetterRTP.getInstance().getRTP().RTPworldLocations.keySet()) if (location.toLowerCase().startsWith(args[2].toLowerCase())) list.add(location); break; diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdInfo.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdInfo.java index c104c99..d42a740 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdInfo.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdInfo.java @@ -128,7 +128,7 @@ public class CmdInfo implements RTPCommand, RTPCommandHelpable { info.add("&7- &6Overriden&7: " + _false); if (_rtpworld == null) _rtpworld = BetterRTP.getInstance().getRTP().getPlayerWorld(new RTPSetupInformation(w, player != null ? player : sendi, player, player != null)); - WorldDefault worldDefault = BetterRTP.getInstance().getRTP().defaultWorld; + WorldDefault worldDefault = BetterRTP.getInstance().getRTP().RTPdefaultWorld; info.add("&7- &eSetup Type&7: " + _rtpworld.setup_type.name() + getInfo(_rtpworld, worldDefault, "setup")); info.add("&7- &6Use World Border&7: " + (_rtpworld.getUseWorldborder() ? _true : _false)); info.add("&7- &eWorld Type&7: &f" + _rtpworld.getWorldtype().name()); diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdLocation.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdLocation.java index 13662e2..719116c 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdLocation.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/commands/types/CmdLocation.java @@ -1,7 +1,6 @@ package me.SuperRonanCraft.BetterRTP.player.commands.types; import me.SuperRonanCraft.BetterRTP.BetterRTP; -import me.SuperRonanCraft.BetterRTP.player.commands.Commands; import me.SuperRonanCraft.BetterRTP.player.commands.RTPCommand; import me.SuperRonanCraft.BetterRTP.player.commands.RTPCommandHelpable; import me.SuperRonanCraft.BetterRTP.player.rtp.RTP_TYPE; @@ -81,7 +80,7 @@ public class CmdLocation implements RTPCommand, RTPCommandHelpable { } private static HashMap getLocations() { - return BetterRTP.getInstance().getRTP().worldLocations; + return BetterRTP.getInstance().getRTP().RTPworldLocations; } //Get locations a player has access to diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTP.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTP.java index 96c53a0..5e13824 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTP.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTP.java @@ -2,8 +2,6 @@ package me.SuperRonanCraft.BetterRTP.player.rtp; import lombok.Getter; import me.SuperRonanCraft.BetterRTP.BetterRTP; -import me.SuperRonanCraft.BetterRTP.player.commands.types.CmdInfo; -import me.SuperRonanCraft.BetterRTP.player.commands.types.CmdWorld; import me.SuperRonanCraft.BetterRTP.references.PermissionNode; import me.SuperRonanCraft.BetterRTP.references.WarningHandler; import me.SuperRonanCraft.BetterRTP.references.customEvents.RTP_SettingUpEvent; @@ -12,7 +10,6 @@ import me.SuperRonanCraft.BetterRTP.references.helpers.HelperRTP; import me.SuperRonanCraft.BetterRTP.references.rtpinfo.PermissionGroup; import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.*; import org.bukkit.Bukkit; -import org.bukkit.World; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -25,15 +22,15 @@ public class RTP { //public final WorldPermissionGroup permConfig = new WorldPermissionGroup(); //Cache public final HashMap overriden = new HashMap<>(); - public final WorldDefault defaultWorld = new WorldDefault(); @Getter List disabledWorlds, blockList; int maxAttempts, delayTime; boolean cancelOnMove, cancelOnDamage; public final HashMap world_type = new HashMap<>(); //Worlds - public final HashMap customWorlds = new HashMap<>(); - public final HashMap worldLocations = new HashMap<>(); - public final HashMap worldPermissionGroups = new HashMap<>(); + public final WorldDefault RTPdefaultWorld = new WorldDefault(); + public final HashMap RTPcustomWorld = new HashMap<>(); + public final HashMap RTPworldLocations = new HashMap<>(); + public final HashMap permissionGroups = new HashMap<>(); public RTPTeleport getTeleport() { return teleport; @@ -52,25 +49,25 @@ public class RTP { //WorldType RTPLoader.loadWorldTypes(world_type); //Worlds & CustomWorlds - RTPLoader.loadWorlds(defaultWorld, customWorlds); + RTPLoader.loadWorlds(RTPdefaultWorld, RTPcustomWorld); //Locations - RTPLoader.loadLocations(worldLocations); + RTPLoader.loadLocations(RTPworldLocations); //Permissions - RTPLoader.loadPermissionGroups(worldPermissionGroups); + RTPLoader.loadPermissionGroups(permissionGroups); teleport.load(); //Load teleporting stuff //permConfig.load(); //Load permission configs } public void loadWorlds() { //Keeping this here because of the edit command - RTPLoader.loadWorlds(defaultWorld, customWorlds); + RTPLoader.loadWorlds(RTPdefaultWorld, RTPcustomWorld); } public void loadLocations() { //Keeping this here because of the edit command - RTPLoader.loadLocations(worldLocations); + RTPLoader.loadLocations(RTPworldLocations); } public void loadPermissionGroups() { //Keeping this here because of the edit command - RTPLoader.loadPermissionGroups(worldPermissionGroups); + RTPLoader.loadPermissionGroups(permissionGroups); } public WorldPlayer getPlayerWorld(RTPSetupInformation setup_info) { @@ -87,7 +84,7 @@ public class RTP { //Location if (setup_info.getLocation() != null) { String setup_name = null; - for (Map.Entry location_set : worldLocations.entrySet()) { + for (Map.Entry location_set : RTPworldLocations.entrySet()) { RTPWorld location = location_set.getValue(); if (location == setup_info.getLocation()) { setup_name = location_set.getKey(); @@ -100,7 +97,7 @@ public class RTP { if (!pWorld.isSetup()) { WorldPermissionGroup group = null; if (pWorld.getPlayer() != null) - for (Map.Entry permissionGroup : BetterRTP.getInstance().getRTP().worldPermissionGroups.entrySet()) { + for (Map.Entry permissionGroup : BetterRTP.getInstance().getRTP().permissionGroups.entrySet()) { for (Map.Entry worldPermission : permissionGroup.getValue().getWorlds().entrySet()) { if (pWorld.getWorld().equals(worldPermission.getValue().getWorld())) { if (PermissionNode.getPermissionGroup(pWorld.getPlayer(), permissionGroup.getKey())) { @@ -120,27 +117,31 @@ public class RTP { pWorld.config = group; } //Custom World - else if (customWorlds.containsKey(setup_info.getWorld().getName())) { - RTPWorld cWorld = customWorlds.get(pWorld.getWorld().getName()); + else if (RTPcustomWorld.containsKey(setup_info.getWorld().getName())) { + RTPWorld cWorld = RTPcustomWorld.get(pWorld.getWorld().getName()); pWorld.setup(null, cWorld, setup_info.getBiomes(), setup_info.isPersonalized()); } //Default World else - pWorld.setup(null, defaultWorld, setup_info.getBiomes(), setup_info.isPersonalized()); + pWorld.setup(null, RTPdefaultWorld, setup_info.getBiomes(), setup_info.isPersonalized()); } //World type + pWorld.setWorldtype(getWorldType(pWorld)); + return pWorld; + } + + public static WORLD_TYPE getWorldType(RTPWorld pWorld) { WORLD_TYPE world_type; - if (this.world_type.containsKey(setup_info.getWorld().getName())) - world_type = this.world_type.get(setup_info.getWorld().getName()); + RTP rtp = BetterRTP.getInstance().getRTP(); + if (rtp.world_type.containsKey(pWorld.getWorld().getName())) + world_type = rtp.world_type.get(pWorld.getWorld().getName()); else { world_type = WORLD_TYPE.NORMAL; - this.world_type.put(setup_info.getWorld().getName(), world_type); //Defaults this so the error message isn't spammed - getPl().getLogger().warning("Seems like the world `" + setup_info.getWorld() + "` does not have a `WorldType` declared. " + - "Please add/fix this in the config.yml file! " + - "This world will be treated as an overworld!"); + rtp.world_type.put(pWorld.getWorld().getName(), world_type); //Defaults this so the error message isn't spammed + WarningHandler.warn(WarningHandler.WARNING.NO_WORLD_TYPE_DECLARED, "Seems like the world `" + pWorld.getWorld() + "` does not have a `WorldType` declared. " + + "Please add/fix this in the config.yml file! This world will be treated as an overworld!"); } - pWorld.setWorldtype(world_type); - return pWorld; + return world_type; } public void start(RTPSetupInformation setup_info) { diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPPlayer.java b/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPPlayer.java index 3038c3b..dfa4900 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPPlayer.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/player/rtp/RTPPlayer.java @@ -1,13 +1,11 @@ package me.SuperRonanCraft.BetterRTP.player.rtp; import me.SuperRonanCraft.BetterRTP.references.customEvents.RTP_FindLocationEvent; +import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.WORLD_TYPE; import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.WorldPlayer; import io.papermc.lib.PaperLib; import me.SuperRonanCraft.BetterRTP.BetterRTP; -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.World; +import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -44,36 +42,39 @@ public class RTPPlayer { RTP_FindLocationEvent event = new RTP_FindLocationEvent(p, pWorld); //Find a queue'd location Bukkit.getServer().getPluginManager().callEvent(event); Location loc; - if (event.getLocation() != null && pWorld.checkIsValid(event.getLocation())) + if (event.getLocation() != null) // && WorldPlayer.checkIsValid(event.getLocation(), pWorld)) loc = event.getLocation(); else - loc = pWorld.generateLocation(); + loc = WorldPlayer.generateLocation(pWorld); attempts++; //Add an attempt //Load chunk and find out if safe location (asynchronously) CompletableFuture chunk = PaperLib.getChunkAtAsync(loc); chunk.thenAccept(result -> { //BetterRTP.debug("Checking location for " + p.getName()); Location tpLoc; - float yaw = p.getLocation().getYaw(); - float pitch = p.getLocation().getPitch(); - switch (pWorld.getWorldtype()) { //Get a Y position and check for bad blocks - case NETHER: - tpLoc = getLocAtNether(loc.getBlockX(), loc.getBlockZ(), pWorld.getWorld(), yaw, pitch, pWorld); break; - case NORMAL: - default: - tpLoc = getLocAtNormal(loc.getBlockX(), loc.getBlockZ(), pWorld.getWorld(), yaw, pitch, pWorld); - } + tpLoc = getSafeLocation(pWorld.getWorldtype(), pWorld.getWorld(), loc, pWorld.getMinY(), pWorld.getMaxY(), pWorld.getBiomes()); attemptedLocations.add(loc); //Valid location? if (tpLoc != null && checkDepends(tpLoc)) { - if (getPl().getEco().charge(p, pWorld)) + if (getPl().getEco().charge(p, pWorld)) { + tpLoc.setYaw(p.getLocation().getYaw()); + tpLoc.setPitch(p.getLocation().getPitch()); settings.teleport.sendPlayer(sendi, p, tpLoc, pWorld.getPrice(), attempts, type, pWorld.getWorldtype()); + } } else randomlyTeleport(sendi); }); } } + public static Location getSafeLocation(WORLD_TYPE type, World world, Location loc, int minY, int maxY, List biomes) { + switch (type) { //Get a Y position and check for bad blocks + case NETHER: return getLocAtNether(loc.getBlockX(), loc.getBlockZ(), minY, maxY, world, biomes); + case NORMAL: + default: return getLocAtNormal(loc.getBlockX(), loc.getBlockZ(), minY, maxY, world, biomes); + } + } + // Compressed code for MaxAttempts being met private void metMax(CommandSender sendi, Player p) { settings.teleport.failedTeleport(p, sendi); @@ -86,54 +87,54 @@ public class RTPPlayer { getPl().getpInfo().getRtping().put(p, false); } - private Location getLocAtNormal(int x, int z, World world, Float yaw, Float pitch, WorldPlayer pWorld) { + private static Location getLocAtNormal(int x, int z, int minY, int maxY, World world, List biomes) { Block b = world.getHighestBlockAt(x, z); if (b.getType().toString().endsWith("AIR")) //1.15.1 or less b = world.getBlockAt(x, b.getY() - 1, z); else if (!b.getType().isSolid()) { //Water, lava, shrubs... - if (!badBlock(b.getType().name(), x, z, pWorld.getWorld(), null)) { //Make sure it's not an invalid block (ex: water, lava...) + if (!badBlock(b.getType().name(), x, z, world, null)) { //Make sure it's not an invalid block (ex: water, lava...) //int y = world.getHighestBlockYAt(x, z); b = world.getBlockAt(x, b.getY() - 1, z); } } //Between max and min y - if ( b.getY() >= pWorld.getMinY() - && b.getY() <= pWorld.getMaxY() - && !badBlock(b.getType().name(), x, z, pWorld.getWorld(), pWorld.getBiomes())) { - return new Location(world, (x + 0.5), b.getY() + 1, (z + 0.5), yaw, pitch); + if ( b.getY() >= minY + && b.getY() <= maxY + && !badBlock(b.getType().name(), x, z, world, biomes)) { + return new Location(world, (x + 0.5), b.getY() + 1, (z + 0.5)); } return null; } - private Location getLocAtNether(int x, int z, World world, Float yaw, Float pitch, WorldPlayer pWorld) { + private static Location getLocAtNether(int x, int z, int minY, int maxY, World world, List biomes) { //Max and Min Y - for (int y = pWorld.getMinY() + 1; y < pWorld.getMaxY()/*world.getMaxHeight()*/; y++) { + for (int y = minY + 1; y < maxY/*world.getMaxHeight()*/; y++) { Block block_current = world.getBlockAt(x, y, z); if (block_current.getType().name().endsWith("AIR") || !block_current.getType().isSolid()) { if (!block_current.getType().name().endsWith("AIR") && !block_current.getType().isSolid()) { //Block is not a solid (ex: lava, water...) String block_in = block_current.getType().name(); - if (badBlock(block_in, x, z, pWorld.getWorld(), null)) + if (badBlock(block_in, x, z, world, null)) continue; } String block = world.getBlockAt(x, y - 1, z).getType().name(); if (block.endsWith("AIR")) //Block below is air, skip continue; if (world.getBlockAt(x, y + 1, z).getType().name().endsWith("AIR") //Head space - && !badBlock(block, x, z, pWorld.getWorld(), pWorld.getBiomes())) //Valid block - return new Location(world, (x + 0.5), y, (z + 0.5), yaw, pitch); + && !badBlock(block, x, z, world, biomes)) //Valid block + return new Location(world, (x + 0.5), y, (z + 0.5)); } } return null; } - private boolean checkDepends(Location loc) { - return settings.softDepends.checkLocation(loc); + public static boolean checkDepends(Location loc) { + return BetterRTP.getInstance().getRTP().softDepends.checkLocation(loc); } // Bad blocks, or bad biome - private boolean badBlock(String block, int x, int z, World world, List biomes) { - for (String currentBlock : settings.blockList) //Check Block + public static boolean badBlock(String block, int x, int z, World world, List biomes) { + for (String currentBlock : BetterRTP.getInstance().getRTP().blockList) //Check Block if (currentBlock.toUpperCase().equals(block)) return true; //Check Biomes diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/WarningHandler.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/WarningHandler.java index 9600c6b..cf0349c 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/WarningHandler.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/WarningHandler.java @@ -19,6 +19,7 @@ public class WarningHandler { } public enum WARNING { - USELOCATION_ENABLED_NO_LOCATION_AVAILABLE + USELOCATION_ENABLED_NO_LOCATION_AVAILABLE, + NO_WORLD_TYPE_DECLARED } } diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/customEvents/RTP_FindLocationEvent.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/customEvents/RTP_FindLocationEvent.java index 33a3272..984dc80 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/customEvents/RTP_FindLocationEvent.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/customEvents/RTP_FindLocationEvent.java @@ -3,13 +3,14 @@ package me.SuperRonanCraft.BetterRTP.references.customEvents; import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.RTPWorld; import org.bukkit.Location; import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; -//Called when an rtp has found a valid location +//Called when an rtp is finding a valid location public class RTP_FindLocationEvent extends RTPEvent { Player p; RTPWorld world; - Location loc = null; + Location loc; //Used to force a location into find event public RTP_FindLocationEvent(Player p, RTPWorld world) { this.p = p; @@ -17,11 +18,12 @@ public class RTP_FindLocationEvent extends RTPEvent { } //A location can be pushed in if a developer wants to inject a custom location - //Safe location code will still be run! + //Safe block code will still be run! public void setLocation(Location loc) { this.loc = loc; } + @Nullable public Location getLocation() { return loc; } diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/database/DatabaseQueue.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/database/DatabaseQueue.java index 9bbd6f2..0633db6 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/database/DatabaseQueue.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/database/DatabaseQueue.java @@ -1,7 +1,6 @@ package me.SuperRonanCraft.BetterRTP.references.database; import me.SuperRonanCraft.BetterRTP.BetterRTP; -import me.SuperRonanCraft.BetterRTP.references.player.playerdata.PlayerData; import me.SuperRonanCraft.BetterRTP.references.rtpinfo.QueueData; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -36,6 +35,7 @@ public class DatabaseQueue extends SQLite { Z("z", "long"), WORLD("world", "varchar(32)"), GENERATED("generated", "long"), + //IDENTIFIER("identifier", "varchar(32)"), //USES("uses", "integer"), ; @@ -63,6 +63,7 @@ public class DatabaseQueue extends SQLite { long y = rs.getLong(COLUMNS.Y.name); long z = rs.getLong(COLUMNS.Z.name); String worldName = rs.getString(COLUMNS.WORLD.name); + //String id = rs.getString(COLUMNS.IDENTIFIER.name); long generated = rs.getLong(COLUMNS.GENERATED.name); World world = Bukkit.getWorld(worldName); if (world != null) { diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/QueueData.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/QueueData.java index ff15e85..54f41c8 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/QueueData.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/QueueData.java @@ -1,16 +1,27 @@ package me.SuperRonanCraft.BetterRTP.references.rtpinfo; import lombok.Getter; +import lombok.Setter; +import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.RTPWorld; +import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.WorldPlayer; import org.bukkit.Location; public class QueueData { - @Getter Location location; - @Getter long generated; + //@Getter final String identifier; + @Getter @Setter Location location; + @Getter final long generated; - public QueueData(Location location, long generated) { + public QueueData(Location location, long generated/*, String identifier*/) { this.location = location; this.generated = generated; + //this.identifier = identifier; + } + + public QueueData(RTPWorld rtpWorld) { + this.location = WorldPlayer.generateLocation(rtpWorld); + this.generated = System.currentTimeMillis(); + //this.identifier = rtpWorld.getID(); } } diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/QueueHandler.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/QueueHandler.java index a894a1d..86d7e8e 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/QueueHandler.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/QueueHandler.java @@ -1,24 +1,32 @@ package me.SuperRonanCraft.BetterRTP.references.rtpinfo; import me.SuperRonanCraft.BetterRTP.BetterRTP; +import me.SuperRonanCraft.BetterRTP.player.rtp.RTP; +import me.SuperRonanCraft.BetterRTP.player.rtp.RTPPlayer; import me.SuperRonanCraft.BetterRTP.references.customEvents.RTP_FindLocationEvent; +import me.SuperRonanCraft.BetterRTP.references.customEvents.RTP_TeleportPostEvent; import me.SuperRonanCraft.BetterRTP.references.database.DatabaseHandler; import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.RTPWorld; +import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.WORLD_TYPE; +import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.WorldDefault; +import me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds.WorldPlayer; import org.bukkit.Bukkit; import org.bukkit.Location; -import org.bukkit.entity.Player; +import org.bukkit.World; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.plugin.PluginManager; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Random; -public class QueueHandler implements Listener { //Randomly queues up some randomly safe locations +public class QueueHandler implements Listener { //Randomly queues up some safe locations boolean loaded = false; List queueList = new ArrayList<>(); - private final int queueSize = 32; + private final int queueSize = 8; //Amount to ready up for each rtp world public void registerEvents(BetterRTP pl) { //DEBUG ONLY FOR THE TIME BEING @@ -50,21 +58,148 @@ public class QueueHandler implements Listener { //Randomly queues up some random }, 10L); } + //Inject queue to find event @EventHandler public void onRtpFindLoc(RTP_FindLocationEvent e) { - //RTPWorld world = e.getWorld(); - Location location = e.getLocation(); - List deleteList = new ArrayList<>(); - for (QueueData data : queueList) { - Location dataLoc = data.getLocation(); - if (location.getBlockX() == dataLoc.getBlockX() - && location.getBlockY() == dataLoc.getBlockY() - && location.getBlockZ() == dataLoc.getBlockZ() - && location.getWorld().getName().equals(dataLoc.getWorld().getName())) { + List queueData = getApplicable(e.getWorld()); + if (!queueData.isEmpty()) { + QueueData data = queueData.get(new Random().nextInt(queueData.size())); + e.setLocation(data.location); + } + queueGenerator(e.getWorld()); + } + + @EventHandler + public void onRTP(RTP_TeleportPostEvent e) { + //Delete previously used location + Bukkit.getScheduler().runTaskAsynchronously(BetterRTP.getInstance(), () -> { + Location location = e.getLocation(); + List deleteList = new ArrayList<>(); + for (QueueData data : queueList) { + Location dataLoc = data.getLocation(); + if (location.getBlockX() == dataLoc.getBlockX() + && location.getBlockY() == dataLoc.getBlockY() + && location.getBlockZ() == dataLoc.getBlockZ() + && location.getWorld().getName().equals(dataLoc.getWorld().getName())) { deleteList.add(data); + } + } + deleteList.forEach(data -> queueList.remove(data)); + }); + } + + + private void queueGenerator(RTPWorld rtpWorld) { + /*if (queueList.size() >= queueSize) { + //Plenty of locations, cancel out + return; + }*/ + + Bukkit.getScheduler().runTaskLaterAsynchronously(BetterRTP.getInstance(), () -> { + //Generate more locations + //Rare cases where a rtp world didnt have a location generated (Permission Groups?) + if (getApplicable(rtpWorld).size() < queueSize / 2) { + generateFromWorld(rtpWorld); + queueGenerator(rtpWorld); //Generate another later + return; + } + + //Generate Defaults + WorldDefault worldDefault = BetterRTP.getInstance().getRTP().RTPdefaultWorld; + for (World world : Bukkit.getWorlds()) { + if (!BetterRTP.getInstance().getRTP().getDisabledWorlds().contains(world.getName()) + && !BetterRTP.getInstance().getRTP().RTPcustomWorld.containsKey(world.getName())) { + if (getApplicable(worldDefault).size() < queueSize) { + generateFromWorld(worldDefault); + queueGenerator(null); //Generate another later + return; + } + } + } + + //Generate Custom Worlds + for (Map.Entry customWorld : BetterRTP.getInstance().getRTP().RTPcustomWorld.entrySet()) { + RTPWorld world = customWorld.getValue(); + if (getApplicable(world).size() < queueSize) { + generateFromWorld(world); + queueGenerator(null); //Generate another later + return; + } + } + + //Generate Locations + for (Map.Entry location : BetterRTP.getInstance().getRTP().RTPworldLocations.entrySet()) { + RTPWorld world = location.getValue(); + if (getApplicable(world).size() < queueSize) { + generateFromWorld(world); + queueGenerator(null); //Generate another later + return; + } + } + }, 20L * 5 /*delay before starting queue generator*/); + } + + //Generate a location on another thread + private void generateFromWorld(RTPWorld world) { + Bukkit.getScheduler().runTaskAsynchronously(BetterRTP.getInstance(), () -> addQueue(world, new QueueData(world))); + } + + private void addQueue(RTPWorld rtpWorld, QueueData data) { + Location loc = RTPPlayer.getSafeLocation( + RTP.getWorldType(rtpWorld), + data.getLocation().getWorld(), + data.getLocation(), + rtpWorld.getMinY(), + rtpWorld.getMaxY(), + rtpWorld.getBiomes()); + if (loc != null) { + data.setLocation(loc); + queueList.add(data); + } + } + + public static List getApplicable(RTPWorld rtpWorld) { + List queueData = BetterRTP.getInstance().getQueue().queueList; + List available = new ArrayList<>(); + for (QueueData data : queueData) { + switch (rtpWorld.getShape()) { + case CIRCLE: + if (isInCircle(data.location, rtpWorld)) + available.add(data); + break; + default: + if (isInSquare(data.location, rtpWorld)) + available.add(data); } } - deleteList.forEach(queueData -> queueList.remove(queueData)); + return available; + } + + private static boolean isInCircle(Location loc, RTPWorld rtpWorld) { + int center_x = rtpWorld.getCenterX(); + int center_z = rtpWorld.getCenterZ(); + int radius = rtpWorld.getMaxRadius(); + int radius_min = rtpWorld.getMinRadius(); + int x = loc.getBlockX(); + int z = loc.getBlockZ(); + int square_dist = (center_x - x) * 2 + (center_z - z) * 2; + return square_dist <= radius * 2 && square_dist >= radius_min * 2; + } + + private static boolean isInSquare(Location loc, RTPWorld rtpWorld) { + int center_x = rtpWorld.getCenterX(); + int center_z = rtpWorld.getCenterZ(); + int radius = rtpWorld.getMaxRadius(); + int radius_min = rtpWorld.getMinRadius(); + int x = loc.getBlockX(); + int z = loc.getBlockZ(); + boolean xright = x <= center_x + radius && x >= center_x + radius_min; + boolean xleft = x >= center_x - radius && x <= center_x - radius_min; + if (!(xleft || xright)) + return false; + boolean zbottom = z <= center_z + radius && z >= center_z + radius_min; + boolean ztop = z >= center_z - radius && z <=center_z - radius_min; + return ztop || zbottom; } } diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/RTPWorld.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/RTPWorld.java index 5982729..5b16f57 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/RTPWorld.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/RTPWorld.java @@ -4,6 +4,7 @@ import lombok.NonNull; import me.SuperRonanCraft.BetterRTP.BetterRTP; import me.SuperRonanCraft.BetterRTP.player.rtp.RTP_SHAPE; import org.bukkit.World; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -31,6 +32,11 @@ public interface RTPWorld { int getMaxY(); + @Nullable + default String getID() { + return null; + } + default long getCooldown() { return BetterRTP.getInstance().getCooldowns().getCooldownTime(); } diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/RTPWorld_Defaulted.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/RTPWorld_Defaulted.java index 802c0ba..879cd54 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/RTPWorld_Defaulted.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/RTPWorld_Defaulted.java @@ -31,7 +31,7 @@ public interface RTPWorld_Defaulted { void setMaxY(int value); default void setupDefaults() { - setAllFrom(BetterRTP.getInstance().getRTP().defaultWorld); + setAllFrom(BetterRTP.getInstance().getRTP().RTPdefaultWorld); } default void setAllFrom(RTPWorld rtpWorld) { diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldCustom.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldCustom.java index 84374cf..29c670e 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldCustom.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldCustom.java @@ -54,7 +54,7 @@ public class WorldCustom implements RTPWorld, RTPWorld_Defaulted { if (maxBorderRad <= 0) { BetterRTP.getInstance().getText().sms(Bukkit.getConsoleSender(), "WARNING! Custom world '" + world + "' Maximum radius of '" + maxBorderRad + "' is not allowed! Set to default value!"); - maxBorderRad = BetterRTP.getInstance().getRTP().defaultWorld.getMaxRadius(); + maxBorderRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMaxRadius(); } } if (test.get("MinRadius") != null) { @@ -63,9 +63,9 @@ public class WorldCustom implements RTPWorld, RTPWorld_Defaulted { if (minBorderRad < 0 || minBorderRad >= maxBorderRad) { BetterRTP.getInstance().getText().sms(Bukkit.getConsoleSender(), "WARNING! Custom world '" + world + "' Minimum radius of '" + minBorderRad + "' is not allowed! Set to default value!"); - minBorderRad = BetterRTP.getInstance().getRTP().defaultWorld.getMinRadius(); + minBorderRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMinRadius(); if (minBorderRad >= maxBorderRad) - maxBorderRad = BetterRTP.getInstance().getRTP().defaultWorld.getMaxRadius(); + maxBorderRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMaxRadius(); } } if (test.get("Biomes") != null) { @@ -108,13 +108,13 @@ public class WorldCustom implements RTPWorld, RTPWorld_Defaulted { if (maxBorderRad <= 0) { BetterRTP.getInstance().getText().sms(Bukkit.getConsoleSender(), "WARNING! Custom world '" + world + "' Maximum radius of '" + maxBorderRad + "' is not allowed! Set to default value!"); - maxBorderRad = BetterRTP.getInstance().getRTP().defaultWorld.getMaxRadius(); + maxBorderRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMaxRadius(); } //minBorderRad = config.getInt(pre + world + ".MinRadius"); if (minBorderRad <= 0 || minBorderRad >= maxBorderRad) { BetterRTP.getInstance().getText().sms(Bukkit.getConsoleSender(), "WARNING! Custom world '" + world + "' Minimum radius of '" + minBorderRad + "' is not allowed! Set to default value!"); - minBorderRad = BetterRTP.getInstance().getRTP().defaultWorld.getMinRadius(); + minBorderRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMinRadius(); } /*if (BetterRTP.getInstance().getFiles().getType(FileBasics.FILETYPE.ECO).getBoolean("Economy.Enabled")) if (BetterRTP.getInstance().getFiles().getType(FileBasics.FILETYPE.ECO).getBoolean("CustomWorlds.Enabled")) { diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldLocations.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldLocations.java index cc9b0e2..8a1e3a5 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldLocations.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldLocations.java @@ -6,6 +6,7 @@ import me.SuperRonanCraft.BetterRTP.references.file.FileBasics; import org.bukkit.Bukkit; import org.bukkit.World; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -17,6 +18,7 @@ public class WorldLocations implements RTPWorld, RTPWorld_Defaulted { private List biomes; private World world; private RTP_SHAPE shape; + private String name; public WorldLocations(String location_name) { FileBasics.FILETYPE config = BetterRTP.getInstance().getFiles().getType(FileBasics.FILETYPE.LOCATIONS); @@ -24,6 +26,7 @@ public class WorldLocations implements RTPWorld, RTPWorld_Defaulted { //WorldDefault worldDefault = BetterRTP.getInstance().getRTP().defaultWorld; setupDefaults(); + this.name = location_name; //Find Location and cache its values for (Map m : map) { @@ -61,7 +64,7 @@ public class WorldLocations implements RTPWorld, RTPWorld_Defaulted { if (maxRad <= 0) { BetterRTP.getInstance().getText().sms(Bukkit.getConsoleSender(), "WARNING! Location '" + location_name + "' Maximum radius of '" + maxRad + "' is not allowed! Set to default value!"); - maxRad = BetterRTP.getInstance().getRTP().defaultWorld.getMaxRadius(); + maxRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMaxRadius(); } } if (test.get("MinRadius") != null) { @@ -70,9 +73,9 @@ public class WorldLocations implements RTPWorld, RTPWorld_Defaulted { if (minRad < 0 || minRad >= maxRad) { BetterRTP.getInstance().getText().sms(Bukkit.getConsoleSender(), "WARNING! Location '" + location_name + "' Minimum radius of '" + minRad + "' is not allowed! Set to default value!"); - minRad = BetterRTP.getInstance().getRTP().defaultWorld.getMinRadius(); + minRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMinRadius(); if (minRad >= maxRad) - maxRad = BetterRTP.getInstance().getRTP().defaultWorld.getMaxRadius(); + maxRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMaxRadius(); } } if (test.get("Biomes") != null) { @@ -175,6 +178,12 @@ public class WorldLocations implements RTPWorld, RTPWorld_Defaulted { return maxy; } + @Nullable + @Override + public String getID() { + return name; + } + //Setters @Override diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldPermissionGroup.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldPermissionGroup.java index 4ebce9f..9b3ee9b 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldPermissionGroup.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldPermissionGroup.java @@ -7,8 +7,6 @@ import me.SuperRonanCraft.BetterRTP.references.file.FileBasics; import me.SuperRonanCraft.BetterRTP.BetterRTP; import org.bukkit.Bukkit; import org.bukkit.World; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.YamlConfiguration; import java.util.*; @@ -65,7 +63,7 @@ public class WorldPermissionGroup implements RTPWorld, RTPWorld_Defaulted { if (maxRad <= 0) { BetterRTP.getInstance().getText().sms(Bukkit.getConsoleSender(), "WARNING! Group '" + group + "' Maximum radius of '" + maxRad + "' is not allowed! Set to default value!"); - maxRad = BetterRTP.getInstance().getRTP().defaultWorld.getMaxRadius(); + maxRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMaxRadius(); } } if (field.equalsIgnoreCase("MinRadius")) { @@ -76,9 +74,9 @@ public class WorldPermissionGroup implements RTPWorld, RTPWorld_Defaulted { if (minRad < 0 || minRad >= maxRad) { BetterRTP.getInstance().getText().sms(Bukkit.getConsoleSender(), "WARNING! Group '" + group + "' Minimum radius of '" + minRad + "' is not allowed! Set to default value!"); - minRad = BetterRTP.getInstance().getRTP().defaultWorld.getMinRadius(); + minRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMinRadius(); if (minRad >= maxRad) - maxRad = BetterRTP.getInstance().getRTP().defaultWorld.getMaxRadius(); + maxRad = BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMaxRadius(); } } if (field.equalsIgnoreCase("Biomes")) { diff --git a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldPlayer.java b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldPlayer.java index 3f859c7..d16179c 100644 --- a/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldPlayer.java +++ b/src/main/java/me/SuperRonanCraft/BetterRTP/references/rtpinfo/worlds/WorldPlayer.java @@ -3,10 +3,7 @@ package me.SuperRonanCraft.BetterRTP.references.rtpinfo.worlds; import lombok.Getter; import me.SuperRonanCraft.BetterRTP.player.commands.RTP_SETUP_TYPE; import me.SuperRonanCraft.BetterRTP.BetterRTP; -import me.SuperRonanCraft.BetterRTP.player.rtp.RTP; import me.SuperRonanCraft.BetterRTP.player.rtp.RTP_SHAPE; -import me.SuperRonanCraft.BetterRTP.references.rtpinfo.PermissionGroup; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.WorldBorder; @@ -70,7 +67,7 @@ public class WorldPlayer implements RTPWorld, RTPWorld_Defaulted { } //Make sure our borders will not cause an invalid integer if (getMaxRadius() <= getMinRadius()) { - setMinRadius(BetterRTP.getInstance().getRTP().defaultWorld.getMinRadius()); + setMinRadius(BetterRTP.getInstance().getRTP().RTPdefaultWorld.getMinRadius()); if (getMaxRadius() <= getMinRadius()) setMinRadius(0); } @@ -81,38 +78,39 @@ public class WorldPlayer implements RTPWorld, RTPWorld_Defaulted { setup = true; } - public boolean checkIsValid(Location loc) { //Will check if a previously given location is valid - if (loc.getWorld() != getWorld()) + public static boolean checkIsValid(Location loc, RTPWorld rtpWorld) { //Will check if a previously given location is valid + if (loc.getWorld() != rtpWorld.getWorld()) return false; - int _xLMax = getCenterX() - getMaxRadius(); //I|-|| - int _xLMin = getCenterX() - getMinRadius(); //|I-|| - int _xRMax = getCenterX() + getMaxRadius(); //||-|I - int _xRMin = getCenterX() + getMinRadius(); //||-I| + int _xLMax = rtpWorld.getCenterX() - rtpWorld.getMaxRadius(); //I|-|| + int _xLMin = rtpWorld.getCenterX() - rtpWorld.getMinRadius(); //|I-|| + int _xRMax = rtpWorld.getCenterX() + rtpWorld.getMaxRadius(); //||-|I + int _xRMin = rtpWorld.getCenterX() + rtpWorld.getMinRadius(); //||-I| int _xLoc = loc.getBlockX(); if (_xLoc < _xLMax || (_xLoc > _xLMin && _xLoc < _xRMin) || _xLoc > _xRMax) return false; - int _zLMax = getCenterZ() - getMaxRadius(); //I|-|| - int _zLMin = getCenterZ() - getMinRadius(); //|I-|| - int _zRMax = getCenterZ() + getMaxRadius(); //||-|I - int _zRMin = getCenterZ() + getMinRadius(); //||-I| + int _zLMax = rtpWorld.getCenterZ() - rtpWorld.getMaxRadius(); //I|-|| + int _zLMin = rtpWorld.getCenterZ() - rtpWorld.getMinRadius(); //|I-|| + int _zRMax = rtpWorld.getCenterZ() + rtpWorld.getMaxRadius(); //||-|I + int _zRMin = rtpWorld.getCenterZ() + rtpWorld.getMinRadius(); //||-I| int _zLoc = loc.getBlockX(); return _zLoc >= _zLMax && (_zLoc <= _zLMin || _zLoc >= _zRMin) && _zLoc <= _zRMax; } - public Location generateLocation() { + public static Location generateLocation(RTPWorld rtpWorld) { Location loc; - switch (shape) { + switch (rtpWorld.getShape()) { case CIRCLE: - loc = generateRound(getMaxRadius(), getMinRadius()); break; + loc = generateRound(rtpWorld); break; default: - loc = generateSquare(getMaxRadius(), getMinRadius()); break; + loc = generateSquare(rtpWorld); break; } return loc; } - private Location generateSquare(int maxRad, int min) { + private static Location generateSquare(RTPWorld rtpWorld) { //Generate a random X and Z based off the quadrant selected - int max = maxRad - min; + int min = rtpWorld.getMinRadius(); + int max = rtpWorld.getMaxRadius() - min; int x, z; int quadrant = new Random().nextInt(4); switch (quadrant) { @@ -129,29 +127,30 @@ public class WorldPlayer implements RTPWorld, RTPWorld_Defaulted { x = new Random().nextInt(max) + min; z = -(new Random().nextInt(max) + min); break; } - x += getCenterX(); - z += getCenterZ(); + x += rtpWorld.getCenterX(); + z += rtpWorld.getCenterZ(); //System.out.println(quadrant); - return new Location(getWorld(), x, 0, z); + return new Location(rtpWorld.getWorld(), x, 0, z); } - private Location generateRound(int maxRad, int min) { + private static Location generateRound(RTPWorld rtpWorld) { //Generate a random X and Z based off location on a spiral curve - int max = maxRad - min; + int min = rtpWorld.getMinRadius(); + int max = rtpWorld.getMaxRadius() - min; int x, z; double area = Math.PI * (max - min) * (max + min); //of all the area in this donut double subArea = area * new Random().nextDouble(); //pick a random subset of that area - double r = Math.sqrt(subArea/Math.PI + min*min); //convert area to radius + double r = Math.sqrt(subArea/Math.PI + min * min); //convert area to radius double theta = (r - (int) r) * 2 * Math.PI; //use the remainder as an angle // polar to cartesian x = (int) (r * Math.cos(theta)); z = (int) (r * Math.sin(theta)); - x += getCenterX(); - z += getCenterZ(); - return new Location(getWorld(), x, 0, z); + x += rtpWorld.getCenterX(); + z += rtpWorld.getCenterZ(); + return new Location(rtpWorld.getWorld(), x, 0, z); } @NotNull