From 3501ae94e3889678406e8d15690cd905c859d788 Mon Sep 17 00:00:00 2001 From: Aikar <aikar@aikar.co> Date: Sun, 9 Sep 2018 13:30:00 -0400 Subject: [PATCH] Mob Pathfinding API Implements Pathfinding API for mobs diff --git a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java new file mode 100644 index 000000000..ed3d86ddd --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java @@ -0,0 +1,113 @@ +package com.destroystokyo.paper.entity; + +import net.minecraft.server.EntityInsentient; +import net.minecraft.server.PathEntity; +import net.minecraft.server.PathPoint; +import org.apache.commons.lang.Validate; +import org.bukkit.Location; +import org.bukkit.craftbukkit.entity.CraftLivingEntity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Mob; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.List; + +public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinder { + + private final EntityInsentient entity; + + public PaperPathfinder(EntityInsentient entity) { + this.entity = entity; + } + + @Override + public Mob getEntity() { + return entity.getBukkitMob(); + } + + @Override + public void stopPathfinding() { + entity.getNavigation().stopPathfinding(); + } + + @Override + public boolean hasPath() { + return entity.getNavigation().getPathEntity() != null; + } + + @Nullable + @Override + public PathResult getCurrentPath() { + PathEntity path = entity.getNavigation().getPathEntity(); + return path != null ? new PaperPathResult(path) : null; + } + + @Nullable + @Override + public PathResult findPath(Location loc) { + Validate.notNull(loc, "Location can not be null"); + PathEntity path = entity.getNavigation().calculateDestination(loc.getX(), loc.getY(), loc.getZ()); + return path != null ? new PaperPathResult(path) : null; + } + + @Nullable + @Override + public PathResult findPath(LivingEntity target) { + Validate.notNull(target, "Target can not be null"); + PathEntity path = entity.getNavigation().calculateDestination(((CraftLivingEntity) target).getHandle()); + return path != null ? new PaperPathResult(path) : null; + } + + @Override + public boolean moveTo(@Nonnull PathResult path, double speed) { + Validate.notNull(path, "PathResult can not be null"); + PathEntity pathEntity = ((PaperPathResult) path).path; + return entity.getNavigation().setDestination(pathEntity, speed); + } + + public class PaperPathResult implements com.destroystokyo.paper.entity.PaperPathfinder.PathResult { + + private final PathEntity path; + PaperPathResult(PathEntity path) { + this.path = path; + } + + @Nullable + @Override + public Location getFinalPoint() { + PathPoint point = path.getFinalPoint(); + return point != null ? toLoc(point) : null; + } + + @Override + public List<Location> getPoints() { + int pathCount = path.getPathCount(); + List<Location> points = new ArrayList<>(); + PathPoint[] pathPoints = path.getPoints(); + for (int i = 0; i < pathCount; i++) { + points.add(toLoc(pathPoints[i])); + } + return points; + } + + @Override + public int getNextPointIndex() { + return path.getNextIndex(); + } + + @Nullable + @Override + public Location getNextPoint() { + if (!path.hasNext()) { + return null; + } + return toLoc(path.getPoints()[path.getNextIndex()]); + } + } + + private Location toLoc(PathPoint point) { + return new Location(entity.world.getWorld(), point.getX(), point.getY(), point.getZ()); + } +} diff --git a/src/main/java/net/minecraft/server/NavigationAbstract.java b/src/main/java/net/minecraft/server/NavigationAbstract.java index c55aadb53..cac0ce2a3 100644 --- a/src/main/java/net/minecraft/server/NavigationAbstract.java +++ b/src/main/java/net/minecraft/server/NavigationAbstract.java @@ -69,7 +69,7 @@ public abstract class NavigationAbstract { } @Nullable - public final PathEntity a(double d0, double d1, double d2) { + public final PathEntity calculateDestination(double d0, double d1, double d2) { return a(d0, d1, d2); } @Nullable public final PathEntity a(double d0, double d1, double d2) { // Paper - OBFHELPER return this.b(new BlockPosition(d0, d1, d2)); } @@ -97,7 +97,7 @@ public abstract class NavigationAbstract { } @Nullable - public PathEntity a(Entity entity) { + public PathEntity calculateDestination(Entity entity) { return a(entity); } @Nullable public PathEntity a(Entity entity) { // Paper - OBFHELPER if (!this.b()) { return null; } else { @@ -148,6 +148,7 @@ public abstract class NavigationAbstract { private int pathfindFailures = 0; // Paper end + public boolean setDestination(@Nullable PathEntity pathentity, double speed) { return a(pathentity, speed); } // Paper - OBFHELPER public boolean a(@Nullable PathEntity pathentity, double d0) { if (pathentity == null) { this.c = null; @@ -170,8 +171,7 @@ public abstract class NavigationAbstract { } } } - - @Nullable + @Nullable public PathEntity getPathEntity() { return m(); } @Nullable // Paper - OBFHELPER public PathEntity m() { return this.c; } @@ -279,6 +279,7 @@ public abstract class NavigationAbstract { return this.c == null || this.c.b(); } + public void stopPathfinding() { q(); } // Paper - OBFHELPER public void q() { this.pathfindFailures = 0; this.lastFailure = 0; // Paper - Pathfinding optimizations this.c = null; diff --git a/src/main/java/net/minecraft/server/PathEntity.java b/src/main/java/net/minecraft/server/PathEntity.java index 31fc1fbc6..5cf7f3bf1 100644 --- a/src/main/java/net/minecraft/server/PathEntity.java +++ b/src/main/java/net/minecraft/server/PathEntity.java @@ -4,12 +4,13 @@ import javax.annotation.Nullable; public class PathEntity { - private final PathPoint[] a; + private final PathPoint[] a; public PathPoint[] getPoints() { return a; } // Paper - OBFHELPER private PathPoint[] b = new PathPoint[0]; private PathPoint[] c = new PathPoint[0]; private PathPoint d; - private int e; - private int f; + private int e; public int getNextIndex() { return e; } // Paper - OBFHELPER + private int f; public int getPathCount() { return f; } // Paper - OBFHELPER + public boolean hasNext() { return getNextIndex() < getPathCount(); } // Paper public PathEntity(PathPoint[] apathpoint) { this.a = apathpoint; @@ -25,7 +26,7 @@ public class PathEntity { } @Nullable - public PathPoint c() { + public PathPoint getFinalPoint() { return c(); } @Nullable public PathPoint c() { // Paper - OBFHELPER return this.f > 0 ? this.a[this.f - 1] : null; } @@ -65,7 +66,7 @@ public class PathEntity { return this.a(entity, this.e); } - public Vec3D f() { + public Vec3D getNext() { return f(); } public Vec3D f() { // Paper - OBFHELPER PathPoint pathpoint = this.a[this.e]; return new Vec3D((double) pathpoint.a, (double) pathpoint.b, (double) pathpoint.c); diff --git a/src/main/java/net/minecraft/server/PathPoint.java b/src/main/java/net/minecraft/server/PathPoint.java index 78ed00286..0dd6e46d1 100644 --- a/src/main/java/net/minecraft/server/PathPoint.java +++ b/src/main/java/net/minecraft/server/PathPoint.java @@ -2,9 +2,9 @@ package net.minecraft.server; public class PathPoint { - public final int a; - public final int b; - public final int c; + public final int a; public final int getX() { return a; } // Paper - OBFHELPER + public final int b; public final int getY() { return b; } // Paper - OBFHELPER + public final int c; public final int getZ() { return c; } // Paper - OBFHELPER private final int n; public int d = -1; public float e; diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java index 5bf1cd06f..53c2d154e 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java @@ -12,8 +12,11 @@ import org.bukkit.loot.LootTable; public abstract class CraftMob extends CraftLivingEntity implements Mob { public CraftMob(CraftServer server, EntityInsentient entity) { super(server, entity); + paperPathfinder = new com.destroystokyo.paper.entity.PaperPathfinder(entity); // Paper } + private final com.destroystokyo.paper.entity.PaperPathfinder paperPathfinder; // Paper + @Override public com.destroystokyo.paper.entity.Pathfinder getPathfinder() { return paperPathfinder; } // Paper @Override public void setTarget(LivingEntity target) { EntityInsentient entity = getHandle(); -- 2.21.0