Last active
August 29, 2015 14:00
-
-
Save hansihe/737c83d68c3fb632759c to your computer and use it in GitHub Desktop.
Minecraft portal finding algorithm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private final LongHashMap<Long, ChunkCoordinatesPortal> portalCache = new LongHashMap(); // ChunkCoord -> PortalCoord Originally named 'c', used for caching. | |
private final List<Long> portalChunks = new ArrayList(); // Originally named 'd', list of portal chunk coordinates (??) | |
public ChunkCoordinates findPortal(double xPos, double yPos, double zPos, int searchRadius) { | |
//Inserted | |
final int worldHeight = this.a.S() | |
// If world env is END, use spesific algorithm for that | |
if (this.a.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) { // this.a instanceof WorldServer | |
return this.findEndPortal(this.a.worldProvider.h()); | |
} | |
// CraftBukkit end | |
double currentClosestPortal = -1.0D; // d3 | |
int finalX = 0; // i | |
int finalY = 0; // j | |
int finalZ = 0; // k | |
// CraftBukkit start | |
int xPosI = MathHelper.floor(xPos); | |
int zPosI = MathHelper.floor(zPos); | |
// CraftBukkit end | |
long chunkCoord = ChunkCoordIntPair.a(xPosI, zPosI); | |
boolean shouldUpdateCache = true; | |
double zPortalOffset; | |
int xSearch; | |
if (this.portalCache.contains(chunkCoord)) { | |
ChunkCoordinatesPortal cachedPortal = (ChunkCoordinatesPortal) this.portalCache.getEntry(chunkCoord); | |
currentClosestPortal = 0.0D; | |
finalX = cachedPortal.x; | |
finalY = cachedPortal.y; | |
finalZ = cachedPortal.z; | |
cachedPortal.d = this.a.getTime(); // this.a instanceof WorldServer (portals use the current time?) | |
shouldUpdateCache = false; | |
} else { | |
for (xSearch = xPosI - searchRadius; xSearch <= xPosI + searchRadius; ++xSearch) { | |
double xPortalOffset = (double) xSearch + 0.5D - xPos; // CraftBukkit | |
for (int zSearch = zPosI - searchRadius; zSearch <= zPosI + searchRadius; ++zSearch) { | |
double yPortalOffset = (double) zSearch + 0.5D - zPos; // CraftBukkit | |
for (int ySearch = worldHeight - 1; ySearch >= 0; --ySearch) { | |
if (this.a.getType(xSearch, ySearch, zSearch) == Blocks.PORTAL) { | |
while (this.a.getType(xSearch, ySearch - 1, zSearch) == Blocks.PORTAL) { | |
--ySearch; | |
} | |
zPortalOffset = (double) ySearch + 0.5D - yPos; // CraftBukkit | |
double portalDistance = xPortalOffset * xPortalOffset + zPortalOffset * zPortalOffset + yPortalOffset * yPortalOffset; | |
if (currentClosestPortal < 0.0D || portalDistance < currentClosestPortal) { | |
currentClosestPortal = portalDistance; | |
finalX = xSearch; | |
finalY = ySearch; | |
finalZ = zSearch; | |
} | |
} | |
} | |
} | |
} | |
} | |
if (currentClosestPortal >= 0.0D) { | |
if (shouldUpdateCache) { | |
this.portalCache.put(chunkCoord, new ChunkCoordinatesPortal(this, finalX, finalY, finalZ, this.a.getTime())); // this.a instanceof WorldServer | |
this.portalChunks.add(Long.valueOf(chunkCoord)); | |
} | |
// CraftBukkit start - Moved entity teleportation logic into exit | |
return new ChunkCoordinates(finalX, finalY, finalZ); | |
} else { | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment