finish moving away from betterblockpos in path calculation

This commit is contained in:
Leijurv 2018-09-23 08:52:03 -07:00
parent 7fa6e001e6
commit 23c11a5170
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
17 changed files with 166 additions and 152 deletions

View File

@ -91,14 +91,12 @@ public final class CachedWorld implements Helper {
} }
} }
public final boolean isCached(BlockPos pos) { public final boolean isCached(int blockX, int blockZ) {
int x = pos.getX(); CachedRegion region = getRegion(blockX >> 9, blockZ >> 9);
int z = pos.getZ();
CachedRegion region = getRegion(x >> 9, z >> 9);
if (region == null) { if (region == null) {
return false; return false;
} }
return region.isCached(x & 511, z & 511); return region.isCached(blockX & 511, blockZ & 511);
} }
public final LinkedList<BlockPos> getLocationsOf(String block, int minimum, int maxRegionDistanceSq) { public final LinkedList<BlockPos> getLocationsOf(String block, int minimum, int maxRegionDistanceSq) {

View File

@ -35,6 +35,7 @@ import net.minecraft.util.math.BlockPos;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
/** /**
* The actual A* pathfinding * The actual A* pathfinding
@ -43,16 +44,16 @@ import java.util.Optional;
*/ */
public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper { public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
private final Optional<HashSet<BetterBlockPos>> favoredPositions; private final Optional<HashSet<Long>> favoredPositions;
public AStarPathFinder(BlockPos start, Goal goal, Optional<Collection<BetterBlockPos>> favoredPositions) { public AStarPathFinder(BlockPos start, Goal goal, Optional<Collection<BetterBlockPos>> favoredPositions) {
super(start, goal); super(start, goal);
this.favoredPositions = favoredPositions.map(HashSet::new); // <-- okay this is epic this.favoredPositions = favoredPositions.map(Collection::stream).map(x -> x.map(y -> y.hashCode)).map(x -> x.collect(Collectors.toList())).map(HashSet::new); // <-- okay this is EPIC
} }
@Override @Override
protected Optional<IPath> calculate0(long timeout) { protected Optional<IPath> calculate0(long timeout) {
startNode = getNodeAtPosition(start); startNode = getNodeAtPosition(start.x, start.y, start.z);
startNode.cost = 0; startNode.cost = 0;
startNode.combinedCost = startNode.estimatedCostToGoal; startNode.combinedCost = startNode.estimatedCostToGoal;
BinaryHeapOpenSet openSet = new BinaryHeapOpenSet(); BinaryHeapOpenSet openSet = new BinaryHeapOpenSet();
@ -65,7 +66,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
bestSoFar[i] = startNode; bestSoFar[i] = startNode;
} }
CalculationContext calcContext = new CalculationContext(); CalculationContext calcContext = new CalculationContext();
HashSet<BetterBlockPos> favored = favoredPositions.orElse(null); HashSet<Long> favored = favoredPositions.orElse(null);
CachedWorld cachedWorld = Optional.ofNullable(WorldProvider.INSTANCE.getCurrentWorld()).map(w -> w.cache).orElse(null); CachedWorld cachedWorld = Optional.ofNullable(WorldProvider.INSTANCE.getCurrentWorld()).map(w -> w.cache).orElse(null);
ChunkProviderClient chunkProvider = Minecraft.getMinecraft().world.getChunkProvider(); ChunkProviderClient chunkProvider = Minecraft.getMinecraft().world.getChunkProvider();
BlockStateInterface.clearCachedChunk(); BlockStateInterface.clearCachedChunk();
@ -94,43 +95,42 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
PathNode currentNode = openSet.removeLowest(); PathNode currentNode = openSet.removeLowest();
currentNode.isOpen = false; currentNode.isOpen = false;
mostRecentConsidered = currentNode; mostRecentConsidered = currentNode;
BetterBlockPos currentNodePos = currentNode.pos;
numNodes++; numNodes++;
if (goal.isInGoal(currentNodePos)) { if (goal.isInGoal(currentNode.x, currentNode.y, currentNode.z)) {
logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered"); logDebug("Took " + (System.nanoTime() / 1000000L - startTime) + "ms, " + numMovementsConsidered + " movements considered");
return Optional.of(new Path(startNode, currentNode, numNodes, goal)); return Optional.of(new Path(startNode, currentNode, numNodes, goal));
} }
for (Moves moves : Moves.values()) { for (Moves moves : Moves.values()) {
MoveResult res = moves.apply(calcContext, currentNodePos.x, currentNodePos.y, currentNodePos.z); int newX = currentNode.x + moves.xOffset;
numMovementsConsidered++; int newZ = currentNode.z + moves.zOffset;
double actionCost = res.cost; if (newX >> 4 != currentNode.x >> 4 || newZ >> 4 != currentNode.z >> 4) {
if (actionCost >= ActionCosts.COST_INF) {
continue;
}
BetterBlockPos dest = new BetterBlockPos(res.destX, res.destY, res.destZ);
int chunkX = currentNodePos.x >> 4;
int chunkZ = currentNodePos.z >> 4;
if (dest.x >> 4 != chunkX || dest.z >> 4 != chunkZ) {
// only need to check if the destination is a loaded chunk if it's in a different chunk than the start of the movement // only need to check if the destination is a loaded chunk if it's in a different chunk than the start of the movement
if (chunkProvider.isChunkGeneratedAt(chunkX, chunkZ)) { if (chunkProvider.isChunkGeneratedAt(newX >> 4, newZ >> 4)) { // TODO could also call BlockStateInterface here
// see issue #106 // see issue #106
if (cachedWorld == null || !cachedWorld.isCached(dest)) { if (cachedWorld == null || !cachedWorld.isCached(newX, newZ)) { // TODO isCached could call BlockStateInterface to skip a hashmap lookup
numEmptyChunk++; numEmptyChunk++;
continue; continue;
} }
} }
} }
MoveResult res = moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z);
if (res.destX != newX || res.destZ != newZ) {
throw new IllegalStateException(moves + " " + res.destX + " " + newX + " " + res.destZ + " " + newZ);
}
numMovementsConsidered++;
double actionCost = res.cost;
if (actionCost >= ActionCosts.COST_INF) { if (actionCost >= ActionCosts.COST_INF) {
continue; continue;
} }
if (actionCost <= 0) { if (actionCost <= 0) {
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost); throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
} }
if (favoring && favored.contains(dest)) { if (favoring && favored.contains(posHash(res.destX, res.destY, res.destZ))) {
// see issue #18 // see issue #18
actionCost *= favorCoeff; actionCost *= favorCoeff;
} }
PathNode neighbor = getNodeAtPosition(dest); PathNode neighbor = getNodeAtPosition(res.destX, res.destY, res.destZ);
double tentativeCost = currentNode.cost + actionCost; double tentativeCost = currentNode.cost + actionCost;
if (tentativeCost < neighbor.cost) { if (tentativeCost < neighbor.cost) {
if (tentativeCost < 0) { if (tentativeCost < 0) {

View File

@ -115,9 +115,9 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
* @return The distance, squared * @return The distance, squared
*/ */
protected double getDistFromStartSq(PathNode n) { protected double getDistFromStartSq(PathNode n) {
int xDiff = n.pos.x - start.x; int xDiff = n.x - start.x;
int yDiff = n.pos.y - start.y; int yDiff = n.y - start.y;
int zDiff = n.pos.z - start.z; int zDiff = n.z - start.z;
return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff; return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff;
} }
@ -126,20 +126,38 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
* for the node mapped to the specified pos. If no node is found, * for the node mapped to the specified pos. If no node is found,
* a new node is created. * a new node is created.
* *
* @param pos The pos to lookup
* @return The associated node * @return The associated node
* @see <a href="https://github.com/cabaletta/baritone/issues/107">Issue #107</a> * @see <a href="https://github.com/cabaletta/baritone/issues/107">Issue #107</a>
*/ */
protected PathNode getNodeAtPosition(BetterBlockPos pos) { protected PathNode getNodeAtPosition(int x, int y, int z) {
long hashCode = pos.hashCode; long hashCode = posHash(x, y, z);
PathNode node = map.get(hashCode); PathNode node = map.get(hashCode);
if (node == null) { if (node == null) {
node = new PathNode(pos, goal); node = new PathNode(x, y, z, goal);
map.put(hashCode, node); map.put(hashCode, node);
} }
return node; return node;
} }
public static long posHash(int x, int y, int z) {
/*
* This is the hashcode implementation of Vec3i, the superclass of BlockPos
*
* public int hashCode() {
* return (this.getY() + this.getZ() * 31) * 31 + this.getX();
* }
*
* That is terrible and has tons of collisions and makes the HashMap terribly inefficient.
*
* That's why we grab out the X, Y, Z and calculate our own hashcode
*/
long hash = 3241;
hash = 3457689L * hash + x;
hash = 8734625L * hash + y;
hash = 2873465L * hash + z;
return hash;
}
public static void forceCancel() { public static void forceCancel() {
PathingBehavior.INSTANCE.cancel(); PathingBehavior.INSTANCE.cancel();
currentlyRunning = null; currentlyRunning = null;

View File

@ -25,7 +25,7 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.Tuple; import net.minecraft.util.Tuple;
public enum Moves { public enum Moves {
DOWNWARD() { DOWNWARD(0, 0) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { // TODO specific return types protected Movement apply0(BetterBlockPos src) { // TODO specific return types
return new MovementDownward(src, src.down()); return new MovementDownward(src, src.down());
@ -37,7 +37,7 @@ public enum Moves {
} }
}, },
PILLAR() { PILLAR(0, 0) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { // TODO specific return types protected Movement apply0(BetterBlockPos src) { // TODO specific return types
return new MovementPillar(src, src.up()); return new MovementPillar(src, src.up());
@ -49,7 +49,7 @@ public enum Moves {
} }
}, },
TRAVERSE_NORTH() { TRAVERSE_NORTH(0, -1) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementTraverse(src, src.north()); return new MovementTraverse(src, src.north());
@ -61,7 +61,7 @@ public enum Moves {
} }
}, },
TRAVERSE_SOUTH() { TRAVERSE_SOUTH(0, +1) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementTraverse(src, src.south()); return new MovementTraverse(src, src.south());
@ -73,7 +73,7 @@ public enum Moves {
} }
}, },
TRAVERSE_EAST() { TRAVERSE_EAST(+1, 0) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementTraverse(src, src.east()); return new MovementTraverse(src, src.east());
@ -85,7 +85,7 @@ public enum Moves {
} }
}, },
TRAVERSE_WEST() { TRAVERSE_WEST(-1, 0) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementTraverse(src, src.west()); return new MovementTraverse(src, src.west());
@ -97,7 +97,7 @@ public enum Moves {
} }
}, },
ASCEND_NORTH() { ASCEND_NORTH(0, -1) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementAscend(src, new BetterBlockPos(src.x, src.y + 1, src.z - 1)); return new MovementAscend(src, new BetterBlockPos(src.x, src.y + 1, src.z - 1));
@ -109,7 +109,7 @@ public enum Moves {
} }
}, },
ASCEND_SOUTH() { ASCEND_SOUTH(0, +1) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementAscend(src, new BetterBlockPos(src.x, src.y + 1, src.z + 1)); return new MovementAscend(src, new BetterBlockPos(src.x, src.y + 1, src.z + 1));
@ -121,7 +121,7 @@ public enum Moves {
} }
}, },
ASCEND_EAST() { ASCEND_EAST(+1, 0) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementAscend(src, new BetterBlockPos(src.x + 1, src.y + 1, src.z)); return new MovementAscend(src, new BetterBlockPos(src.x + 1, src.y + 1, src.z));
@ -129,11 +129,11 @@ public enum Moves {
@Override @Override
public MoveResult apply(CalculationContext context, int x, int y, int z) { public MoveResult apply(CalculationContext context, int x, int y, int z) {
return new MoveResult(x, y + 1, z + 1, MovementAscend.cost(context, x, y, z, x + 1, z)); return new MoveResult(x + 1, y + 1, z, MovementAscend.cost(context, x, y, z, x + 1, z));
} }
}, },
ASCEND_WEST() { ASCEND_WEST(-1, 0) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementAscend(src, new BetterBlockPos(src.x - 1, src.y + 1, src.z)); return new MovementAscend(src, new BetterBlockPos(src.x - 1, src.y + 1, src.z));
@ -141,11 +141,11 @@ public enum Moves {
@Override @Override
public MoveResult apply(CalculationContext context, int x, int y, int z) { public MoveResult apply(CalculationContext context, int x, int y, int z) {
return new MoveResult(x, y + 1, z - 1, MovementAscend.cost(context, x, y, z, x - 1, z)); return new MoveResult(x - 1, y + 1, z, MovementAscend.cost(context, x, y, z, x - 1, z));
} }
}, },
DESCEND_EAST() { DESCEND_EAST(+1, 0) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z); MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z);
@ -163,7 +163,7 @@ public enum Moves {
} }
}, },
DESCEND_WEST() { DESCEND_WEST(-1, 0) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z); MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z);
@ -181,7 +181,7 @@ public enum Moves {
} }
}, },
DESCEND_NORTH() { DESCEND_NORTH(0, -1) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z); MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z);
@ -199,7 +199,7 @@ public enum Moves {
} }
}, },
DESCEND_SOUTH() { DESCEND_SOUTH(0, +1) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z); MoveResult res = apply(new CalculationContext(), src.x, src.y, src.z);
@ -217,7 +217,7 @@ public enum Moves {
} }
}, },
DIAGONAL_NORTHEAST() { DIAGONAL_NORTHEAST(+1, -1) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementDiagonal(src, EnumFacing.NORTH, EnumFacing.EAST); return new MovementDiagonal(src, EnumFacing.NORTH, EnumFacing.EAST);
@ -229,7 +229,7 @@ public enum Moves {
} }
}, },
DIAGONAL_NORTHWEST() { DIAGONAL_NORTHWEST(-1, -1) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementDiagonal(src, EnumFacing.NORTH, EnumFacing.WEST); return new MovementDiagonal(src, EnumFacing.NORTH, EnumFacing.WEST);
@ -241,7 +241,7 @@ public enum Moves {
} }
}, },
DIAGONAL_SOUTHEAST() { DIAGONAL_SOUTHEAST(+1, +1) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementDiagonal(src, EnumFacing.SOUTH, EnumFacing.EAST); return new MovementDiagonal(src, EnumFacing.SOUTH, EnumFacing.EAST);
@ -253,7 +253,7 @@ public enum Moves {
} }
}, },
DIAGONAL_SOUTHWEST() { DIAGONAL_SOUTHWEST(-1, +1) {
@Override @Override
protected Movement apply0(BetterBlockPos src) { protected Movement apply0(BetterBlockPos src) {
return new MovementDiagonal(src, EnumFacing.SOUTH, EnumFacing.WEST); return new MovementDiagonal(src, EnumFacing.SOUTH, EnumFacing.WEST);
@ -271,4 +271,12 @@ public enum Moves {
public abstract MoveResult apply(CalculationContext context, int x, int y, int z); public abstract MoveResult apply(CalculationContext context, int x, int y, int z);
public final int xOffset;
public final int zOffset;
Moves(int x, int z) {
this.xOffset = x;
this.zOffset = z;
}
} }

View File

@ -60,8 +60,8 @@ class Path implements IPath {
private volatile boolean verified; private volatile boolean verified;
Path(PathNode start, PathNode end, int numNodes, Goal goal) { Path(PathNode start, PathNode end, int numNodes, Goal goal) {
this.start = start.pos; this.start = new BetterBlockPos(start.x, start.y, start.z);
this.end = end.pos; this.end = new BetterBlockPos(end.x, end.y, end.z);
this.numNodes = numNodes; this.numNodes = numNodes;
this.path = new ArrayList<>(); this.path = new ArrayList<>();
this.movements = new ArrayList<>(); this.movements = new ArrayList<>();
@ -88,11 +88,11 @@ class Path implements IPath {
LinkedList<BetterBlockPos> tempPath = new LinkedList<>(); // Repeatedly inserting to the beginning of an arraylist is O(n^2) LinkedList<BetterBlockPos> tempPath = new LinkedList<>(); // Repeatedly inserting to the beginning of an arraylist is O(n^2)
LinkedList<Movement> tempMovements = new LinkedList<>(); // Instead, do it into a linked list, then convert at the end LinkedList<Movement> tempMovements = new LinkedList<>(); // Instead, do it into a linked list, then convert at the end
while (!current.equals(start)) { while (!current.equals(start)) {
tempPath.addFirst(current.pos); tempPath.addFirst(new BetterBlockPos(current.x, current.y, current.z));
tempMovements.addFirst(runBackwards(current.previous.pos, current.pos)); tempMovements.addFirst(runBackwards(current.previous, current));
current = current.previous; current = current.previous;
} }
tempPath.addFirst(start.pos); tempPath.addFirst(this.start);
// Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is // Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
// inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able // inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
// to performantly do that conversion since it knows the length. // to performantly do that conversion since it knows the length.
@ -100,7 +100,9 @@ class Path implements IPath {
movements.addAll(tempMovements); movements.addAll(tempMovements);
} }
private static Movement runBackwards(BetterBlockPos src, BetterBlockPos dest) { // TODO this is horrifying private static Movement runBackwards(PathNode src0, PathNode dest0) { // TODO this is horrifying
BetterBlockPos src = new BetterBlockPos(src0.x, src0.y, src0.z);
BetterBlockPos dest = new BetterBlockPos(dest0.x, dest0.y, dest0.z);
for (Moves moves : Moves.values()) { for (Moves moves : Moves.values()) {
Movement move = moves.apply0(src); Movement move = moves.apply0(src);
if (move.getDest().equals(dest)) { if (move.getDest().equals(dest)) {

View File

@ -19,7 +19,6 @@ package baritone.pathing.calc;
import baritone.pathing.goals.Goal; import baritone.pathing.goals.Goal;
import baritone.pathing.movement.ActionCosts; import baritone.pathing.movement.ActionCosts;
import baritone.utils.pathing.BetterBlockPos;
/** /**
* A node in the path, containing the cost and steps to get to it. * A node in the path, containing the cost and steps to get to it.
@ -31,12 +30,9 @@ public final class PathNode {
/** /**
* The position of this node * The position of this node
*/ */
final BetterBlockPos pos; final int x;
final int y;
/** final int z;
* The goal it's going towards
*/
final Goal goal;
/** /**
* Cached, should always be equal to goal.heuristic(pos) * Cached, should always be equal to goal.heuristic(pos)
@ -72,13 +68,14 @@ public final class PathNode {
*/ */
public int heapPosition; public int heapPosition;
public PathNode(BetterBlockPos pos, Goal goal) { public PathNode(int x, int y, int z, Goal goal) {
this.pos = pos;
this.previous = null; this.previous = null;
this.cost = ActionCosts.COST_INF; this.cost = ActionCosts.COST_INF;
this.goal = goal; this.estimatedCostToGoal = goal.heuristic(x, y, z);
this.estimatedCostToGoal = goal.heuristic(pos);
this.isOpen = false; this.isOpen = false;
this.x = x;
this.y = y;
this.z = z;
} }
/** /**
@ -88,7 +85,7 @@ public final class PathNode {
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
return pos.hashCode() * 7 + 3; return (x * 935847 + y) * 239761 + z;
} }
@Override @Override
@ -100,8 +97,9 @@ public final class PathNode {
// return false; // return false;
//} //}
//final PathNode other = (PathNode) obj; final PathNode other = (PathNode) obj;
//return Objects.equals(this.pos, other.pos) && Objects.equals(this.goal, other.goal); //return Objects.equals(this.pos, other.pos) && Objects.equals(this.goal, other.goal);
return this.pos.equals(((PathNode) obj).pos);
return x == other.x && y == other.y && z == other.z;
} }
} }

View File

@ -31,16 +31,22 @@ public interface Goal extends ActionCosts {
* Returns whether or not the specified position * Returns whether or not the specified position
* meets the requirement for this goal based. * meets the requirement for this goal based.
* *
* @param pos The position
* @return Whether or not it satisfies this goal * @return Whether or not it satisfies this goal
*/ */
boolean isInGoal(BlockPos pos); boolean isInGoal(int x, int y, int z);
/** /**
* Estimate the number of ticks it will take to get to the goal * Estimate the number of ticks it will take to get to the goal
* *
* @param pos The
* @return The estimate number of ticks to satisfy the goal * @return The estimate number of ticks to satisfy the goal
*/ */
double heuristic(BlockPos pos); double heuristic(int x, int y, int z);
default boolean isInGoal(BlockPos pos) {
return isInGoal(pos.getX(), pos.getY(), pos.getZ());
}
default double heuristic(BlockPos pos) {
return heuristic(pos.getX(), pos.getY(), pos.getZ());
}
} }

View File

@ -18,25 +18,20 @@
package baritone.pathing.goals; package baritone.pathing.goals;
import baritone.Baritone; import baritone.Baritone;
import net.minecraft.util.math.BlockPos;
public class GoalAxis implements Goal { public class GoalAxis implements Goal {
private static final double SQRT_2_OVER_2 = Math.sqrt(2) / 2; private static final double SQRT_2_OVER_2 = Math.sqrt(2) / 2;
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
return y == Baritone.settings().axisHeight.get() && (x == 0 || z == 0 || Math.abs(x) == Math.abs(z)); return y == Baritone.settings().axisHeight.get() && (x == 0 || z == 0 || Math.abs(x) == Math.abs(z));
} }
@Override @Override
public double heuristic(BlockPos pos) { public double heuristic(int x0, int y, int z0) {
int x = Math.abs(pos.getX()); int x = Math.abs(x0);
int y = pos.getY(); int z = Math.abs(z0);
int z = Math.abs(pos.getZ());
int shrt = Math.min(x, z); int shrt = Math.min(x, z);
int lng = Math.max(x, z); int lng = Math.max(x, z);

View File

@ -53,15 +53,15 @@ public class GoalBlock implements Goal, IGoalRenderPos {
} }
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
return pos.getX() == this.x && pos.getY() == this.y && pos.getZ() == this.z; return x == this.x && y == this.y && z == this.z;
} }
@Override @Override
public double heuristic(BlockPos pos) { public double heuristic(int x, int y, int z) {
int xDiff = pos.getX() - this.x; int xDiff = x - this.x;
int yDiff = pos.getY() - this.y; int yDiff = y - this.y;
int zDiff = pos.getZ() - this.z; int zDiff = z - this.z;
return calculate(xDiff, yDiff, zDiff); return calculate(xDiff, yDiff, zDiff);
} }

View File

@ -49,15 +49,21 @@ public class GoalComposite implements Goal {
} }
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
return Arrays.stream(this.goals).anyMatch(goal -> goal.isInGoal(pos)); for (Goal goal : goals) {
if (goal.isInGoal(x, y, z)) {
return true;
}
}
return false;
} }
@Override @Override
public double heuristic(BlockPos pos) { public double heuristic(int x, int y, int z) {
double min = Double.MAX_VALUE; double min = Double.MAX_VALUE;
for (Goal g : goals) { for (Goal g : goals) {
min = Math.min(min, g.heuristic(pos)); // whichever is closest // TODO technically this isn't admissible...?
min = Math.min(min, g.heuristic(x, y, z)); // whichever is closest
} }
return min; return min;
} }

View File

@ -45,10 +45,10 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
} }
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
int xDiff = pos.getX() - this.x; int xDiff = x - this.x;
int yDiff = pos.getY() - this.y; int yDiff = y - this.y;
int zDiff = pos.getZ() - this.z; int zDiff = z - this.z;
if (yDiff < 0) { if (yDiff < 0) {
yDiff++; yDiff++;
} }
@ -56,10 +56,10 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
} }
@Override @Override
public double heuristic(BlockPos pos) { public double heuristic(int x, int y, int z) {
int xDiff = pos.getX() - this.x; int xDiff = x - this.x;
int yDiff = pos.getY() - this.y; int yDiff = y - this.y;
int zDiff = pos.getZ() - this.z; int zDiff = z - this.z;
return GoalBlock.calculate(xDiff, yDiff, zDiff); return GoalBlock.calculate(xDiff, yDiff, zDiff);
} }

View File

@ -34,19 +34,19 @@ public class GoalNear implements Goal, IGoalRenderPos {
} }
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
int diffX = x - pos.getX(); int xDiff = x - this.x;
int diffY = y - pos.getY(); int yDiff = y - this.y;
int diffZ = z - pos.getZ(); int zDiff = z - this.z;
return diffX * diffX + diffY * diffY + diffZ * diffZ <= rangeSq; return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff <= rangeSq;
} }
@Override @Override
public double heuristic(BlockPos pos) { public double heuristic(int x, int y, int z) {
int diffX = x - pos.getX(); int xDiff = x - this.x;
int diffY = y - pos.getY(); int yDiff = y - this.y;
int diffZ = z - pos.getZ(); int zDiff = z - this.z;
return GoalBlock.calculate(diffX, diffY, diffZ); return GoalBlock.calculate(xDiff, yDiff, zDiff);
} }
@Override @Override

