Players who are flying (from creative mode or otherwise) can now be moved back into air when they cross the border and are knocked back; no more requirement for a safe place to stand for them

also a minor change to the Fill command to make it potentially less taxing when run at high rates
This commit is contained in:
Brettflan 2013-03-29 17:57:52 -05:00
parent d2f0f407c2
commit 6b4a0be0b2
3 changed files with 22 additions and 14 deletions

View File

@ -101,7 +101,7 @@ public class BorderCheckTask implements Runnable
Config.LogWarn("Player position X: " + Config.coord.format(loc.getX()) + " Y: " + Config.coord.format(loc.getY()) + " Z: " + Config.coord.format(loc.getZ()));
}
Location newLoc = border.correctedPosition(loc, Config.ShapeRound());
Location newLoc = border.correctedPosition(loc, Config.ShapeRound(), player.isFlying());
// it's remotely possible (such as in the Nether) a suitable location isn't available, in which case...
if (newLoc == null)

View File

@ -179,7 +179,7 @@ public class BorderData
return insideBorder(loc.getX(), loc.getZ(), Config.ShapeRound());
}
public Location correctedPosition(Location loc, boolean round)
public Location correctedPosition(Location loc, boolean round, boolean flying)
{
// if this border has a shape override set, use it
if (shapeRound != null)
@ -226,15 +226,19 @@ public class BorderData
if (!tChunk.isLoaded())
tChunk.load();
yLoc = getSafeY(loc.getWorld(), ixLoc, Location.locToBlock(yLoc), izLoc);
yLoc = getSafeY(loc.getWorld(), ixLoc, Location.locToBlock(yLoc), izLoc, flying);
if (yLoc == -1)
return null;
return new Location(loc.getWorld(), Math.floor(xLoc) + 0.5, yLoc, Math.floor(zLoc) + 0.5, loc.getYaw(), loc.getPitch());
}
public Location correctedPosition(Location loc, boolean round)
{
return correctedPosition(loc, round, false);
}
public Location correctedPosition(Location loc)
{
return correctedPosition(loc, Config.ShapeRound());
return correctedPosition(loc, Config.ShapeRound(), false);
}
//these material IDs are acceptable for places to teleport player; breathable blocks and water
@ -248,20 +252,24 @@ public class BorderData
));
// check if a particular spot consists of 2 breathable blocks over something relatively solid
private boolean isSafeSpot(World world, int X, int Y, int Z)
private boolean isSafeSpot(World world, int X, int Y, int Z, boolean flying)
{
boolean safe = safeOpenBlocks.contains((Integer)world.getBlockTypeIdAt(X, Y, Z)) // target block open and safe
&& safeOpenBlocks.contains((Integer)world.getBlockTypeIdAt(X, Y + 1, Z)); // above target block open and safe
if (!safe || flying)
return safe;
Integer below = (Integer)world.getBlockTypeIdAt(X, Y - 1, Z);
return (safeOpenBlocks.contains((Integer)world.getBlockTypeIdAt(X, Y, Z)) // target block open and safe
&& safeOpenBlocks.contains((Integer)world.getBlockTypeIdAt(X, Y + 1, Z)) // above target block open and safe
&& (!safeOpenBlocks.contains(below) || below == 8 || below == 9) // below target block not open and safe (probably solid), or is water
&& !painfulBlocks.contains(below) // below target block not painful
return (safe
&& (!safeOpenBlocks.contains(below) || below == 8 || below == 9) // below target block not open and safe (probably solid), or is water
&& !painfulBlocks.contains(below) // below target block not painful
);
}
private static final int limBot = 1;
// find closest safe Y position from the starting position
private double getSafeY(World world, int X, int Y, int Z)
private double getSafeY(World world, int X, int Y, int Z, boolean flying)
{
// artificial height limit of 127 added for Nether worlds since CraftBukkit still incorrectly returns 255 for their max height, leading to players sent to the "roof" of the Nether
final int limTop = (world.getEnvironment() == World.Environment.NETHER) ? 125 : world.getMaxHeight() - 2;
@ -271,14 +279,14 @@ public class BorderData
// Look below.
if(y1 > limBot)
{
if (isSafeSpot(world, X, y1, Z))
if (isSafeSpot(world, X, y1, Z, flying))
return (double)y1;
}
// Look above.
if(y2 < limTop && y2 != y1)
{
if (isSafeSpot(world, X, y2, Z))
if (isSafeSpot(world, X, y2, Z, flying))
return (double)y2;
}
}

View File

@ -160,8 +160,8 @@ public class WorldFillTask implements Runnable
if (now > lastReport + 5000)
reportProgress();
// if this iteration has been running for 250ms (~5 ticks) or more, stop to take a breather
if (now > loopStartTime + 250)
// if this iteration has been running for 45ms (almost 1 tick) or more, stop to take a breather
if (now > loopStartTime + 45)
{
readyToGo = true;
return;