289 lines
12 KiB
Diff
289 lines
12 KiB
Diff
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
|
|
index 0000000000000000000000000000000000000000..92d1bb8b9cdb9eb0c04574c0b6ba5acdca9fb377
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
|
|
@@ -0,0 +1,139 @@
|
|
+package com.destroystokyo.paper.entity;
|
|
+
|
|
+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 net.minecraft.world.level.pathfinder.Node;
|
|
+import net.minecraft.world.level.pathfinder.Path;
|
|
+import java.util.ArrayList;
|
|
+import java.util.List;
|
|
+
|
|
+public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinder {
|
|
+
|
|
+ private final net.minecraft.world.entity.Mob entity;
|
|
+
|
|
+ public PaperPathfinder(net.minecraft.world.entity.Mob 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() {
|
|
+ Path 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");
|
|
+ Path 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");
|
|
+ Path 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");
|
|
+ Path pathEntity = ((PaperPathResult) path).path;
|
|
+ return entity.getNavigation().setDestination(pathEntity, speed);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean canOpenDoors() {
|
|
+ return entity.getNavigation().getPathfinder().getPathfinder().shouldOpenDoors();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setCanOpenDoors(boolean canOpenDoors) {
|
|
+ entity.getNavigation().getPathfinder().getPathfinder().setShouldOpenDoors(canOpenDoors);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean canPassDoors() {
|
|
+ return entity.getNavigation().getPathfinder().getPathfinder().shouldPassDoors();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setCanPassDoors(boolean canPassDoors) {
|
|
+ entity.getNavigation().getPathfinder().getPathfinder().setShouldPassDoors(canPassDoors);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean canFloat() {
|
|
+ return entity.getNavigation().getPathfinder().getPathfinder().shouldFloat();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setCanFloat(boolean canFloat) {
|
|
+ entity.getNavigation().getPathfinder().getPathfinder().setShouldFloat(canFloat);
|
|
+ }
|
|
+
|
|
+ public class PaperPathResult implements com.destroystokyo.paper.entity.PaperPathfinder.PathResult {
|
|
+
|
|
+ private final Path path;
|
|
+ PaperPathResult(Path path) {
|
|
+ this.path = path;
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ @Override
|
|
+ public Location getFinalPoint() {
|
|
+ Node point = path.getFinalPoint();
|
|
+ return point != null ? toLoc(point) : null;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public List<Location> getPoints() {
|
|
+ List<Location> points = new ArrayList<>();
|
|
+ for (Node point : path.getPoints()) {
|
|
+ points.add(toLoc(point));
|
|
+ }
|
|
+ return points;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int getNextPointIndex() {
|
|
+ return path.getNextIndex();
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ @Override
|
|
+ public Location getNextPoint() {
|
|
+ if (!path.hasNext()) {
|
|
+ return null;
|
|
+ }
|
|
+ return toLoc(path.getPoints().get(path.getNextIndex()));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private Location toLoc(Node point) {
|
|
+ return new Location(entity.level.getWorld(), point.getX(), point.getY(), point.getZ());
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
|
|
index 8212aab2884c2a894bc981850e483ce31814c708..69edca1ef95c37b11fe3f793e6a8f8a674bd7f6f 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
|
|
@@ -93,7 +93,7 @@ public abstract class PathNavigation {
|
|
}
|
|
|
|
@Nullable
|
|
- public final Path createPath(double x, double y, double z, int distance) {
|
|
+ public final Path calculateDestination(double d0, double d1, double d2) { return createPath(d0, d1, d2, 0); } public final Path createPath(double x, double y, double z, int distance) { // Paper - OBFHELPER
|
|
return this.createPath(new BlockPos(x, y, z), distance);
|
|
}
|
|
|
|
@@ -123,7 +123,7 @@ public abstract class PathNavigation {
|
|
}
|
|
|
|
@Nullable
|
|
- public Path createPath(Entity entity, int distance) {
|
|
+ public final Path calculateDestination(Entity entity) { return createPath(entity, 0); } public Path createPath(Entity entity, int distance) {
|
|
return this.createPath(ImmutableSet.of(entity.blockPosition()), entity, 16, true, distance); // Paper
|
|
}
|
|
|
|
@@ -195,6 +195,7 @@ public abstract class PathNavigation {
|
|
return path != null && this.moveTo(path, speed);
|
|
}
|
|
|
|
+ public boolean setDestination(@Nullable Path pathentity, double speed) { return moveTo(pathentity, speed); } // Paper - OBFHELPER
|
|
public boolean moveTo(@Nullable Path path, double speed) {
|
|
if (path == null) {
|
|
this.path = null;
|
|
@@ -221,7 +222,7 @@ public abstract class PathNavigation {
|
|
}
|
|
}
|
|
|
|
- @Nullable
|
|
+ @Nullable public Path getPathEntity() { return getPath(); } @Nullable // Paper - OBFHELPER
|
|
public Path getPath() {
|
|
return this.path;
|
|
}
|
|
@@ -335,6 +336,7 @@ public abstract class PathNavigation {
|
|
return !this.isDone();
|
|
}
|
|
|
|
+ public void stopPathfinding() { stop(); } // Paper - OBFHELPER
|
|
public void stop() {
|
|
this.path = null;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/Node.java b/src/main/java/net/minecraft/world/level/pathfinder/Node.java
|
|
index d7a86444d0e76154319c409317fc5ac9c54403a8..328f050ae68e0b42690f05e5995fb2711b8cf46d 100644
|
|
--- a/src/main/java/net/minecraft/world/level/pathfinder/Node.java
|
|
+++ b/src/main/java/net/minecraft/world/level/pathfinder/Node.java
|
|
@@ -6,9 +6,9 @@ import net.minecraft.util.Mth;
|
|
import net.minecraft.world.phys.Vec3;
|
|
|
|
public class Node {
|
|
- public final int x;
|
|
- public final int y;
|
|
- public final int z;
|
|
+ public final int x; public final int getX() { return x; } // Paper - OBFHELPER
|
|
+ public final int y; public final int getY() { return y; } // Paper - OBFHELPER
|
|
+ public final int z; public final int getZ() { return z; } // Paper - OBFHELPER
|
|
private final int hash;
|
|
public int heapIdx = -1;
|
|
public float g;
|
|
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/NodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/NodeEvaluator.java
|
|
index 72ca8adb9fa65588c6b1e19be2dc27a36c0146a6..e5bfd9ade1a49e11afd4a49784a0874654945709 100644
|
|
--- a/src/main/java/net/minecraft/world/level/pathfinder/NodeEvaluator.java
|
|
+++ b/src/main/java/net/minecraft/world/level/pathfinder/NodeEvaluator.java
|
|
@@ -15,9 +15,9 @@ public abstract class NodeEvaluator {
|
|
protected int entityWidth;
|
|
protected int entityHeight;
|
|
protected int entityDepth;
|
|
- protected boolean canPassDoors;
|
|
- protected boolean canOpenDoors;
|
|
- protected boolean canFloat;
|
|
+ protected boolean canPassDoors; public boolean shouldPassDoors() { return canPassDoors; } public void setShouldPassDoors(boolean b) { canPassDoors = b; } // Paper - obfhelper
|
|
+ protected boolean canOpenDoors; public boolean shouldOpenDoors() { return canOpenDoors; } public void setShouldOpenDoors(boolean b) { canOpenDoors = b; } // Paper - obfhelper
|
|
+ protected boolean canFloat; public boolean shouldFloat() { return canFloat; } public void setShouldFloat(boolean b) { canFloat = b; } // Paper - obfhelper
|
|
|
|
public void prepare(PathNavigationRegion cachedWorld, Mob entity) {
|
|
this.level = cachedWorld;
|
|
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/Path.java b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
|
index 6928c415e328dd7cff2e9ec553bc4faa1ff8facf..e95312e5b0f0200178cbe1a61b3629dfeac55b4a 100644
|
|
--- a/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
|
+++ b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
|
@@ -12,14 +12,15 @@ import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.phys.Vec3;
|
|
|
|
public class Path {
|
|
- private final List<Node> nodes;
|
|
+ private final List<Node> nodes; public List<Node> getPoints() { return nodes; } // Paper - OBFHELPER
|
|
private Node[] openSet = new Node[0];
|
|
private Node[] closedSet = new Node[0];
|
|
private Set<Target> targetNodes;
|
|
- private int nextNodeIndex;
|
|
+ private int nextNodeIndex; public int getNextIndex() { return this.nextNodeIndex; } // Paper - OBFHELPER
|
|
private final BlockPos target;
|
|
private final float distToTarget;
|
|
private final boolean reached;
|
|
+ public boolean hasNext() { return getNextIndex() < getPoints().size(); } // Paper
|
|
|
|
public Path(List<Node> nodes, BlockPos target, boolean reachesTarget) {
|
|
this.nodes = nodes;
|
|
@@ -41,7 +42,7 @@ public class Path {
|
|
}
|
|
|
|
@Nullable
|
|
- public Node getEndNode() {
|
|
+ public Node getFinalPoint() { return getEndNode(); } @Nullable public Node getEndNode() { // Paper - OBFHELPER
|
|
return !this.nodes.isEmpty() ? this.nodes.get(this.nodes.size() - 1) : null;
|
|
}
|
|
|
|
@@ -88,7 +89,7 @@ public class Path {
|
|
return this.getEntityPosAtNode(entity, this.nextNodeIndex);
|
|
}
|
|
|
|
- public BlockPos getNextNodePos() {
|
|
+ public BlockPos getNext() { return getNextNodePos(); } public BlockPos getNextNodePos() { // Paper - OBFHELPER
|
|
return this.nodes.get(this.nextNodeIndex).asBlockPos();
|
|
}
|
|
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
|
index 71872fdfafca82cf745eecee4bf984726d49f5a4..9c9fa83615cd06539ce5e4e3d4feaa69f65b7931 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
|
@@ -11,8 +11,11 @@ import org.bukkit.loot.LootTable;
|
|
public abstract class CraftMob extends CraftLivingEntity implements Mob {
|
|
public CraftMob(CraftServer server, net.minecraft.world.entity.Mob 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) {
|
|
net.minecraft.world.entity.Mob entity = this.getHandle();
|