mirror of
https://github.com/Multiverse/Multiverse-Core.git
synced 2025-01-26 02:01:34 +01:00
Refactored the Teleportation Method. Finally Closes #1 :D
This commit is contained in:
parent
ecbdff428c
commit
6e88301351
@ -1,9 +1,6 @@
|
||||
package com.onarandombox.MultiverseCore;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
import com.onarandombox.utils.BlockSafety;
|
||||
@ -13,7 +10,6 @@ public class MVTeleport {
|
||||
MultiverseCore plugin;
|
||||
|
||||
BlockSafety bs = new BlockSafety();
|
||||
private static final Logger log = Logger.getLogger("Minecraft");
|
||||
|
||||
public MVTeleport(MultiverseCore plugin) {
|
||||
this.plugin = plugin;
|
||||
@ -21,29 +17,158 @@ public class MVTeleport {
|
||||
|
||||
/**
|
||||
* This method will be specific to beds, and check on top of the bed then around it.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Location getSafeBedDestination(Location bedLocation) {
|
||||
//System.out.print(bedLocation);
|
||||
// System.out.print(bedLocation);
|
||||
Location idealLocation = bedLocation;
|
||||
idealLocation.setY(idealLocation.getY() + 1);
|
||||
idealLocation.setX(idealLocation.getX() + .5);
|
||||
idealLocation.setZ(idealLocation.getZ() + .5);
|
||||
//System.out.print(idealLocation);
|
||||
// System.out.print(idealLocation);
|
||||
if (this.bs.playerCanSpawnHereSafely(idealLocation)) {
|
||||
//System.out.print(idealLocation);
|
||||
// System.out.print(idealLocation);
|
||||
return bedLocation;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private Location getSafeLocation(Location l) {
|
||||
|
||||
// Check around the player first in a configurable radius:
|
||||
// TODO: Make this configurable
|
||||
Location safe = checkAboveAndBelowLocation(l, 6, 9);
|
||||
if (safe != null) {
|
||||
safe.setX(safe.getBlockX() + .5);
|
||||
safe.setZ(safe.getBlockZ() + .5);
|
||||
}
|
||||
return safe;
|
||||
}
|
||||
|
||||
private Location checkAboveAndBelowLocation(Location l, int tolerance, int radius) {
|
||||
// Tolerance must be an even number:
|
||||
if (tolerance % 2 != 0) {
|
||||
tolerance += 1;
|
||||
}
|
||||
// We want half of it, so we can go up and down
|
||||
tolerance /= 2;
|
||||
|
||||
// For now this will just do a straight up block.
|
||||
Location locToCheck = l.clone();
|
||||
// Check the main level
|
||||
Location safe = this.checkAroundLocation(locToCheck, radius);
|
||||
if (safe != null) {
|
||||
return safe;
|
||||
}
|
||||
// We've already checked zero right above this.
|
||||
int currentLevel = 1;
|
||||
while (currentLevel <= tolerance) {
|
||||
// Check above
|
||||
locToCheck = l.clone();
|
||||
locToCheck.add(0, currentLevel, 0);
|
||||
safe = this.checkAroundLocation(locToCheck, radius);
|
||||
if (safe != null) {
|
||||
return safe;
|
||||
}
|
||||
// Check below
|
||||
locToCheck = l.clone();
|
||||
locToCheck.subtract(0, currentLevel, 0);
|
||||
safe = this.checkAroundLocation(locToCheck, radius);
|
||||
if (safe != null) {
|
||||
return safe;
|
||||
}
|
||||
currentLevel++;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For my crappy algorithm, radius MUST be odd
|
||||
*
|
||||
* @param l
|
||||
* @param radius
|
||||
* @return
|
||||
*/
|
||||
private Location checkAroundLocation(Location l, int diameter) {
|
||||
if (diameter % 2 == 0) {
|
||||
diameter += 1;
|
||||
}
|
||||
Location checkLoc = l.clone();
|
||||
|
||||
// Start at 3, the min diameter around a block
|
||||
int loopcounter = 3;
|
||||
while (loopcounter <= diameter) {
|
||||
boolean foundSafeArea = checkAroundSpecificDiameter(checkLoc, loopcounter);
|
||||
// If a safe area was found:
|
||||
if (foundSafeArea) {
|
||||
// Return the checkLoc, it is the safe location.
|
||||
return checkLoc;
|
||||
}
|
||||
// Otherwise, let's reset our location
|
||||
checkLoc = l.clone();
|
||||
// And increment the radius
|
||||
loopcounter += 2;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean checkAroundSpecificDiameter(Location checkLoc, int circle) {
|
||||
// Adjust the circle to get how many blocks to step out.
|
||||
// A radius of 3 makes the block step 1
|
||||
// A radius of 5 makes the block step 2
|
||||
// A radius of 7 makes the block step 3
|
||||
// ...
|
||||
int adjustedCircle = ((circle - 1) / 2);
|
||||
checkLoc.add(adjustedCircle, 0, 0);
|
||||
if (this.bs.playerCanSpawnHereSafely(checkLoc)) {
|
||||
return true;
|
||||
}
|
||||
// Now we go to the right that adjustedCircle many
|
||||
for (int i = 0; i < adjustedCircle; i++) {
|
||||
checkLoc.add(0, 0, 1);
|
||||
if (this.bs.playerCanSpawnHereSafely(checkLoc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Then down adjustedCircle *2
|
||||
for (int i = 0; i < adjustedCircle * 2; i++) {
|
||||
checkLoc.add(-1, 0, 0);
|
||||
if (this.bs.playerCanSpawnHereSafely(checkLoc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Then left adjustedCircle *2
|
||||
for (int i = 0; i < adjustedCircle * 2; i++) {
|
||||
checkLoc.add(0, 0, -1);
|
||||
if (this.bs.playerCanSpawnHereSafely(checkLoc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Then up Then left adjustedCircle *2
|
||||
for (int i = 0; i < adjustedCircle * 2; i++) {
|
||||
checkLoc.add(1, 0, 0);
|
||||
if (this.bs.playerCanSpawnHereSafely(checkLoc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Then finish up by doing adjustedCircle - 1
|
||||
for (int i = 0; i < adjustedCircle - 1; i++) {
|
||||
checkLoc.add(0, 0, 1);
|
||||
if (this.bs.playerCanSpawnHereSafely(checkLoc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean safelyTeleport(Entity e, Location l) {
|
||||
if(this.bs.playerCanSpawnHereSafely(l)) {
|
||||
if (this.bs.playerCanSpawnHereSafely(l)) {
|
||||
e.teleport(l);
|
||||
System.out.print("The first location you gave me was safe!");
|
||||
return true;
|
||||
@ -55,86 +180,4 @@ public class MVTeleport {
|
||||
System.out.print("Sorry champ, you're basically trying to teleport into a minefield. I should just kill you now.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function gets a safe place to teleport to.
|
||||
*
|
||||
* @param world
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
private 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) && !this.bs.blockIsNotSafe(world, x, y + ny, z)) {
|
||||
return y + ny;
|
||||
}
|
||||
if ((y - ny > 4) && !this.bs.blockIsNotSafe(world, x, y - ny, z)) {
|
||||
return y - ny;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -41,41 +41,95 @@ public class BlockSafety {
|
||||
upOne.setY(upOne.getY() + 1);
|
||||
downOne.setY(downOne.getY() - 1);
|
||||
|
||||
if (/*actual.getBlock().getType() != Material.AIR || */upOne.getBlock().getType() != Material.AIR) {
|
||||
System.out.print("Air!");
|
||||
if (this.isNotSolidBlock(actual.getBlock().getType()) || this.isNotSolidBlock(upOne.getBlock().getType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (downOne.getBlock().getType() == Material.LAVA) {
|
||||
System.out.print("Lava!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (downOne.getBlock().getType() == Material.STATIONARY_LAVA) {
|
||||
System.out.print("Lava!!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (downOne.getBlock().getType() == Material.FIRE) {
|
||||
System.out.print("Fire Below!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (actual.getBlock().getType() == Material.FIRE) {
|
||||
System.out.print("Fire!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blockIsAboveAir(actual)) {
|
||||
System.out.print("Above Air!");
|
||||
// FOR NOW THIS IS OK
|
||||
// TODO: Take out once the other one is fixed.
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If someone has a better way of this... Please either tell us, or submit a pull request!
|
||||
*
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
private boolean isNotSolidBlock(Material type) {
|
||||
switch (type) {
|
||||
case AIR:
|
||||
return true;
|
||||
case TRAP_DOOR:
|
||||
return true;
|
||||
case TORCH:
|
||||
return true;
|
||||
case YELLOW_FLOWER:
|
||||
return true;
|
||||
case RED_ROSE:
|
||||
return true;
|
||||
case RED_MUSHROOM:
|
||||
return true;
|
||||
case BROWN_MUSHROOM:
|
||||
return true;
|
||||
case REDSTONE:
|
||||
return true;
|
||||
case REDSTONE_WIRE:
|
||||
return true;
|
||||
case RAILS:
|
||||
return true;
|
||||
case POWERED_RAIL:
|
||||
return true;
|
||||
case REDSTONE_TORCH_ON:
|
||||
return true;
|
||||
case REDSTONE_TORCH_OFF:
|
||||
return true;
|
||||
case DEAD_BUSH:
|
||||
return true;
|
||||
case SAPLING:
|
||||
return true;
|
||||
case STONE_BUTTON:
|
||||
return true;
|
||||
case LEVER:
|
||||
return true;
|
||||
case LONG_GRASS:
|
||||
return true;
|
||||
case PORTAL:
|
||||
return true;
|
||||
case STONE_PLATE:
|
||||
return true;
|
||||
case WOOD_PLATE:
|
||||
return true;
|
||||
case SEEDS:
|
||||
return true;
|
||||
case SUGAR_CANE_BLOCK:
|
||||
return true;
|
||||
case WALL_SIGN:
|
||||
return true;
|
||||
case SIGN_POST:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void showDangers(Location l) {
|
||||
Location actual = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
|
||||
Location upOne = new Location(l.getWorld(), l.getX(), l.getY(), l.getZ());
|
||||
|
Loading…
Reference in New Issue
Block a user