Mob Pathfinding API

Implements Pathfinding API for mobs

== AT ==
public net.minecraft.world.entity.ai.navigation.PathNavigation pathFinder
public net.minecraft.world.level.pathfinder.PathFinder nodeEvaluator
public net.minecraft.world.level.pathfinder.Path nodes
This commit is contained in:
Aikar 2018-09-09 13:30:00 -04:00
parent ca341c9de8
commit ca42ec8f4e
3 changed files with 169 additions and 0 deletions

View file

@ -0,0 +1,10 @@
--- a/net/minecraft/world/level/pathfinder/Path.java
+++ b/net/minecraft/world/level/pathfinder/Path.java
@@ -18,6 +18,7 @@
private final BlockPos target;
private final float distToTarget;
private final boolean reached;
+ public boolean hasNext() { return getNextNodeIndex() < this.nodes.size(); } // Paper - Mob Pathfinding API
public Path(List<Node> nodes, BlockPos target, boolean reachesTarget) {
this.nodes = nodes;

View file

@ -0,0 +1,148 @@
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 net.minecraft.world.entity.Mob entity;
public PaperPathfinder(net.minecraft.world.entity.Mob entity) {
this.entity = entity;
}
@Override
public Mob getEntity() {
return (Mob) entity.getBukkitEntity();
}
public void setHandle(net.minecraft.world.entity.Mob entity) {
this.entity = entity;
}
@Override
public void stopPathfinding() {
entity.getNavigation().stop();
}
@Override
public boolean hasPath() {
return entity.getNavigation().getPath() != null && !entity.getNavigation().getPath().isDone();
}
@Nullable
@Override
public PathResult getCurrentPath() {
Path path = entity.getNavigation().getPath();
return path != null && !path.isDone() ? new PaperPathResult(path) : null;
}
@Nullable
@Override
public PathResult findPath(Location loc) {
Validate.notNull(loc, "Location can not be null");
Path path = entity.getNavigation().createPath(loc.getX(), loc.getY(), loc.getZ(), 0);
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().createPath(((CraftLivingEntity) target).getHandle(), 0);
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().moveTo(pathEntity, speed);
}
@Override
public boolean canOpenDoors() {
return entity.getNavigation().pathFinder.nodeEvaluator.canOpenDoors();
}
@Override
public void setCanOpenDoors(boolean canOpenDoors) {
entity.getNavigation().pathFinder.nodeEvaluator.setCanOpenDoors(canOpenDoors);
}
@Override
public boolean canPassDoors() {
return entity.getNavigation().pathFinder.nodeEvaluator.canPassDoors();
}
@Override
public void setCanPassDoors(boolean canPassDoors) {
entity.getNavigation().pathFinder.nodeEvaluator.setCanPassDoors(canPassDoors);
}
@Override
public boolean canFloat() {
return entity.getNavigation().pathFinder.nodeEvaluator.canFloat();
}
@Override
public void setCanFloat(boolean canFloat) {
entity.getNavigation().pathFinder.nodeEvaluator.setCanFloat(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.getEndNode();
return point != null ? toLoc(point) : null;
}
@Override
public boolean canReachFinalPoint() {
return path.canReach();
}
@Override
public List<Location> getPoints() {
List<Location> points = new ArrayList<>();
for (Node point : path.nodes) {
points.add(toLoc(point));
}
return points;
}
@Override
public int getNextPointIndex() {
return path.getNextNodeIndex();
}
@Nullable
@Override
public Location getNextPoint() {
if (!path.hasNext()) {
return null;
}
return toLoc(path.nodes.get(path.getNextNodeIndex()));
}
}
private Location toLoc(Node point) {
return new Location(entity.level().getWorld(), point.x, point.y, point.z);
}
}

View file

@ -14,8 +14,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 - Mob Pathfinding API
}
private final com.destroystokyo.paper.entity.PaperPathfinder paperPathfinder; // Paper - Mob Pathfinding API
@Override public com.destroystokyo.paper.entity.Pathfinder getPathfinder() { return paperPathfinder; } // Paper - Mob Pathfinding API
@Override
public void setTarget(LivingEntity target) {
Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation");
@ -56,6 +59,14 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
return (net.minecraft.world.entity.Mob) this.entity;
}
// Paper start - Mob Pathfinding API
@Override
public void setHandle(net.minecraft.world.entity.Entity entity) {
super.setHandle(entity);
paperPathfinder.setHandle(getHandle());
}
// Paper end - Mob Pathfinding API
@Override
public String toString() {
return "CraftMob";