mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2025-02-26 01:01:50 +01:00
Rewrote safe teleport.
Needs testing.
This commit is contained in:
parent
f3d7bf2af3
commit
aae4c6d0b2
@ -9,6 +9,7 @@ import us.tastybento.bskyblock.Constants;
|
|||||||
import us.tastybento.bskyblock.api.commands.CompositeCommand;
|
import us.tastybento.bskyblock.api.commands.CompositeCommand;
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
import us.tastybento.bskyblock.util.SafeSpotTeleport;
|
import us.tastybento.bskyblock.util.SafeSpotTeleport;
|
||||||
|
import us.tastybento.bskyblock.util.SafeTeleportBuilder;
|
||||||
|
|
||||||
public class AdminTeleportCommand extends CompositeCommand {
|
public class AdminTeleportCommand extends CompositeCommand {
|
||||||
|
|
||||||
@ -46,7 +47,10 @@ public class AdminTeleportCommand extends CompositeCommand {
|
|||||||
// Other wise, go to a safe spot
|
// Other wise, go to a safe spot
|
||||||
String failureMessage = user.getTranslation("commands.admin.tp.manual", "[location]", warpSpot.getBlockX() + " " + warpSpot.getBlockY() + " "
|
String failureMessage = user.getTranslation("commands.admin.tp.manual", "[location]", warpSpot.getBlockX() + " " + warpSpot.getBlockY() + " "
|
||||||
+ warpSpot.getBlockZ());
|
+ warpSpot.getBlockZ());
|
||||||
new SafeSpotTeleport(getPlugin(), user.getPlayer(), warpSpot, failureMessage);
|
new SafeTeleportBuilder(getPlugin()).entity(user.getPlayer())
|
||||||
|
.location(warpSpot)
|
||||||
|
.failureMessage(failureMessage)
|
||||||
|
.build();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
user.sendMessage("command.admin.tp.no-island");
|
user.sendMessage("command.admin.tp.no-island");
|
||||||
|
@ -27,7 +27,7 @@ import us.tastybento.bskyblock.database.BSBDatabase;
|
|||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
import us.tastybento.bskyblock.util.DeleteIslandChunks;
|
import us.tastybento.bskyblock.util.DeleteIslandChunks;
|
||||||
import us.tastybento.bskyblock.util.SafeSpotTeleport;
|
import us.tastybento.bskyblock.util.SafeTeleportBuilder;
|
||||||
import us.tastybento.bskyblock.util.Util;
|
import us.tastybento.bskyblock.util.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -625,7 +625,11 @@ public class IslandsManager {
|
|||||||
plugin.getLogger().info("Fixing home location using safe spot teleport");
|
plugin.getLogger().info("Fixing home location using safe spot teleport");
|
||||||
}
|
}
|
||||||
// Try to fix this teleport location and teleport the player if possible
|
// Try to fix this teleport location and teleport the player if possible
|
||||||
new SafeSpotTeleport(plugin, player, plugin.getPlayers().getHomeLocation(player.getUniqueId(), number), number);
|
new SafeTeleportBuilder(plugin).entity(player)
|
||||||
|
.location(plugin.getPlayers().getHomeLocation(player.getUniqueId(), number))
|
||||||
|
.setHome(true)
|
||||||
|
.homeNumber(number)
|
||||||
|
.build();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@ -633,7 +637,6 @@ public class IslandsManager {
|
|||||||
}
|
}
|
||||||
//home.getChunk().load();
|
//home.getChunk().load();
|
||||||
player.teleport(home);
|
player.teleport(home);
|
||||||
//player.sendBlockChange(home, Material.GLOWSTONE, (byte)0);
|
|
||||||
User user = User.getInstance(player);
|
User user = User.getInstance(player);
|
||||||
if (number == 1) {
|
if (number == 1) {
|
||||||
user.sendMessage("commands.island.go.teleport", "[label]", Constants.ISLANDCOMMAND);
|
user.sendMessage("commands.island.go.teleport", "[label]", Constants.ISLANDCOMMAND);
|
||||||
|
@ -11,9 +11,11 @@ import org.bukkit.World;
|
|||||||
import org.bukkit.World.Environment;
|
import org.bukkit.World.Environment;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
import us.tastybento.bskyblock.api.commands.User;
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,185 +25,234 @@ import us.tastybento.bskyblock.database.objects.Island;
|
|||||||
*/
|
*/
|
||||||
public class SafeSpotTeleport {
|
public class SafeSpotTeleport {
|
||||||
|
|
||||||
|
private enum State {
|
||||||
|
CENTER, SURROUNDING, LAST_CHECK, FAILURE, CENTER_WAIT, SURROUNDING_WAIT
|
||||||
|
}
|
||||||
|
private static final long SPEED = 10;
|
||||||
|
private State step = State.CENTER;
|
||||||
|
private BukkitTask task;
|
||||||
|
|
||||||
|
|
||||||
|
private BSkyBlock plugin;
|
||||||
|
private final Entity entity;
|
||||||
|
private final Location location;
|
||||||
|
private final int homeNumber;
|
||||||
|
private final boolean setHome;
|
||||||
|
private int lastX;
|
||||||
|
private int lastZ;
|
||||||
|
private int chunksToCheck = 10;
|
||||||
|
private int worldHeight = 255;
|
||||||
|
private World world;
|
||||||
|
private double safeDistance;
|
||||||
|
private Vector safeSpotInChunk;
|
||||||
|
private boolean safeSpotFound;
|
||||||
|
private Vector portalPart;
|
||||||
|
private ChunkSnapshot portalChunk;
|
||||||
|
private ChunkSnapshot safeChunk;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Teleport to a safe place and if it fails, show a failure message
|
* Teleports and entity to a safe spot on island
|
||||||
* @param plugin
|
* @param plugin2
|
||||||
* @param player
|
* @param entity2
|
||||||
* @param l
|
* @param island
|
||||||
* @param failureMessage
|
* @param failureMessage
|
||||||
|
* @param setHome2
|
||||||
|
* @param homeNumber2
|
||||||
*/
|
*/
|
||||||
public SafeSpotTeleport(final BSkyBlock plugin, final Entity player, final Location l, final String failureMessage) {
|
public SafeSpotTeleport(BSkyBlock plugin2, Entity entity2, Location location, String failureMessage, boolean setHome2,
|
||||||
new SafeSpotTeleport(plugin, player, l, 1, failureMessage, false);
|
int homeNumber2) {
|
||||||
}
|
this.plugin = plugin2;
|
||||||
|
this.entity = entity2;
|
||||||
|
this.setHome = setHome2;
|
||||||
|
this.homeNumber = homeNumber2;
|
||||||
|
this.location = location;
|
||||||
|
|
||||||
/**
|
// Put player into spectator mode
|
||||||
* Teleport to a safe place and set home
|
if (entity instanceof Player && ((Player)entity).getGameMode().equals(GameMode.SURVIVAL)) {
|
||||||
* @param plugin
|
((Player)entity).setGameMode(GameMode.SPECTATOR);
|
||||||
* @param player
|
}
|
||||||
* @param l
|
// Get world info
|
||||||
* @param number
|
world = location.getWorld();
|
||||||
*/
|
worldHeight = world.getEnvironment().equals(Environment.NETHER) ? world.getMaxHeight() - 20 : world.getMaxHeight() - 2;
|
||||||
public SafeSpotTeleport(final BSkyBlock plugin, final Entity player, final Location l, final int number) {
|
|
||||||
new SafeSpotTeleport(plugin, player, l, number, "", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// Get island mins and max
|
||||||
* Teleport to a safe spot on an island
|
Island island = plugin.getIslands().getIslandAt(location).orElse(null);
|
||||||
* @param plugin
|
if (island == null) {
|
||||||
* @param player
|
if (entity instanceof Player) {
|
||||||
* @param l
|
User.getInstance((Player)entity).sendMessage(failureMessage);
|
||||||
*/
|
}
|
||||||
public SafeSpotTeleport(final BSkyBlock plugin, final Entity player, final Location l) {
|
return;
|
||||||
new SafeSpotTeleport(plugin, player, l, 1, "", false);
|
}
|
||||||
}
|
// Set the minimums and maximums
|
||||||
/**
|
lastX = island.getMinProtectedX() / 16;
|
||||||
* Teleport to a safe spot on an island
|
lastZ = island.getMinProtectedZ() / 16;
|
||||||
*
|
int biggestX = (island.getMinProtectedX() + island.getProtectionRange() - 1) / 16;
|
||||||
* TODO: REFACTOR THIS!
|
int biggestZ = (island.getMinProtectedZ() + island.getProtectionRange() - 1) / 16;
|
||||||
|
|
||||||
* @param plugin
|
// Start a recurring task until done or cancelled
|
||||||
* @param entity
|
task = plugin.getServer().getScheduler().runTaskTimer(plugin, () -> {
|
||||||
* @param islandLoc
|
|
||||||
*/
|
|
||||||
public SafeSpotTeleport(final BSkyBlock plugin, final Entity entity, final Location islandLoc, final int homeNumber, final String failureMessage, final boolean setHome) {
|
|
||||||
//this.plugin = plugin;
|
|
||||||
//plugin.getLogger().info("DEBUG: running safe spot");
|
|
||||||
// Get island
|
|
||||||
Island island = plugin.getIslands().getIslandAt(islandLoc).orElse(null);
|
|
||||||
if (island != null) {
|
|
||||||
final World world = islandLoc.getWorld();
|
|
||||||
// Get the chunks
|
|
||||||
List<ChunkSnapshot> chunkSnapshot = new ArrayList<>();
|
List<ChunkSnapshot> chunkSnapshot = new ArrayList<>();
|
||||||
// Add the center chunk
|
switch (step) {
|
||||||
chunkSnapshot.add(island.getCenter().toVector().toLocation(world).getChunk().getChunkSnapshot());
|
case CENTER:
|
||||||
// Add immediately adjacent chunks
|
// Add the center chunk
|
||||||
for (int x = islandLoc.getChunk().getX()-1; x <= islandLoc.getChunk().getX()+1; x++) {
|
chunkSnapshot.add(location.toVector().toLocation(world).getChunk().getChunkSnapshot());
|
||||||
for (int z = islandLoc.getChunk().getZ()-1; z <= islandLoc.getChunk().getZ()+1; z++) {
|
// Add immediately adjacent chunks
|
||||||
if (x != islandLoc.getChunk().getX() || z != islandLoc.getChunk().getZ()) {
|
for (int x = location.getChunk().getX()-1; x <= location.getChunk().getX()+1; x++) {
|
||||||
chunkSnapshot.add(world.getChunkAt(x, z).getChunkSnapshot());
|
for (int z = location.getChunk().getZ()-1; z <= location.getChunk().getZ()+1; z++) {
|
||||||
|
if (x != location.getChunk().getX() || z != location.getChunk().getZ()) {
|
||||||
|
chunkSnapshot.add(world.getChunkAt(x, z).getChunkSnapshot());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Move to next step
|
||||||
|
step = State.CENTER_WAIT;
|
||||||
|
checkChunks(chunkSnapshot);
|
||||||
|
break;
|
||||||
|
case CENTER_WAIT:
|
||||||
|
// Do nothing while the center scan is done
|
||||||
|
break;
|
||||||
|
case SURROUNDING:
|
||||||
|
for (int x = lastX; x <= biggestX; x++) {
|
||||||
|
for (int z = lastZ; z <= biggestZ; z++) {
|
||||||
|
chunkSnapshot.add(world.getChunkAt(x, z).getChunkSnapshot());
|
||||||
|
if (chunkSnapshot.size() == chunksToCheck) {
|
||||||
|
lastX = x;
|
||||||
|
lastZ = z;
|
||||||
|
step = State.SURROUNDING_WAIT;
|
||||||
|
checkChunks(chunkSnapshot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Last few chunks, may be none
|
||||||
|
step = State.LAST_CHECK;
|
||||||
|
checkChunks(chunkSnapshot);
|
||||||
|
break;
|
||||||
|
case SURROUNDING_WAIT:
|
||||||
|
// Do nothing while the surrounding scan is done
|
||||||
|
break;
|
||||||
|
case LAST_CHECK:
|
||||||
|
// Do nothing while the last few chunks are scanned
|
||||||
|
break;
|
||||||
|
case FAILURE:
|
||||||
|
// We are done searching - failure
|
||||||
|
task.cancel();
|
||||||
|
if (entity instanceof Player) {
|
||||||
|
if (!failureMessage.isEmpty()) {
|
||||||
|
entity.sendMessage(failureMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Add the rest of the island protected area
|
}, 0L, SPEED);
|
||||||
for (int x = island.getMinProtectedX() /16; x <= (island.getMinProtectedX() + island.getProtectionRange() - 1)/16; x++) {
|
}
|
||||||
for (int z = island.getMinProtectedZ() /16; z <= (island.getMinProtectedZ() + island.getProtectionRange() - 1)/16; z++) {
|
|
||||||
// This includes the center spots again, so is not as efficient...
|
private boolean checkChunks(List<ChunkSnapshot> chunkSnapshot) {
|
||||||
chunkSnapshot.add(world.getChunkAt(x, z).getChunkSnapshot());
|
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||||
}
|
// Find a safe spot, defined as a solid block, with 2 air spaces above it
|
||||||
}
|
//long time = System.nanoTime();
|
||||||
//plugin.getLogger().info("DEBUG: size of chunk ss = " + chunkSnapshot.size());
|
int x = 0;
|
||||||
final List<ChunkSnapshot> finalChunk = chunkSnapshot;
|
int y = 0;
|
||||||
int maxHeight = world.getMaxHeight() - 2;
|
int z = 0;
|
||||||
if (world.getEnvironment().equals(Environment.NETHER)) {
|
double distance = 0D;
|
||||||
// We need to ignore the roof
|
|
||||||
maxHeight -= 20;
|
for (ChunkSnapshot chunk: chunkSnapshot) {
|
||||||
}
|
// Run through the chunk
|
||||||
final int worldHeight = maxHeight;
|
for (x = 0; x< 16; x++) {
|
||||||
//plugin.getLogger().info("DEBUG:world height = " + worldHeight);
|
for (z = 0; z < 16; z++) {
|
||||||
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
|
// Work down from the entry point up
|
||||||
// Find a safe spot, defined as a solid block, with 2 air spaces above it
|
for (y = Math.min(chunk.getHighestBlockYAt(x, z), worldHeight); y >= 0; y--) {
|
||||||
//long time = System.nanoTime();
|
//System.out.println("Trying " + (16 * chunk.getX() + x) + " " + y + " " + (16 * chunk.getZ() + z));
|
||||||
int x = 0;
|
// Check for portal - only if this is not a safe home search
|
||||||
int y = 0;
|
if (!setHome && chunk.getBlockType(x, y, z).equals(Material.PORTAL)) {
|
||||||
int z = 0;
|
if (portalPart == null || (distance > location.toVector().distanceSquared(new Vector(x,y,z)))) {
|
||||||
ChunkSnapshot safeChunk = null;
|
// First one found or a closer one, save the chunk the position and the distance
|
||||||
ChunkSnapshot portalChunk = null;
|
portalChunk = chunk;
|
||||||
boolean safeSpotFound = false;
|
portalPart = new Vector(x,y,z);
|
||||||
Vector safeSpotInChunk = null;
|
distance = portalPart.distanceSquared(location.toVector());
|
||||||
Vector portalPart = null;
|
|
||||||
double distance = 0D;
|
|
||||||
double safeDistance = 0D;
|
|
||||||
for (ChunkSnapshot chunk: finalChunk) {
|
|
||||||
for (x = 0; x< 16; x++) {
|
|
||||||
for (z = 0; z < 16; z++) {
|
|
||||||
// Work down from the entry point up
|
|
||||||
for (y = Math.min(chunk.getHighestBlockYAt(x, z), worldHeight); y >= 0; y--) {
|
|
||||||
//System.out.println("Trying " + (16 * chunk.getX() + x) + " " + y + " " + (16 * chunk.getZ() + z));
|
|
||||||
// Check for portal - only if this is not a safe home search
|
|
||||||
if (!setHome && chunk.getBlockType(x, y, z).equals(Material.PORTAL)) {
|
|
||||||
if (portalPart == null || (distance > islandLoc.toVector().distanceSquared(new Vector(x,y,z)))) {
|
|
||||||
// First one found or a closer one, save the chunk the position and the distance
|
|
||||||
portalChunk = chunk;
|
|
||||||
portalPart = new Vector(x,y,z);
|
|
||||||
distance = portalPart.distanceSquared(islandLoc.toVector());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check for safe spot, but only if it is closer than one we have found already
|
|
||||||
if (!safeSpotFound || (safeDistance > islandLoc.toVector().distanceSquared(new Vector(x,y,z)))) {
|
|
||||||
// No safe spot yet, or closer distance
|
|
||||||
if (checkBlock(chunk,x,y,z, worldHeight)) {
|
|
||||||
safeChunk = chunk;
|
|
||||||
safeSpotFound = true;
|
|
||||||
safeSpotInChunk = new Vector(x,y,z);
|
|
||||||
safeDistance = islandLoc.toVector().distanceSquared(safeSpotInChunk);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} //end z
|
// Check for safe spot, but only if it is closer than one we have found already
|
||||||
} // end x
|
if (!safeSpotFound || (safeDistance > location.toVector().distanceSquared(new Vector(x,y,z)))) {
|
||||||
//if (safeSpotFound) {
|
// No safe spot yet, or closer distance
|
||||||
//System.out.print("DEBUG: safe spot found " + safeSpotInChunk.toString());
|
if (checkBlock(chunk,x,y,z, worldHeight)) {
|
||||||
//break search;
|
safeChunk = chunk;
|
||||||
//}
|
safeSpotFound = true;
|
||||||
}
|
safeSpotInChunk = new Vector(x,y,z);
|
||||||
// End search
|
safeDistance = location.toVector().distanceSquared(safeSpotInChunk);
|
||||||
// Check if the portal is safe (it should be)
|
}
|
||||||
if (portalPart != null) {
|
|
||||||
//System.out.print("DEBUG: Portal found");
|
|
||||||
// There is a portal available, but is it safe?
|
|
||||||
// Get the lowest portal spot
|
|
||||||
x = portalPart.getBlockX();
|
|
||||||
y = portalPart.getBlockY();
|
|
||||||
z = portalPart.getBlockZ();
|
|
||||||
while (portalChunk.getBlockType(x,y,z).equals(Material.PORTAL)) {
|
|
||||||
y--;
|
|
||||||
}
|
|
||||||
//System.out.print("DEBUG: Portal teleport loc = " + (16 * portalChunk.getX() + x) + "," + (y) + "," + (16 * portalChunk.getZ() + z));
|
|
||||||
// Now check if this is a safe location
|
|
||||||
if (checkBlock(portalChunk,x,y,z, worldHeight)) {
|
|
||||||
// Yes, so use this instead of the highest location
|
|
||||||
//System.out.print("DEBUG: Portal is safe");
|
|
||||||
safeSpotFound = true;
|
|
||||||
safeSpotInChunk = new Vector(x,y,z);
|
|
||||||
safeChunk = portalChunk;
|
|
||||||
// TODO: Add safe portal spot to island
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//System.out.print("Seconds = " + ((System.nanoTime() - time) * 0.000000001));
|
|
||||||
if (safeChunk != null && safeSpotFound) {
|
|
||||||
//final Vector spot = new Vector((16 *currentChunk.getX()) + x + 0.5D, y +1, (16 * currentChunk.getZ()) + z + 0.5D)
|
|
||||||
final Vector spot = new Vector((16 *safeChunk.getX()) + 0.5D, 1, (16 * safeChunk.getZ()) + 0.5D).add(safeSpotInChunk);
|
|
||||||
// Return to main thread and teleport the player
|
|
||||||
plugin.getServer().getScheduler().runTask(plugin, () -> {
|
|
||||||
Location destination = spot.toLocation(islandLoc.getWorld());
|
|
||||||
if (setHome && entity instanceof Player) {
|
|
||||||
plugin.getPlayers().setHomeLocation(entity.getUniqueId(), destination, homeNumber);
|
|
||||||
}
|
|
||||||
Vector velocity = entity.getVelocity();
|
|
||||||
entity.teleport(destination);
|
|
||||||
entity.setVelocity(velocity);
|
|
||||||
// Exit spectator mode if in it
|
|
||||||
if (entity instanceof Player) {
|
|
||||||
Player player = (Player)entity;
|
|
||||||
if (player.getGameMode().equals(GameMode.SPECTATOR)) {
|
|
||||||
player.setGameMode(GameMode.SURVIVAL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
} //end z
|
||||||
} else {
|
} // end x
|
||||||
// We did not find a spot
|
// If this is not a home search do a check for portal
|
||||||
plugin.getServer().getScheduler().runTask(plugin, () -> {
|
if (!this.setHome) {
|
||||||
//plugin.getLogger().info("DEBUG: safe spot not found");
|
checkPortal();
|
||||||
if (entity instanceof Player) {
|
|
||||||
if (!failureMessage.isEmpty()) {
|
|
||||||
entity.sendMessage(failureMessage);
|
|
||||||
} else {
|
|
||||||
entity.sendMessage("Warp not safe");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
// If successful, teleport otherwise move to the next step in the state machine
|
||||||
|
if (safeSpotFound) {
|
||||||
|
task.cancel();
|
||||||
|
teleportEntity();
|
||||||
|
} else if (step.equals(State.SURROUNDING_WAIT) || step.equals(State.CENTER_WAIT)) {
|
||||||
|
step = State.SURROUNDING;
|
||||||
|
} else if (step.equals(State.LAST_CHECK)) {
|
||||||
|
step = State.FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Teleports entity to the safe spot
|
||||||
|
*/
|
||||||
|
private void teleportEntity() {
|
||||||
|
final Vector spot = new Vector((16 *safeChunk.getX()) + 0.5D, 1, (16 * safeChunk.getZ()) + 0.5D).add(safeSpotInChunk);
|
||||||
|
// Return to main thread and teleport the player
|
||||||
|
plugin.getServer().getScheduler().runTask(plugin, () -> {
|
||||||
|
Location destination = spot.toLocation(world);
|
||||||
|
if (setHome && entity instanceof Player) {
|
||||||
|
plugin.getPlayers().setHomeLocation(entity.getUniqueId(), destination, homeNumber);
|
||||||
|
}
|
||||||
|
Vector velocity = entity.getVelocity();
|
||||||
|
entity.teleport(destination);
|
||||||
|
// Exit spectator mode if in it
|
||||||
|
if (entity instanceof Player) {
|
||||||
|
Player player = (Player)entity;
|
||||||
|
if (player.getGameMode().equals(GameMode.SPECTATOR)) {
|
||||||
|
player.setGameMode(GameMode.SURVIVAL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entity.setVelocity(velocity);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a portal is safe
|
||||||
|
*/
|
||||||
|
private void checkPortal() {
|
||||||
|
if (portalPart == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// There is a portal available, but is it safe?
|
||||||
|
// Get the lowest portal spot
|
||||||
|
int x = portalPart.getBlockX();
|
||||||
|
int y = portalPart.getBlockY();
|
||||||
|
int z = portalPart.getBlockZ();
|
||||||
|
while (portalChunk.getBlockType(x,y,z).equals(Material.PORTAL)) {
|
||||||
|
y--;
|
||||||
|
}
|
||||||
|
//System.out.print("DEBUG: Portal teleport loc = " + (16 * portalChunk.getX() + x) + "," + (y) + "," + (16 * portalChunk.getZ() + z));
|
||||||
|
// Now check if this is a safe location
|
||||||
|
if (checkBlock(portalChunk,x,y,z, worldHeight)) {
|
||||||
|
// Yes, so use this instead of the highest location
|
||||||
|
//System.out.print("DEBUG: Portal is safe");
|
||||||
|
safeSpotFound = true;
|
||||||
|
safeSpotInChunk = new Vector(x,y,z);
|
||||||
|
safeChunk = portalChunk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,4 +319,5 @@ public class SafeSpotTeleport {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
package us.tastybento.bskyblock.util;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
import us.tastybento.bskyblock.BSkyBlock;
|
||||||
|
import us.tastybento.bskyblock.database.objects.Island;
|
||||||
|
|
||||||
|
public class SafeTeleportBuilder {
|
||||||
|
|
||||||
|
private BSkyBlock plugin;
|
||||||
|
private Entity entity;
|
||||||
|
private int homeNumber = 0;
|
||||||
|
private boolean setHome = false;
|
||||||
|
private String failureMessage = "";
|
||||||
|
private Location location;
|
||||||
|
|
||||||
|
|
||||||
|
public SafeTeleportBuilder(BSkyBlock plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set who or what is going to teleport
|
||||||
|
* @param entity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SafeTeleportBuilder entity(Entity entity) {
|
||||||
|
this.entity = entity;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the island to teleport to
|
||||||
|
* @param island
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SafeTeleportBuilder island(Island island) {
|
||||||
|
this.location = island.getCenter();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the home number to this number
|
||||||
|
* @param homeNumber
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SafeTeleportBuilder homeNumber(int homeNumber) {
|
||||||
|
this.homeNumber = homeNumber;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the home of the player to the safe location
|
||||||
|
* @param setHome
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SafeTeleportBuilder setHome(boolean setHome) {
|
||||||
|
this.setHome = setHome;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the failure message if this teleport cannot happen
|
||||||
|
* @param failureMessage
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SafeTeleportBuilder failureMessage(String failureMessage) {
|
||||||
|
this.failureMessage = failureMessage;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the desired location
|
||||||
|
* @param location
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SafeTeleportBuilder location(Location location) {
|
||||||
|
this.location = location;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to teleport the player
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SafeSpotTeleport build() {
|
||||||
|
return new SafeSpotTeleport(plugin, entity, location, failureMessage, setHome, homeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user