View File

@ -41,10 +41,10 @@ public class GoalRunAway implements Goal {
} }
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
for (BlockPos p : from) { for (BlockPos p : from) {
int diffX = pos.getX() - p.getX(); int diffX = x - p.getX();
int diffZ = pos.getZ() - p.getZ(); int diffZ = z - p.getZ();
double distSq = diffX * diffX + diffZ * diffZ; double distSq = diffX * diffX + diffZ * diffZ;
if (distSq < distanceSq) { if (distSq < distanceSq) {
return false; return false;
@ -54,10 +54,10 @@ public class GoalRunAway implements Goal {
} }
@Override @Override
public double heuristic(BlockPos pos) {//mostly copied from GoalBlock public double heuristic(int x, int y, int z) {//mostly copied from GoalBlock
double min = Double.MAX_VALUE; double min = Double.MAX_VALUE;
for (BlockPos p : from) { for (BlockPos p : from) {
double h = GoalXZ.calculate(p.getX() - pos.getX(), p.getZ() - pos.getZ()); double h = GoalXZ.calculate(p.getX() - x, p.getZ() - z);
if (h < min) { if (h < min) {
min = h; min = h;
} }

View File

@ -54,18 +54,18 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
} }
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
return pos.getX() == this.x && (pos.getY() == this.y || pos.getY() == this.y - 1) && pos.getZ() == this.z; return x == this.x && (y == this.y || y == this.y - 1) && z == this.z;
} }
@Override @Override
public double heuristic(BlockPos pos) { public double heuristic(int x, int y, int z) {
double xDiff = pos.getX() - this.x; int xDiff = x - this.x;
int yDiff = pos.getY() - this.y; int yDiff = y - this.y;
int zDiff = z - this.z;
if (yDiff < 0) { if (yDiff < 0) {
yDiff++; yDiff++;
} }
double zDiff = pos.getZ() - this.z;
return GoalBlock.calculate(xDiff, yDiff, zDiff); return GoalBlock.calculate(xDiff, yDiff, zDiff);
} }

View File

@ -19,7 +19,6 @@ package baritone.pathing.goals;
import baritone.Baritone; import baritone.Baritone;
import baritone.utils.Utils; import baritone.utils.Utils;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -48,14 +47,14 @@ public class GoalXZ implements Goal {
} }
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
return pos.getX() == x && pos.getZ() == z; return x == this.x && z == this.z;
} }
@Override @Override
public double heuristic(BlockPos pos) {//mostly copied from GoalBlock public double heuristic(int x, int y, int z) {//mostly copied from GoalBlock
double xDiff = pos.getX() - this.x; int xDiff = x - this.x;
double zDiff = pos.getZ() - this.z; int zDiff = z - this.z;
return calculate(xDiff, zDiff); return calculate(xDiff, zDiff);
} }

