Add pathfinding API
This commit is contained in:
@@ -140,6 +140,14 @@ public interface Tile extends Locatable
|
||||
*/
|
||||
boolean hasLineOfSightTo(Tile other);
|
||||
|
||||
/**
|
||||
* Computes and returns the path from this tile to another.
|
||||
*
|
||||
* @param other the other tile
|
||||
* @return the checkpoint tiles of the path, or null if no path found
|
||||
*/
|
||||
List<Tile> pathTo(Tile other);
|
||||
|
||||
/**
|
||||
* Get all the ground items for this tile
|
||||
*
|
||||
|
||||
@@ -34,6 +34,7 @@ import net.runelite.api.Client;
|
||||
import static net.runelite.api.Constants.CHUNK_SIZE;
|
||||
import static net.runelite.api.Constants.REGION_SIZE;
|
||||
import net.runelite.api.Perspective;
|
||||
import net.runelite.api.Tile;
|
||||
|
||||
/**
|
||||
* A three-dimensional point representing the coordinate of a Tile.
|
||||
@@ -436,4 +437,90 @@ public class WorldPoint
|
||||
{
|
||||
return position & (REGION_SIZE - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the checkpoint tiles of a server-sided path from this WorldPoint to another WorldPoint.
|
||||
* <p>
|
||||
* The checkpoint tiles of a path are the "corner tiles" of a path and determine the path completely.
|
||||
*
|
||||
* Note that true server-sided pathfinding uses collisiondata of the 128x128 area around this WorldPoint,
|
||||
* while the client only has access to collisiondata within the 104x104 loaded area.
|
||||
* This means that the results would differ in case the server's path goes near (or over) the border of the loaded area.
|
||||
*
|
||||
* @param client The client to compare in
|
||||
* @param other The other WorldPoint to compare with
|
||||
* @return Returns the checkpoint tiles of the path
|
||||
*/
|
||||
public List<WorldPoint> pathTo(Client client, WorldPoint other)
|
||||
{
|
||||
if (plane != other.getPlane())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalPoint sourceLp = LocalPoint.fromWorld(client, x, y);
|
||||
LocalPoint targetLp = LocalPoint.fromWorld(client, other.getX(), other.getY());
|
||||
if (sourceLp == null || targetLp == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int thisX = sourceLp.getSceneX();
|
||||
int thisY = sourceLp.getSceneY();
|
||||
int otherX = targetLp.getSceneX();
|
||||
int otherY = targetLp.getSceneY();
|
||||
|
||||
Tile[][][] tiles = client.getScene().getTiles();
|
||||
Tile sourceTile = tiles[plane][thisX][thisY];
|
||||
|
||||
Tile targetTile = tiles[plane][otherX][otherY];
|
||||
List<Tile> checkpointTiles = sourceTile.pathTo(targetTile);
|
||||
if (checkpointTiles == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
List<WorldPoint> checkpointWPs = new ArrayList<>();
|
||||
for (Tile checkpointTile : checkpointTiles)
|
||||
{
|
||||
if (checkpointTile == null) {
|
||||
break;
|
||||
}
|
||||
checkpointWPs.add(checkpointTile.getWorldLocation());
|
||||
}
|
||||
return checkpointWPs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path distance from this point to a WorldPoint.
|
||||
* <p>
|
||||
* If the other point is unreachable, this method will return {@link Integer#MAX_VALUE}.
|
||||
*
|
||||
* @param client
|
||||
* @param other
|
||||
* @return Returns the path distance
|
||||
*/
|
||||
public int distanceToPath(Client client, WorldPoint other)
|
||||
{
|
||||
List<WorldPoint> checkpointWPs = this.pathTo(client, other);
|
||||
if (checkpointWPs == null)
|
||||
{
|
||||
// No path found
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
WorldPoint destinationPoint = checkpointWPs.get(checkpointWPs.size() - 1);
|
||||
if (other.getX() != destinationPoint.getX() || other.getY() != destinationPoint.getY())
|
||||
{
|
||||
// Path found but not to the requested tile
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
WorldPoint Point1 = this;
|
||||
int distance = 0;
|
||||
for (WorldPoint Point2 : checkpointWPs)
|
||||
{
|
||||
distance += Point1.distanceTo2D(Point2);
|
||||
Point1 = Point2;
|
||||
}
|
||||
return distance;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user