diff --git a/src/main/java/baritone/bot/pathing/calc/AbstractNodeCostSearch.java b/src/main/java/baritone/bot/pathing/calc/AbstractNodeCostSearch.java new file mode 100644 index 00000000..6943fc55 --- /dev/null +++ b/src/main/java/baritone/bot/pathing/calc/AbstractNodeCostSearch.java @@ -0,0 +1,74 @@ +package baritone.bot.pathing.calc; + +import baritone.bot.pathing.goals.Goal; +import net.minecraft.util.math.BlockPos; + +import java.util.HashMap; + +public abstract class AbstractNodeCostSearch implements IPathFinder { + + //TODO this shouldn't be necessary!! + public static AbstractNodeCostSearch currentlyRunning = null; + + + protected final BlockPos start; + protected final Goal goal; + protected final HashMap map; + protected PathNode startNode; + protected PathNode mostRecentConsidered; + protected PathNode[] bestSoFar; + private volatile boolean isFinished; + + /** + * This is really complicated and hard to explain. I wrote a comment in the old version of MineBot but it was so + * long it was easier as a Google Doc (because I could insert charts). + * https://docs.google.com/document/d/1WVHHXKXFdCR1Oz__KtK8sFqyvSwJN_H4lftkHFgmzlc/edit + */ + protected static final double[] COEFFICIENTS = {1.5, 2, 2.5, 3, 4, 5, 10}; + + public AbstractNodeCostSearch(BlockPos start, Goal goal) { + this.start = start; + this.goal = goal; + this.map = new HashMap<>(); + } + + public synchronized IPath calculatePath() { + if (isFinished) { + throw new IllegalStateException("Unable to re-use path finder"); + } + IPath path = calculate(); + isFinished = true; + return path; + } + + protected abstract IPath calculate(); + + @Override + public boolean isFinished() { + return isFinished; + } + + @Override + public Goal getGoal() { + return goal; + } + + @Override + public BlockPos getStart() { + return start; + } + + + @Override + public Path bestPathSoFar() { + if (startNode == null || bestSoFar[0] == null) { + return null; + } + return new Path(startNode, bestSoFar[0], goal); + } + + @Override + public Path pathToMostRecentNodeConsidered() { + return mostRecentConsidered == null ? null : new Path(startNode, mostRecentConsidered, goal); + } +} diff --git a/src/main/java/baritone/bot/pathing/calc/IPathFinder.java b/src/main/java/baritone/bot/pathing/calc/IPathFinder.java new file mode 100644 index 00000000..2e366850 --- /dev/null +++ b/src/main/java/baritone/bot/pathing/calc/IPathFinder.java @@ -0,0 +1,42 @@ +package baritone.bot.pathing.calc; + +import baritone.bot.pathing.goals.Goal; +import net.minecraft.util.math.BlockPos; + +public interface IPathFinder { + BlockPos getStart(); + + Goal getGoal(); + + /** + * Calculate the path in full. Will take several seconds. + * + * @return the final path + */ + IPath calculatePath(); + + /** + * Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet + * + * @return + */ + boolean isFinished(); + + /** + * Called for path rendering. Returns a path to the most recent node popped from the open set and considered. + * + * @return the temporary path + */ + IPath pathToMostRecentNodeConsidered(); + + /** + * The best path so far, according to the most forgiving coefficient heuristic (the reason being that that path is + * most likely to represent the true shape of the path to the goal, assuming it's within a possible cost heuristic. + * That's almost always a safe assumption, but in the case of a nearly impossible path, it still works by providing + * a theoretically plausible but practically unlikely path) + * + * @return the temporary path + */ + IPath bestPathSoFar(); + +}