PaperMC/Spigot-Server-Patches/0281-Mob-Pathfinding-API.patch
2021-05-15 23:42:36 +00:00

290 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..9a3edd114c4736b1843844c6ca49da7aea7983d1
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
@@ -0,0 +1,141 @@
+package com.destroystokyo.paper.entity;
+
+import net.minecraft.world.entity.EntityInsentient;
+import net.minecraft.world.level.pathfinder.PathEntity;
+import net.minecraft.world.level.pathfinder.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);
+ }
+
+ @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 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() {
+ List<Location> points = new ArrayList<>();
+ for (PathPoint 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(PathPoint point) {
+ return new Location(entity.world.getWorld(), point.getX(), point.getY(), point.getZ());
+ }
+}
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/NavigationAbstract.java b/src/main/java/net/minecraft/world/entity/ai/navigation/NavigationAbstract.java
index d134333c736dc1ee1c722d680d7a9c22c1b265bd..06d05b511d623d0247d44989bee85b383a8fb52f 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/NavigationAbstract.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/NavigationAbstract.java
@@ -100,7 +100,7 @@ public abstract class NavigationAbstract {
}
@Nullable
- public final PathEntity a(double d0, double d1, double d2, int i) {
+ public final PathEntity calculateDestination(double d0, double d1, double d2) { return a(d0, d1, d2, 0); } public final PathEntity a(double d0, double d1, double d2, int i) { // Paper - OBFHELPER
return this.a(new BlockPosition(d0, d1, d2), i);
}
@@ -125,7 +125,7 @@ public abstract class NavigationAbstract {
}
@Nullable
- public PathEntity a(Entity entity, int i) {
+ public final PathEntity calculateDestination(Entity entity) { return a(entity, 0); } public PathEntity a(Entity entity, int i) {
return this.a(ImmutableSet.of(entity.getChunkCoordinates()), entity, 16, true, i); // Paper
}
@@ -190,6 +190,7 @@ public abstract class NavigationAbstract {
return pathentity != null && this.a(pathentity, d0);
}
+ 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;
@@ -217,7 +218,7 @@ public abstract class NavigationAbstract {
}
}
- @Nullable
+ @Nullable public PathEntity getPathEntity() { return k(); } @Nullable // Paper - OBFHELPER
public PathEntity k() {
return this.c;
}
@@ -341,6 +342,7 @@ public abstract class NavigationAbstract {
return !this.m();
}
+ public void stopPathfinding() { o(); } // Paper - OBFHELPER
public void o() {
this.c = null;
}
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathEntity.java b/src/main/java/net/minecraft/world/level/pathfinder/PathEntity.java
index 606027de777750f6d2ab0d7f1ef387ed4f0c6092..81c3cb9da3f901d2bcf384f7113bdc5c60f9962f 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/PathEntity.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/PathEntity.java
@@ -8,13 +8,14 @@ import net.minecraft.world.phys.Vec3D;
public class PathEntity {
- private final List<PathPoint> a;
+ private final List<PathPoint> a; public List<PathPoint> getPoints() { return a; } // Paper - OBFHELPER
private PathPoint[] b = new PathPoint[0];
private PathPoint[] c = new PathPoint[0];
- private int e;
+ private int e; public int getNextIndex() { return this.e; } // Paper - OBFHELPER
private final BlockPosition f;
private final float g;
private final boolean h;
+ public boolean hasNext() { return getNextIndex() < getPoints().size(); } // Paper
public PathEntity(List<PathPoint> list, BlockPosition blockposition, boolean flag) {
this.a = list;
@@ -36,7 +37,7 @@ public class PathEntity {
}
@Nullable
- public PathPoint d() {
+ public PathPoint getFinalPoint() { return d(); } @Nullable public PathPoint d() { // Paper - OBFHELPER
return !this.a.isEmpty() ? (PathPoint) this.a.get(this.a.size() - 1) : null;
}
@@ -84,7 +85,7 @@ public class PathEntity {
return this.a(entity, this.e);
}
- public BlockPosition g() {
+ public BlockPosition getNext() { return g(); } public BlockPosition g() { // Paper - OBFHELPER
return ((PathPoint) this.a.get(this.e)).a();
}
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathPoint.java b/src/main/java/net/minecraft/world/level/pathfinder/PathPoint.java
index 43cc9430972a18cbf03a590d576ed200e3836017..c260b0ca70cb18811158761c574aee9c3166da28 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/PathPoint.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/PathPoint.java
@@ -5,9 +5,9 @@ import net.minecraft.util.MathHelper;
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 m;
public int d = -1;
public float e;
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathfinderAbstract.java b/src/main/java/net/minecraft/world/level/pathfinder/PathfinderAbstract.java
index f2080bd50db04af6eabec4b4b757d6dadfb1a2f5..88be03bd77656235322522c3782b9f9a878b86b1 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/PathfinderAbstract.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/PathfinderAbstract.java
@@ -16,9 +16,9 @@ public abstract class PathfinderAbstract {
protected int d;
protected int e;
protected int f;
- protected boolean g;
- protected boolean h;
- protected boolean i;
+ protected boolean g; public boolean shouldPassDoors() { return g; } public void setShouldPassDoors(boolean b) { g = b; } // Paper - obfhelper
+ protected boolean h; public boolean shouldOpenDoors() { return h; } public void setShouldOpenDoors(boolean b) { h = b; } // Paper - obfhelper
+ protected boolean i; public boolean shouldFloat() { return i; } public void setShouldFloat(boolean b) { i = b; } // Paper - obfhelper
public PathfinderAbstract() {}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
index eb275ac45def34d5bb1ed696b4f6a4d53d282ab3..28a4e90130f51fd2fda7003fde5b4d0a410e1aef 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();