View File

@ -17,8 +17,6 @@
package baritone.pathing.goals; package baritone.pathing.goals;
import net.minecraft.util.math.BlockPos;
/** /**
* Useful for mining (getting to diamond / iron level) * Useful for mining (getting to diamond / iron level)
* *
@ -36,13 +34,13 @@ public class GoalYLevel implements Goal {
} }
@Override @Override
public boolean isInGoal(BlockPos pos) { public boolean isInGoal(int x, int y, int z) {
return pos.getY() == level; return y == level;
} }
@Override @Override
public double heuristic(BlockPos pos) { public double heuristic(int x, int y, int z) {
return calculate(level, pos.getY()); return calculate(level, y);
} }
public static double calculate(int goalY, int currentY) { public static double calculate(int goalY, int currentY) {

View File

@ -17,6 +17,7 @@
package baritone.utils.pathing; package baritone.utils.pathing;
import baritone.pathing.calc.AbstractNodeCostSearch;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
@ -42,22 +43,7 @@ public final class BetterBlockPos extends BlockPos {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
/* this.hashCode = AbstractNodeCostSearch.posHash(x, y, z);
* This is the hashcode implementation of Vec3i, the superclass of BlockPos
*
* public int hashCode() {
* return (this.getY() + this.getZ() * 31) * 31 + this.getX();
* }
*
* That is terrible and has tons of collisions and makes the HashMap terribly inefficient.
*
* That's why we grab out the X, Y, Z and calculate our own hashcode
*/
long hash = 3241;
hash = 3457689L * hash + x;
hash = 8734625L * hash + y;
hash = 2873465L * hash + z;
this.hashCode = hash;
} }
public BetterBlockPos(double x, double y, double z) { public BetterBlockPos(double x, double y, double z) {