Improved pathfinding to handle cases when both player and target are moving

This commit is contained in:
dam 2025-11-25 15:14:39 +02:00 committed by Ryan
parent dfb53cfa03
commit 6241ff9ce5

View file

@ -11,6 +11,7 @@ import core.game.world.GameWorld;
import core.game.world.map.Direction;
import core.game.world.map.Location;
import core.game.world.map.Point;
import core.game.world.map.RegionManager;
import core.game.world.map.path.Path;
import core.game.world.map.path.Pathfinder;
import core.net.packet.PacketRepository;
@ -394,24 +395,29 @@ public abstract class MovementPulse extends Pulse {
for (int i = 0; i < points.length; i++) {
Location closestBorder = getClosestBorderToPoint(points[i], loc.getZ());
if (!RegionManager.isTeleportPermitted(closestBorder)) { // A nasty hack to discard invalid intersection points
continue;
}
int moverDist = Math.max(Math.abs(ml.getX() - closestBorder.getX()), Math.abs(ml.getY() - closestBorder.getY()));
float movementRatio = moverDist / (float) ((i + 1) / (mover.getWalkingQueue().isRunning() ? 2 : 1));
if (predictiveIntersection == null && movementRatio <= 1.0) { //try to predict an intersection point on the path if possible
predictiveIntersection = points[i];
break;
}
// Otherwise, we target the farthest point along target's planned movement that's within 1 tick's running,
// this ensures the player will run to catch up to the target if able.
if (moverDist <= 2) {
p = points[i];
}
}
if (predictiveIntersection != null)
p = predictiveIntersection;
Location endLoc = getClosestBorderToPoint(p, loc.getZ());
if (!RegionManager.isTeleportPermitted(endLoc)) { // Basically a prayer
return loc;
}
return endLoc;
}
}