2018-09-09 18:58:47 +02:00
|
|
|
From 0000000000000000000000000000000000000000 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
|
2018-09-10 03:45:54 +02:00
|
|
|
index 0000000000..ed3d86ddd3
|
2018-09-09 18:58:47 +02:00
|
|
|
--- /dev/null
|
|
|
|
+++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
|
|
|
|
@@ -0,0 +0,0 @@
|
|
|
|
+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
|
2018-09-10 03:45:54 +02:00
|
|
|
+ public boolean hasPath() {
|
2018-09-09 18:58:47 +02:00
|
|
|
+ return entity.getNavigation().getPathEntity() != null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Nullable
|
|
|
|
+ @Override
|
2018-09-10 03:45:54 +02:00
|
|
|
+ public PathResult getCurrentPath() {
|
2018-09-09 18:58:47 +02:00
|
|
|
+ PathEntity path = entity.getNavigation().getPathEntity();
|
|
|
|
+ return path != null ? new PaperPathResult(path) : null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Nullable
|
|
|
|
+ @Override
|
2018-09-10 03:45:54 +02:00
|
|
|
+ public PathResult findPath(Location loc) {
|
2018-09-09 18:58:47 +02:00
|
|
|
+ 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
|
2018-09-10 03:45:54 +02:00
|
|
|
+ public PathResult findPath(LivingEntity target) {
|
2018-09-09 18:58:47 +02:00
|
|
|
+ Validate.notNull(target, "Target can not be null");
|
|
|
|
+ PathEntity path = entity.getNavigation().calculateDestination(((CraftLivingEntity) target).getHandle());
|
|
|
|
+ return path != null ? new PaperPathResult(path) : null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
2018-09-10 03:45:54 +02:00
|
|
|
+ public boolean moveTo(@Nonnull PathResult path, double speed) {
|
2018-09-09 18:58:47 +02:00
|
|
|
+ Validate.notNull(path, "PathResult can not be null");
|
|
|
|
+ PathEntity pathEntity = ((PaperPathResult) path).path;
|
2018-09-10 03:45:54 +02:00
|
|
|
+ return entity.getNavigation().setDestination(pathEntity, speed);
|
2018-09-09 18:58:47 +02:00
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public class PaperPathResult implements com.destroystokyo.paper.entity.PaperPathfinder.PathResult {
|
|
|
|
+
|
|
|
|
+ private final PathEntity path;
|
|
|
|
+ PaperPathResult(PathEntity path) {
|
|
|
|
+ this.path = path;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Nullable
|
|
|
|
+ @Override
|
2018-09-10 03:45:54 +02:00
|
|
|
+ public Location getFinalPoint() {
|
2018-09-09 18:58:47 +02:00
|
|
|
+ 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
|
2018-09-09 20:36:51 +02:00
|
|
|
+ public int getNextPointIndex() {
|
2018-09-09 18:58:47 +02:00
|
|
|
+ return path.getNextIndex();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Nullable
|
|
|
|
+ @Override
|
2018-09-10 03:45:54 +02:00
|
|
|
+ public Location getNextPoint() {
|
2018-09-09 18:58:47 +02:00
|
|
|
+ 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 452da80f11..4023253f42 100644
|
|
|
|
--- a/src/main/java/net/minecraft/server/NavigationAbstract.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/NavigationAbstract.java
|
|
|
|
@@ -0,0 +0,0 @@ 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));
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -0,0 +0,0 @@ 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 {
|
|
|
|
@@ -0,0 +0,0 @@ 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;
|
|
|
|
@@ -0,0 +0,0 @@ public abstract class NavigationAbstract {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
-
|
|
|
|
- @Nullable
|
|
|
|
+ @Nullable public PathEntity getPathEntity() { return m(); } @Nullable // Paper - OBFHELPER
|
|
|
|
public PathEntity m() {
|
|
|
|
return this.c;
|
|
|
|
}
|
|
|
|
@@ -0,0 +0,0 @@ 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 5ffcda6d56..dae08cbbf8 100644
|
|
|
|
--- a/src/main/java/net/minecraft/server/PathEntity.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/PathEntity.java
|
|
|
|
@@ -0,0 +0,0 @@ package net.minecraft.server;
|
|
|
|
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;
|
|
|
|
@@ -0,0 +0,0 @@ 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -0,0 +0,0 @@ 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 497f472233..7fd1eff0b5 100644
|
|
|
|
--- a/src/main/java/net/minecraft/server/PathPoint.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/PathPoint.java
|
|
|
|
@@ -0,0 +0,0 @@
|
|
|
|
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 5bf1cd06fa..53c2d154ed 100644
|
|
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
|
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
|
|
|
@@ -0,0 +0,0 @@ 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();
|
|
|
|
--
|