Multiverse-Core/src/com/onarandombox/MultiverseCore/MVTeleport.java

174 lines
5.7 KiB
Java

package com.onarandombox.MultiverseCore;
import java.util.ArrayList;
import java.util.logging.Logger;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import com.onarandombox.utils.BlockSafety;
public class MVTeleport {
MultiverseCore plugin;
BlockSafety bs = new BlockSafety();
private static final Logger log = Logger.getLogger("Minecraft");
public MVTeleport(MultiverseCore plugin) {
this.plugin = plugin;
}
/**
* TODO: Sort out JavaDoc
* @param l
* @param w
* @return
*/
public Location getCompressedLocation(Player p, World w) {
Location l = p.getLocation();
// Check if they are the same world, might as well skip any calculations.
if (l.getWorld().getName().equalsIgnoreCase(w.getName())) {
return l;
}
double x, y, z;
// Grab the Compression value for each world.
double srcComp = plugin.worlds.get(l.getWorld().getName()).compression;
double trgComp = plugin.worlds.get(w.getName()).compression;
// MultiverseCore.debugMsg(p.getName() + " -> " + p.getWorld().getName() + "(" + srcComp + ") -> " + w.getName() + "(" + trgComp + ")");
// If the Targets Compression is 0 then we teleport them to the Spawn of the World.
if (trgComp == 0.0) {
x = w.getSpawnLocation().getX();
y = w.getSpawnLocation().getY();
z = w.getSpawnLocation().getZ();
} else {
x = l.getX() / (srcComp != 0 ? srcComp : 1) * trgComp;
y = l.getY();
z = l.getZ() / (srcComp != 0 ? srcComp : 1) * trgComp;
}
return new Location(w, x, y, z);
}
/**
* This function gets a safe place to teleport to.
*
* @param world
* @param player
* @return
*/
public Location getSafeDestination(Location l) {
double x = l.getX();
double y = l.getY();
double z = l.getZ();
World w = l.getWorld();
// To make things easier we'll start with the Y Coordinate on top of a Solid Block.
// while (bs.blockIsAboveAir(w, x, y, z)) {
// y--;
// }
double i = 0, r = 0, aux = -1;
for (r = 0; r < 32; r++) {
for (i = x - r; i <= x + r; i++) {
if ((aux = safeColumn(w, i, y, z - r)) > -1) {
z = z - r;
break;
}
if ((aux = safeColumn(w, i, y, z + r)) > -1) {
z = z + r;
break;
}
}
if (aux > -1) {
x = i;
break;
}
for (i = z - r + 1; i <= z + r - 1; i++) {
if ((aux = safeColumn(w, x - r, y, i)) > -1) {
x = x - r;
break;
}
if ((aux = safeColumn(w, x + r, y, i)) > -1) {
x = x + r;
break;
}
}
if (aux > -1) {
z = i;
break;
}
}
if (aux == -1) {
log.warning("Uh oh, no safe location.");
return null;
}
log.info("Target location (safe): " + x + ", " + aux + ", " + z);
return new Location(w, x, aux, z);
}
/**
* Check the Column given to see if there is an available safe spot.
* @param world
* @param x
* @param y
* @param z
* @return
*/
private double safeColumn(World world, double x, double y, double z) {
for (double ny = 0; ny < 48; ny++) {
if ((y + ny < 120) && !bs.blockIsNotSafe(world, x, y + ny, z)) {
return y + ny;
}
if ((y - ny > 4) && !bs.blockIsNotSafe(world, x, y - ny, z)) {
return y - ny;
}
}
return -1;
}
/**
* Find a portal around the given location and return a new location.
* @param location
* @return
*/
public Location findPortal(Location location) {
World world = location.getWorld();
// Get list of columns in a circle around the block
ArrayList<Block> columns = new ArrayList<Block>();
for (int x = location.getBlockX() - 8; x <= location.getBlockX() + 8; ++x) {
for (int z = location.getBlockZ() - 8; z <= location.getBlockZ() + 8; ++z) {
int dx = location.getBlockX() - x, dz = location.getBlockZ() - z;
if (dx * dx + dz * dz <= 256) {
columns.add(world.getBlockAt(x, 0, z));
}
}
}
// For each column try to find a portal block
for (Block col : columns) {
for (int y = 0; y <= 127; y++) {
Block b = world.getBlockAt(col.getX(), y, col.getZ());
if (b.getType().equals(Material.PORTAL)) {
if (b.getWorld().getBlockAt(b.getX() + 1, b.getY(), b.getZ()).getType().equals(Material.PORTAL) || b.getWorld().getBlockAt(b.getX() - 1, b.getY(), b.getZ()).getType().equals(Material.PORTAL)) {
// portal is in X direction
return new Location(b.getWorld(), b.getX() + 0.5, b.getY(), b.getZ() + 1.5);
} else {
// portal is in Z direction
return new Location(b.getWorld(), b.getX() + 1.5, b.getY(), b.getZ() + 0.5);
}
}
}
}
return null;
}
}