Skip to content

Commit

Permalink
Add new pathfinding APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
fullwall committed Jul 25, 2016
1 parent cb5cd12 commit 88a5945
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 25 deletions.
32 changes: 32 additions & 0 deletions src/main/java/net/citizensnpcs/api/ai/AbstractPathStrategy.java
@@ -0,0 +1,32 @@
package net.citizensnpcs.api.ai;

import net.citizensnpcs.api.ai.TargetType;
import net.citizensnpcs.api.ai.event.CancelReason;

public abstract class AbstractPathStrategy implements PathStrategy {
private CancelReason cancelReason;
private final TargetType type;

protected AbstractPathStrategy(TargetType type) {
this.type = type;
}

@Override
public void clearCancelReason() {
cancelReason = null;
}

@Override
public CancelReason getCancelReason() {
return cancelReason;
}

@Override
public TargetType getTargetType() {
return type;
}

protected void setCancelReason(CancelReason reason) {
cancelReason = reason;
}
}
6 changes: 6 additions & 0 deletions src/main/java/net/citizensnpcs/api/ai/Navigator.java
Expand Up @@ -45,6 +45,12 @@ public interface Navigator {
*/
NPC getNPC();

/**
*
* @return The current {@link PathStrategy} or null if the navigator is not pathfinding
*/
PathStrategy getPathStrategy();

/**
* Returns the current {@link Location} being navigated towards - this is not necessarily permanent and may change,
* for example when pathing towards a moving {@link Entity}. May return null.
Expand Down
49 changes: 49 additions & 0 deletions src/main/java/net/citizensnpcs/api/ai/PathStrategy.java
@@ -0,0 +1,49 @@
package net.citizensnpcs.api.ai;

import org.bukkit.Location;
import org.bukkit.util.Vector;

import net.citizensnpcs.api.ai.event.CancelReason;

/**
* A pathfinding strategy directed at a target. Has two states: pathfinding -> cancelled represented by
* {@link #getCancelReason()}.
*/
public interface PathStrategy {
/**
* Clears the CancelReason returned by {@link #getCancelReason()} and attempts to resume pathfinding.
*/
void clearCancelReason();

/**
* @return The reason for the pathfinding to stop, or null if it is still continuing.
*/
CancelReason getCancelReason();

/**
* @return A copy of the current path, if any
*/
Iterable<Vector> getPath();

/**
* @return Gets the target destination location
*/
Location getTargetAsLocation();

/**
* @return The {@link TargetType} of this strategy
*/
TargetType getTargetType();

/**
* Forcibly stops pathfinding. Note that this method does not necessarily set the cancel reason.
*/
void stop();

/**
* Updates and runs the pathfinding strategy on its current NPC and destination.
*
* @return Whether pathfinding has completed
*/
boolean update();
}
@@ -0,0 +1,7 @@
package net.citizensnpcs.api.astar.pathfinder;

import java.util.List;

public interface NeighbourGeneratorBlockExaminer extends BlockExaminer {
public List<PathPoint> getNeighbours(BlockSource source, PathPoint point);
}
27 changes: 17 additions & 10 deletions src/main/java/net/citizensnpcs/api/astar/pathfinder/Path.java
Expand Up @@ -4,11 +4,6 @@
import java.util.List;
import java.util.ListIterator;

import net.citizensnpcs.api.astar.Agent;
import net.citizensnpcs.api.astar.Plan;
import net.citizensnpcs.api.astar.pathfinder.PathPoint.PathCallback;
import net.citizensnpcs.api.npc.NPC;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
Expand All @@ -17,8 +12,14 @@
import org.bukkit.util.Vector;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import net.citizensnpcs.api.astar.Agent;
import net.citizensnpcs.api.astar.Plan;
import net.citizensnpcs.api.astar.pathfinder.PathPoint.PathCallback;
import net.citizensnpcs.api.npc.NPC;

public class Path implements Plan {
private int index = 0;
private final PathEntry[] path;
Expand Down Expand Up @@ -58,6 +59,15 @@ public Vector getCurrentVector() {
return path[index].vector;
}

public Iterable<Vector> getPath() {
return Iterables.transform(Arrays.asList(path), new Function<PathEntry, Vector>() {
@Override
public Vector apply(PathEntry input) {
return input.vector;
}
});
}

@Override
public boolean isComplete() {
return index >= path.length;
Expand Down Expand Up @@ -100,11 +110,8 @@ public void run(final NPC npc) {
ListIterator<Block> vec = Lists.transform(Arrays.asList(path), new Function<PathEntry, Block>() {
@Override
public Block apply(PathEntry input) {
return npc
.getEntity()
.getWorld()
.getBlockAt(input.vector.getBlockX(), input.vector.getBlockY(),
input.vector.getBlockZ());
return npc.getEntity().getWorld().getBlockAt(input.vector.getBlockX(),
input.vector.getBlockY(), input.vector.getBlockZ());
}
}).listIterator();
if (index > 0) {
Expand Down
Expand Up @@ -2,14 +2,16 @@

import java.util.ListIterator;

import net.citizensnpcs.api.npc.NPC;

import org.bukkit.block.Block;
import org.bukkit.util.Vector;

import net.citizensnpcs.api.npc.NPC;

public interface PathPoint {
void addCallback(PathCallback callback);

PathPoint createAtOffset(Vector vector);

Vector getGoal();

PathPoint getParentPoint();
Expand Down
44 changes: 31 additions & 13 deletions src/main/java/net/citizensnpcs/api/astar/pathfinder/VectorNode.java
Expand Up @@ -2,15 +2,15 @@

import java.util.List;

import net.citizensnpcs.api.astar.AStarNode;
import net.citizensnpcs.api.astar.Plan;
import net.citizensnpcs.api.astar.pathfinder.BlockExaminer.PassableState;

import org.bukkit.Location;
import org.bukkit.util.Vector;

import com.google.common.collect.Lists;

import net.citizensnpcs.api.astar.AStarNode;
import net.citizensnpcs.api.astar.Plan;
import net.citizensnpcs.api.astar.pathfinder.BlockExaminer.PassableState;

public class VectorNode extends AStarNode implements PathPoint {
private float blockCost = -1;
private final BlockSource blockSource;
Expand Down Expand Up @@ -44,6 +44,11 @@ public Plan buildPlan() {
return new Path(parents);
}

@Override
public VectorNode createAtOffset(Vector mod) {
return new VectorNode(goal, mod, blockSource, examiners);
}

public float distance(VectorNode to) {
return (float) location.distance(to.location);
}
Expand Down Expand Up @@ -84,7 +89,27 @@ public Vector getGoal() {

@Override
public Iterable<AStarNode> getNeighbours() {
List<PathPoint> neighbours = null;
for (BlockExaminer examiner : examiners) {
if (examiner instanceof NeighbourGeneratorBlockExaminer) {
neighbours = ((NeighbourGeneratorBlockExaminer) examiner).getNeighbours(blockSource, this);
break;
}
}
if (neighbours == null) {
neighbours = getNeighbours(blockSource, this);
}
List<AStarNode> nodes = Lists.newArrayList();
for (PathPoint sub : neighbours) {
if (!isPassable(sub))
continue;
nodes.add((AStarNode) sub);
}
return nodes;
}

public List<PathPoint> getNeighbours(BlockSource source, PathPoint point) {
List<PathPoint> neighbours = Lists.newArrayList();
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
for (int z = -1; z <= 1; z++) {
Expand All @@ -95,18 +120,11 @@ public Iterable<AStarNode> getNeighbours() {
Vector mod = location.clone().add(new Vector(x, y, z));
if (mod.equals(location))
continue;
VectorNode sub = getNewNode(mod);
if (!isPassable(sub))
continue;
nodes.add(sub);
neighbours.add(point.createAtOffset(mod));
}
}
}
return nodes;
}

private VectorNode getNewNode(Vector mod) {
return new VectorNode(goal, mod, blockSource, examiners);
return neighbours;
}

@Override
Expand Down

0 comments on commit 88a5945

Please sign in to comment.