Pathing code cleanups, javadoc updates, etc.
This commit is contained in:
@@ -4,19 +4,29 @@ import baritone.bot.pathing.goals.Goal;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class AbstractNodeCostSearch implements IPathFinder {
|
public abstract class AbstractNodeCostSearch implements IPathFinder {
|
||||||
|
|
||||||
//TODO this shouldn't be necessary!!
|
/**
|
||||||
|
* The currently running search task
|
||||||
|
*
|
||||||
|
* TODO: This shouldn't be necessary, investigate old purpose of this field and determine necessity.
|
||||||
|
*/
|
||||||
public static AbstractNodeCostSearch currentlyRunning = null;
|
public static AbstractNodeCostSearch currentlyRunning = null;
|
||||||
|
|
||||||
|
|
||||||
protected final BlockPos start;
|
protected final BlockPos start;
|
||||||
|
|
||||||
protected final Goal goal;
|
protected final Goal goal;
|
||||||
protected final HashMap<BlockPos, PathNode> map;
|
|
||||||
|
protected final Map<BlockPos, PathNode> map;
|
||||||
|
|
||||||
protected PathNode startNode;
|
protected PathNode startNode;
|
||||||
|
|
||||||
protected PathNode mostRecentConsidered;
|
protected PathNode mostRecentConsidered;
|
||||||
|
|
||||||
protected PathNode[] bestSoFar;
|
protected PathNode[] bestSoFar;
|
||||||
|
|
||||||
private volatile boolean isFinished;
|
private volatile boolean isFinished;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,38 +47,58 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
this.map = new HashMap<>();
|
this.map = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized IPath calculatePath() {
|
public synchronized IPath calculate() {
|
||||||
if (isFinished) {
|
if (isFinished) {
|
||||||
throw new IllegalStateException("Unable to re-use path finder");
|
throw new IllegalStateException("Path Finder is currently in use! Wait until complete to reuse!");
|
||||||
}
|
}
|
||||||
IPath path = calculate();
|
IPath path = calculate0();
|
||||||
isFinished = true;
|
isFinished = true;
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract IPath calculate();
|
protected abstract IPath calculate0();
|
||||||
|
|
||||||
protected double distFromStart(PathNode n) {
|
/**
|
||||||
|
* Determines the distance squared from the specified node to the start
|
||||||
|
* node. Intended for use in distance comparison, rather than anything that
|
||||||
|
* considers the real distance value, hence the "sq".
|
||||||
|
*
|
||||||
|
* @see AbstractNodeCostSearch#getDistFromStart(PathNode)
|
||||||
|
*
|
||||||
|
* @param n A node
|
||||||
|
* @return The distance, squared
|
||||||
|
*/
|
||||||
|
protected double getDistFromStartSq(PathNode n) {
|
||||||
int xDiff = n.pos.getX() - start.getX();
|
int xDiff = n.pos.getX() - start.getX();
|
||||||
int yDiff = n.pos.getY() - start.getY();
|
int yDiff = n.pos.getY() - start.getY();
|
||||||
int zDiff = n.pos.getZ() - start.getZ();
|
int zDiff = n.pos.getZ() - start.getZ();
|
||||||
return Math.sqrt(xDiff * xDiff + yDiff * yDiff + zDiff * zDiff);
|
return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the distance from the specified node to this the node.
|
||||||
|
*
|
||||||
|
* @param n A node
|
||||||
|
* @return The distance
|
||||||
|
*/
|
||||||
|
protected double getDistFromStart(PathNode n) {
|
||||||
|
return Math.sqrt(getDistFromStartSq(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to search the {@link BlockPos} to {@link PathNode} map
|
||||||
|
* for the node mapped to the specified pos. If no node is found,
|
||||||
|
* a new node is created.
|
||||||
|
*
|
||||||
|
* @param pos The pos to lookup
|
||||||
|
* @return The associated node
|
||||||
|
*/
|
||||||
protected PathNode getNodeAtPosition(BlockPos pos) {
|
protected PathNode getNodeAtPosition(BlockPos pos) {
|
||||||
//technically I think this could be map.computeIfAbsent(pos, pos -> new PathNode(pos, goal))
|
return map.computeIfAbsent(pos, p -> new PathNode(p, goal));
|
||||||
//but this is so core to the pathfinder that I'm wary of the lambda performance, hmmm
|
|
||||||
PathNode alr = map.get(pos);
|
|
||||||
if (alr == null) {
|
|
||||||
PathNode node = new PathNode(pos, goal);
|
|
||||||
map.put(pos, node);
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
return alr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path bestPathSoFar() {
|
public IPath bestPathSoFar() {
|
||||||
if (startNode == null || bestSoFar[0] == null) {
|
if (startNode == null || bestSoFar[0] == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -76,7 +106,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Path pathToMostRecentNodeConsidered() {
|
public IPath pathToMostRecentNodeConsidered() {
|
||||||
return mostRecentConsidered == null ? null : new Path(startNode, mostRecentConsidered, goal);
|
return mostRecentConsidered == null ? null : new Path(startNode, mostRecentConsidered, goal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -87,7 +87,7 @@ public interface IPath {
|
|||||||
*
|
*
|
||||||
* @return an unordered collection of positions
|
* @return an unordered collection of positions
|
||||||
*/
|
*/
|
||||||
Collection<BlockPos> getBlocksToMine();
|
Collection<BlockPos> getBlocksToBreak();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For rendering purposes, what blocks should be highlighted in green
|
* For rendering purposes, what blocks should be highlighted in green
|
||||||
|
@@ -4,6 +4,7 @@ import baritone.bot.pathing.goals.Goal;
|
|||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public interface IPathFinder {
|
public interface IPathFinder {
|
||||||
|
|
||||||
BlockPos getStart();
|
BlockPos getStart();
|
||||||
|
|
||||||
Goal getGoal();
|
Goal getGoal();
|
||||||
@@ -11,21 +12,21 @@ public interface IPathFinder {
|
|||||||
/**
|
/**
|
||||||
* Calculate the path in full. Will take several seconds.
|
* Calculate the path in full. Will take several seconds.
|
||||||
*
|
*
|
||||||
* @return the final path
|
* @return The final path
|
||||||
*/
|
*/
|
||||||
IPath calculatePath();
|
IPath calculate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet
|
* Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet
|
||||||
*
|
*
|
||||||
* @return
|
* @return Whether or not this finder is finished
|
||||||
*/
|
*/
|
||||||
boolean isFinished();
|
boolean isFinished();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called for path rendering. Returns a path to the most recent node popped from the open set and considered.
|
* Called for path rendering. Returns a path to the most recent node popped from the open set and considered.
|
||||||
*
|
*
|
||||||
* @return the temporary path
|
* @return The temporary path
|
||||||
*/
|
*/
|
||||||
IPath pathToMostRecentNodeConsidered();
|
IPath pathToMostRecentNodeConsidered();
|
||||||
|
|
||||||
@@ -35,8 +36,7 @@ public interface IPathFinder {
|
|||||||
* That's almost always a safe assumption, but in the case of a nearly impossible path, it still works by providing
|
* 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)
|
* a theoretically plausible but practically unlikely path)
|
||||||
*
|
*
|
||||||
* @return the temporary path
|
* @return The temporary path
|
||||||
*/
|
*/
|
||||||
IPath bestPathSoFar();
|
IPath bestPathSoFar();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -14,10 +14,19 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
class Path implements IPath {
|
class Path implements IPath {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The start position of this path
|
||||||
|
*/
|
||||||
public final BlockPos start;
|
public final BlockPos start;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The end position of this path
|
||||||
|
*/
|
||||||
public final BlockPos end;
|
public final BlockPos end;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The goal that this path is attempting to accomplish
|
||||||
|
*/
|
||||||
public final Goal goal;
|
public final Goal goal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,6 +47,12 @@ class Path implements IPath {
|
|||||||
sanityCheck();
|
sanityCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assembles this path given the start and end nodes.
|
||||||
|
*
|
||||||
|
* @param start The start node
|
||||||
|
* @param end The end node
|
||||||
|
*/
|
||||||
private void assemblePath(PathNode start, PathNode end) {
|
private void assemblePath(PathNode start, PathNode end) {
|
||||||
if (!path.isEmpty() || !movements.isEmpty()) {
|
if (!path.isEmpty() || !movements.isEmpty()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
@@ -95,7 +110,7 @@ class Path implements IPath {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<BlockPos> getBlocksToMine() {
|
public Collection<BlockPos> getBlocksToBreak() {
|
||||||
return movements.stream().map(move -> move.positionsToBreak).flatMap(Arrays::stream).collect(Collectors.toCollection(HashSet::new));
|
return movements.stream().map(move -> move.positionsToBreak).flatMap(Arrays::stream).collect(Collectors.toCollection(HashSet::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package baritone.bot.pathing.movement;
|
package baritone.bot.pathing.movement;
|
||||||
|
|
||||||
public interface ActionCosts {
|
public interface ActionCosts {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These costs are measured roughly in ticks btw
|
* These costs are measured roughly in ticks btw
|
||||||
* Blocks/Tick: 0.2806167m / tick
|
* Blocks/Tick: 0.2806167m / tick
|
||||||
|
@@ -15,18 +15,21 @@ import java.util.Optional;
|
|||||||
public abstract class Movement implements AbstractGameEventListener, Helper, MovementHelper {
|
public abstract class Movement implements AbstractGameEventListener, Helper, MovementHelper {
|
||||||
|
|
||||||
protected MovementState currentState;
|
protected MovementState currentState;
|
||||||
|
|
||||||
protected final BlockPos src;
|
protected final BlockPos src;
|
||||||
|
|
||||||
protected final BlockPos dest;
|
protected final BlockPos dest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The positions that need to be broken before this movement can ensue
|
* The positions that need to be broken before this movement can ensue
|
||||||
*/
|
*/
|
||||||
public final BlockPos[] positionsToBreak;
|
public final BlockPos[] positionsToBreak;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The positions where we need to place a block before this movement can ensue
|
* The positions where we need to place a block before this movement can ensue
|
||||||
*/
|
*/
|
||||||
public final BlockPos[] positionsToPlace;
|
public final BlockPos[] positionsToPlace;
|
||||||
|
|
||||||
|
|
||||||
protected Movement(BlockPos src, BlockPos dest, BlockPos[] toBreak, BlockPos[] toPlace) {
|
protected Movement(BlockPos src, BlockPos dest, BlockPos[] toBreak, BlockPos[] toPlace) {
|
||||||
this.src = src;
|
this.src = src;
|
||||||
this.dest = dest;
|
this.dest = dest;
|
||||||
|
@@ -14,28 +14,46 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
* @author leijurv
|
* @author leijurv
|
||||||
*/
|
*/
|
||||||
public interface MovementHelper extends ActionCosts {
|
public interface MovementHelper extends ActionCosts {
|
||||||
Block waterFlowing = Block.getBlockById(8);
|
|
||||||
Block waterStill = Block.getBlockById(9);
|
Block waterFlowing = Blocks.FLOWING_WATER;
|
||||||
Block lavaFlowing = Block.getBlockById(10);
|
Block waterStill = Blocks.WATER;
|
||||||
Block lavaStill = Block.getBlockById(11);
|
Block lavaFlowing = Blocks.FLOWING_LAVA;
|
||||||
|
Block lavaStill = Blocks.LAVA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this block water? Includes both still and flowing
|
* Returns whether or not the specified block is
|
||||||
|
* water, regardless of whether or not it is flowing.
|
||||||
*
|
*
|
||||||
* @param b
|
* @param b The block
|
||||||
* @return
|
* @return Whether or not the block is water
|
||||||
*/
|
*/
|
||||||
static boolean isWater(Block b) {
|
static boolean isWater(Block b) {
|
||||||
return waterFlowing.equals(b) || waterStill.equals(b);
|
return waterFlowing.equals(b) || waterStill.equals(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the block at the specified pos is
|
||||||
|
* water, regardless of whether or not it is flowing.
|
||||||
|
*
|
||||||
|
* @param bp The block pos
|
||||||
|
* @return Whether or not the block is water
|
||||||
|
*/
|
||||||
static boolean isWater(BlockPos bp) {
|
static boolean isWater(BlockPos bp) {
|
||||||
return isWater(BlockStateInterface.get(bp).getBlock());
|
return isWater(BlockStateInterface.get(bp).getBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the specified block is any sort of liquid.
|
||||||
|
*
|
||||||
|
* @param b The block
|
||||||
|
* @return Whether or not the block is a liquid
|
||||||
|
*/
|
||||||
static boolean isLiquid(Block b) {
|
static boolean isLiquid(Block b) {
|
||||||
return b instanceof BlockLiquid;
|
return b instanceof BlockLiquid;
|
||||||
//return b != null && (waterFlowing.equals(b) || waterStill.equals(b) || lavaFlowing.equals(b) || lavaStill.equals(b));
|
}
|
||||||
|
|
||||||
|
static boolean isLiquid(BlockPos p) {
|
||||||
|
return isLiquid(BlockStateInterface.get(p).getBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isFlowing(IBlockState state) {
|
static boolean isFlowing(IBlockState state) {
|
||||||
@@ -48,10 +66,6 @@ public interface MovementHelper extends ActionCosts {
|
|||||||
return lavaFlowing.equals(b) || lavaStill.equals(b);
|
return lavaFlowing.equals(b) || lavaStill.equals(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isLiquid(BlockPos p) {
|
|
||||||
return isLiquid(BlockStateInterface.get(p).getBlock());
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean avoidBreaking(BlockPos pos) {
|
static boolean avoidBreaking(BlockPos pos) {
|
||||||
Block b = BlockStateInterface.get(pos).getBlock();
|
Block b = BlockStateInterface.get(pos).getBlock();
|
||||||
Block below = BlockStateInterface.get(new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ())).getBlock();
|
Block below = BlockStateInterface.get(new BlockPos(pos.getX(), pos.getY() - 1, pos.getZ())).getBlock();
|
||||||
|
Reference in New Issue
Block a user