Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions src/main/java/com/wimbli/WorldBorder/BorderData.java
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,13 @@ public Location correctedPosition(Location loc)
// 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, boolean flying)
{
boolean safe = safeOpenBlocks.contains(world.getBlockAt(X, Y, Z).getType()) // target block open and safe
&& safeOpenBlocks.contains(world.getBlockAt(X, Y + 1, Z).getType()); // above target block open and safe
boolean safe =
// target block open and safe or is above maximum Y coordinate
(Y == world.getMaxHeight()
|| (safeOpenBlocks.contains(world.getBlockAt(X, Y, Z).getType())
// above target block open and safe or is above maximum Y coordinate
&& (Y + 1 == world.getMaxHeight()
|| safeOpenBlocks.contains(world.getBlockAt(X, Y + 1, Z).getType()))));
if (!safe || flying)
return safe;

Expand All @@ -423,9 +428,10 @@ private boolean isSafeSpot(World world, int X, int Y, int Z, boolean flying)
// find closest safe Y position from the starting position
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
// 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; we don't bother checking if Y = 126 or 127 are safe because they never will be unless there's a hole in the bedrock
final boolean isNether = world.getEnvironment() == World.Environment.NETHER;
int limTop = isNether ? 125 : world.getMaxHeight() - 2;
int limTop = isNether ? 125 : world.getMaxHeight();
// add 1 because getHighestBlockYAt() will give us the Y coordinate of a solid block, and we want the air block above it
final int highestBlockBoundary = Math.min(world.getHighestBlockYAt(X, Z) + 1, limTop);

// if Y is larger than the world can be and user can fly, return Y - Unless we are in the Nether, we might not want players on the roof
Expand All @@ -448,12 +454,13 @@ private double getSafeY(World world, int X, int Y, int Z, boolean flying)
if (Y < limBot)
Y = limBot;

// for non Nether worlds we don't need to check upwards to the world-limit, it is enough to check up to the highestBlockBoundary, unless player is flying
// for non Nether worlds we don't need to check upwards to the world-limit, it is enough to check up to and including the highestBlockBoundary, unless player is flying
if (!isNether && !flying)
limTop = highestBlockBoundary;
// Expanding Y search method adapted from Acru's code in the Nether plugin

for(int y1 = Y, y2 = Y; (y1 > limBot) || (y2 < limTop); y1--, y2++){
// Note that we want to include limTop in the search - in the extreme case, world.getMaxHeight() should be included since the player can stand on top of the highest block
for(int y1 = Y, y2 = Y; (y1 > limBot) || (y2 <= limTop); y1--, y2++){
// Look below.
if(y1 > limBot)
{
Expand All @@ -462,7 +469,7 @@ private double getSafeY(World world, int X, int Y, int Z, boolean flying)
}

// Look above.
if(y2 < limTop && y2 != y1)
if(y2 <= limTop && y2 != y1)
{
if (isSafeSpot(world, X, y2, Z, flying))
return (double)y2;
Expand Down