Correctly teleport to highest block instead of spawn (fixes #178)
The fix for issue #57 added some limits to the values searched when looking for a safe Y coordinate for the teleport destination, including calling getHighestBlockYAt() to determine the Y coordinate of the highest non-empty block. In non-nether cases with normal terrain that doesn't approach the world's maximum Y values, highestBlockBoundary will be set to 1 greater than the return value of getHighestBlockYAt(), i.e. the Y coordinate of the empty block above the highest non-empty block. In the non-nether, non-flying case, limTop was previously set to this value, and the safe Y coordinate search would proceed up to *but not including* this limit, so the maximum Y coordinate searched to check if it was empty would be the highest *non*-empty y coordinate. However, the player's current Y coordinate is checked first even if it is equal to limTop (unless it is somehow not greater than limBot). As a result, if the only safe block for the player to be teleported on top of was getHighestBlockYAt(), they would only be teleported there if it wouldn't result in a change in their Y coordinate, otherwise they would be teleported to spawn. This fix expands the search to include highestBlockBoundary. highestBlockBoundary cannot be greater than world.getMaxHeight() - 2, so the search for a Y coordinate will now include that value rather than excluding it. isSafeSpot() only adds 1 to that value, giving world.getMaxHeight() - 1, which is still within the valid Y coordinate range. This might also fix issue #115.
This commit is contained in:
parent
f88ede397c
commit
a1488146e1
|
@ -426,6 +426,7 @@ public class BorderData
|
|||
// 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 boolean isNether = world.getEnvironment() == World.Environment.NETHER;
|
||||
int limTop = isNether ? 125 : world.getMaxHeight() - 2;
|
||||
// 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
|
||||
|
@ -448,9 +449,9 @@ public class BorderData
|
|||
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 (hence the addition of 1) the highestBlockBoundary, unless player is flying
|
||||
if (!isNether && !flying)
|
||||
limTop = highestBlockBoundary;
|
||||
limTop = highestBlockBoundary + 1;
|
||||
// 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++){
|
||||
|
|
Loading…
Reference in New Issue