Fixes end portal finding issue when entering from side

There was a bug in the code that prevented to finding of a portal location if the player entered from the side. 
It can happen only if the portal frame is removed, but as in vanilla it is possible, then it needs to be addressed.

The fix itself is simple: instead of checking just up from the starting location, the code will check all blocks in 10x10x10 square from the starting location and find the "closest" portal location.

This will fix #2237
This commit is contained in:
BONNe 2023-11-28 18:55:42 +02:00 committed by GitHub
parent 187ae1c61a
commit ab1fd60d39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -274,9 +274,38 @@ public abstract class AbstractTeleportListener
// If the from is not a portal, then we have to find it // If the from is not a portal, then we have to find it
if (!fromLocation.getBlock().getType().equals(Material.END_PORTAL)) if (!fromLocation.getBlock().getType().equals(Material.END_PORTAL))
{ {
// Find the portal - due to speed, it is possible that the player will be below or above the portal // Search portal block 5 blocks in all directions from starting location. Return the first one.
for (k = toWorld.getMinHeight(); (k < fromWorld.getMaxHeight()) && boolean continueSearch = true;
!fromWorld.getBlockAt(x, k, z).getType().equals(Material.END_PORTAL); k++);
// simplistic search pattern to look at all blocks from the middle outwards by preferring
// Y location first, then Z and as last X
// Proper implementation would require queue and distance calculation.
for (int offsetX = 0; continueSearch && offsetX < 10; offsetX++)
{
// Change sign based on mod value.
int posX = x + ((offsetX % 2 == 0) ? 1 : -1) * (offsetX / 2);
for (int offsetZ = 0; continueSearch && offsetZ < 10; offsetZ++)
{
// Change sign based on mod value.
int posZ = z + ((offsetZ % 2 == 0) ? 1 : -1) * (offsetZ / 2);
for (int offsetY = 0; continueSearch && offsetY < 10; offsetY++)
{
// Change sign based on mod value.
int posY = y + ((offsetY % 2 == 0) ? 1 : -1) * (offsetY / 2);
if (fromWorld.getBlockAt(posX, posY, posZ).getType().equals(Material.END_PORTAL))
{
i = posX;
j = posZ;
k = posY;
continueSearch = false;
}
}
}
}
} }
// Find the maximum x and z corner // Find the maximum x and z corner
@ -289,7 +318,7 @@ public abstract class AbstractTeleportListener
// OBSIDIAN // OBSIDIAN
// and player is placed on second air block above obsidian. // and player is placed on second air block above obsidian.
// If Y coordinate is below 2, then obsidian platform is not generated and player falls in void. // If Y coordinate is below 2, then obsidian platform is not generated and player falls in void.
return new Location(toWorld, i, Math.max(toWorld.getMinHeight() + 2, k), j); return new Location(toWorld, i, Math.min(toWorld.getMaxHeight() - 2, Math.max(toWorld.getMinHeight() + 2, k)), j);
} }