finish moving away from betterblockpos in path calculation
This commit is contained in:
parent
7fa6e001e6
commit
23c11a5170
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user