From 2c62d3aa316307c10c575bd098c753b9b94a72ca Mon Sep 17 00:00:00 2001 From: Doc Date: Sat, 18 Jul 2026 11:19:50 -0400 Subject: [PATCH 1/3] Expose reachRange argument in findPath for PathFinder --- .../paper/entity/Pathfinder.java | 34 +++++++++++++++++-- .../paper/entity/PaperPathfinder.java | 10 +++--- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java b/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java index b952097d9e0f..11edac366399 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java @@ -43,7 +43,19 @@ public interface Pathfinder { * @param loc Location to navigate to * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated */ - @Nullable PathResult findPath(Location loc); + default @Nullable PathResult findPath(Location loc) { + return this.findPath(loc, 0); + } + + /** + * Calculates a destination for the Entity to navigate to, but does not set it + * as the current target. Useful for calculating what would happen before setting it. + * + * @param loc Location to navigate to + * @param reachRange The reach range of the pathfinding + * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated + */ + @Nullable PathResult findPath(Location loc, int reachRange); /** * Calculates a destination for the Entity to navigate to reach the target entity, @@ -76,7 +88,25 @@ default PathResult findPath(LivingEntity target) { * @param target the Entity to navigate to * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated */ - @Nullable PathResult findPath(Entity target); + default @Nullable PathResult findPath(Entity target) { + return this.findPath(target, 0); + } + + /** + * Calculates a destination for the Entity to navigate to to reach the target entity, + * but does not set it as the current target. + * Useful for calculating what would happen before setting it. + *

+ * The behavior of this PathResult is subject to the games pathfinding rules, and may + * result in the pathfinding automatically updating to follow the target Entity. + *

+ * However, this behavior is not guaranteed, and is subject to the games behavior. + * + * @param target the Entity to navigate to + * @param reachRange The reach range of the pathfinding + * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated + */ + @Nullable PathResult findPath(Entity target, int reachRange); /** * Calculates a destination for the Entity to navigate to, and sets it with default speed diff --git a/paper-server/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java b/paper-server/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java index 559df35d7c88..efb22c6535f7 100644 --- a/paper-server/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java +++ b/paper-server/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java @@ -49,17 +49,19 @@ public PathResult getCurrentPath() { @Nullable @Override - public PathResult findPath(Location loc) { + public PathResult findPath(final Location loc, final int reachRange) { Preconditions.checkArgument(loc != null, "Location can not be null"); - Path path = this.entity.getNavigation().createPath(loc.getX(), loc.getY(), loc.getZ(), 0); + Preconditions.checkArgument(reachRange >= 0, "Reach range can not be negative"); + Path path = this.entity.getNavigation().createPath(loc.getX(), loc.getY(), loc.getZ(), reachRange); return path != null ? new PaperPathResult(path) : null; } @Nullable @Override - public PathResult findPath(Entity target) { + public PathResult findPath(final Entity target, final int reachRange) { Preconditions.checkArgument(target != null, "Target can not be null"); - Path path = this.entity.getNavigation().createPath(((CraftEntity) target).getHandle(), 0); + Preconditions.checkArgument(reachRange >= 0, "Reach range can not be negative"); + Path path = this.entity.getNavigation().createPath(((CraftEntity) target).getHandle(), reachRange); return path != null ? new PaperPathResult(path) : null; } From 12fb0aa70ad0bde985c8840f5b467ab45c412801 Mon Sep 17 00:00:00 2001 From: Doc Date: Sun, 19 Jul 2026 12:07:40 -0400 Subject: [PATCH 2/3] Annotation for reachRange parameter --- .../main/java/com/destroystokyo/paper/entity/Pathfinder.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java b/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java index 11edac366399..d996b0278cd8 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java @@ -5,6 +5,7 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Entity; import org.bukkit.entity.Mob; +import org.checkerframework.checker.index.qual.NonNegative; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; @@ -55,7 +56,7 @@ public interface Pathfinder { * @param reachRange The reach range of the pathfinding * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated */ - @Nullable PathResult findPath(Location loc, int reachRange); + @Nullable PathResult findPath(final Location loc, final @NonNegative int reachRange); /** * Calculates a destination for the Entity to navigate to reach the target entity, @@ -106,7 +107,7 @@ default PathResult findPath(LivingEntity target) { * @param reachRange The reach range of the pathfinding * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated */ - @Nullable PathResult findPath(Entity target, int reachRange); + @Nullable PathResult findPath(final Entity target, final @NonNegative int reachRange); /** * Calculates a destination for the Entity to navigate to, and sets it with default speed From 184340eb07d5d3d90a825c26f0a0f610552ead7b Mon Sep 17 00:00:00 2001 From: Doc Date: Sun, 19 Jul 2026 12:28:45 -0400 Subject: [PATCH 3/3] Explain a little more what reachRange parameter represents --- .../java/com/destroystokyo/paper/entity/Pathfinder.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java b/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java index d996b0278cd8..6ddc6cd8c1cb 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/entity/Pathfinder.java @@ -53,7 +53,8 @@ public interface Pathfinder { * as the current target. Useful for calculating what would happen before setting it. * * @param loc Location to navigate to - * @param reachRange The reach range of the pathfinding + * @param reachRange The Manhattan-distance threshold + * from the target position at which the path is considered reached, where {@code 0} requires the exact target position * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated */ @Nullable PathResult findPath(final Location loc, final @NonNegative int reachRange); @@ -104,7 +105,8 @@ default PathResult findPath(LivingEntity target) { * However, this behavior is not guaranteed, and is subject to the games behavior. * * @param target the Entity to navigate to - * @param reachRange The reach range of the pathfinding + * @param reachRange The Manhattan-distance threshold + * from the target position at which the path is considered reached, where {@code 0} requires the exact target position * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated */ @Nullable PathResult findPath(final Entity target, final @NonNegative int reachRange);