better path splicing
This commit is contained in:
parent
399fa003dd
commit
e0f2159276
@ -35,17 +35,22 @@ public class Settings {
|
||||
public Setting<Boolean> chuckCaching = new Setting<>(false);
|
||||
public Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
|
||||
public Setting<Integer> planningTickLookAhead = new Setting<>(150);
|
||||
public Setting<Boolean> renderPath = new Setting<>(true);
|
||||
public Setting<Boolean> chatDebug = new Setting<>(true);
|
||||
public Setting<Boolean> chatControl = new Setting<>(true); // probably false in impact
|
||||
public Setting<Boolean> renderPath = new Setting<>(true);
|
||||
public Setting<Boolean> fadePath = new Setting<>(false); // give this a better name in the UI, like "better path fps" idk
|
||||
public Setting<Number> pathTimeoutMS = new Setting<>(4000L);
|
||||
public Setting<Boolean> slowPath = new Setting<>(false);
|
||||
public Setting<Number> slowPathTimeDelayMS = new Setting<>(100L);
|
||||
public Setting<Number> slowPathTimeoutMS = new Setting<>(40000L);
|
||||
public Setting<List<Item>> acceptableThrowAwayItems = new Setting<>(Arrays.asList(
|
||||
Item.getItemFromBlock(Blocks.DIRT),
|
||||
Item.getItemFromBlock(Blocks.COBBLESTONE),
|
||||
Item.getItemFromBlock(Blocks.NETHERRACK)
|
||||
));
|
||||
public Setting<Boolean> renderGoal = new Setting<>(true);
|
||||
public Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
|
||||
public Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.9);
|
||||
|
||||
public final Map<String, Setting<?>> byName;
|
||||
public final List<Setting<?>> allSettings;
|
||||
@ -63,8 +68,8 @@ public class Settings {
|
||||
this.klass = (Class<T>) value.getClass();
|
||||
}
|
||||
|
||||
public final T get() {
|
||||
return value;
|
||||
public final <K extends T> K get() {
|
||||
return (K) value;
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
|
@ -93,7 +93,7 @@ public class PathingBehavior extends Behavior {
|
||||
// if we aren't calculating right now
|
||||
return;
|
||||
}
|
||||
findPathInNewThread(playerFeet(), true);
|
||||
findPathInNewThread(playerFeet(), true, Optional.empty());
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -126,7 +126,7 @@ public class PathingBehavior extends Behavior {
|
||||
if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) {
|
||||
// and this path has 5 seconds or less left
|
||||
displayChatMessageRaw("Path almost over. Planning ahead...");
|
||||
findPathInNewThread(current.getPath().getDest(), false);
|
||||
findPathInNewThread(current.getPath().getDest(), false, Optional.of(current.getPath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -160,11 +160,17 @@ public class PathingBehavior extends Behavior {
|
||||
}
|
||||
|
||||
public void path() {
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
synchronized (pathPlanLock) {
|
||||
if (current != null) {
|
||||
displayChatMessageRaw("Currently executing a path. Please cancel it first.");
|
||||
return;
|
||||
}
|
||||
findPathInNewThread(playerFeet(), true);
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
return;
|
||||
}
|
||||
findPathInNewThread(playerFeet(), true, Optional.empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,7 +180,7 @@ public class PathingBehavior extends Behavior {
|
||||
* @param start
|
||||
* @param talkAboutIt
|
||||
*/
|
||||
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt) {
|
||||
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt, final Optional<IPath> previous) {
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
throw new IllegalStateException("Already doing it");
|
||||
@ -186,7 +192,7 @@ public class PathingBehavior extends Behavior {
|
||||
displayChatMessageRaw("Starting to search for path from " + start + " to " + goal);
|
||||
}
|
||||
|
||||
findPath(start).map(IPath::cutoffAtLoadedChunks).map(PathExecutor::new).ifPresent(path -> {
|
||||
findPath(start, previous).map(IPath::cutoffAtLoadedChunks).map(PathExecutor::new).ifPresent(path -> {
|
||||
synchronized (pathPlanLock) {
|
||||
if (current == null) {
|
||||
current = path;
|
||||
@ -219,13 +225,13 @@ public class PathingBehavior extends Behavior {
|
||||
* @param start
|
||||
* @return
|
||||
*/
|
||||
private Optional<IPath> findPath(BlockPos start) {
|
||||
private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous) {
|
||||
if (goal == null) {
|
||||
displayChatMessageRaw("no goal");
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
IPathFinder pf = new AStarPathFinder(start, goal);
|
||||
IPathFinder pf = new AStarPathFinder(start, goal, previous.map(IPath::positions));
|
||||
return pf.calculate();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@ -251,6 +257,7 @@ public class PathingBehavior extends Behavior {
|
||||
PathExecutor current = this.current; // this should prevent most race conditions?
|
||||
PathExecutor next = this.next; // like, now it's not possible for current!=null to be true, then suddenly false because of another thread
|
||||
// TODO is this enough, or do we need to acquire a lock here?
|
||||
// TODO benchmark synchronized in render loop
|
||||
|
||||
// Render the current path, if there is one
|
||||
if (current != null && current.getPath() != null) {
|
||||
|
@ -52,6 +52,8 @@ import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.chunk.EmptyChunk;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
@ -62,8 +64,11 @@ import java.util.Random;
|
||||
*/
|
||||
public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||
|
||||
public AStarPathFinder(BlockPos start, Goal goal) {
|
||||
private final Optional<HashSet<BetterBlockPos>> favoredPositions;
|
||||
|
||||
public AStarPathFinder(BlockPos start, Goal goal, Optional<Collection<BetterBlockPos>> favoredPositions) {
|
||||
super(start, goal);
|
||||
this.favoredPositions = favoredPositions.map(HashSet::new); // <-- okay this is epic
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -72,26 +77,30 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||
startNode.cost = 0;
|
||||
startNode.combinedCost = startNode.estimatedCostToGoal;
|
||||
IOpenSet openSet = new BinaryHeapOpenSet();
|
||||
startNode.isOpen = true;
|
||||
openSet.insert(startNode);
|
||||
startNode.isOpen = true;
|
||||
bestSoFar = new PathNode[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i])
|
||||
double[] bestHeuristicSoFar = new double[COEFFICIENTS.length];
|
||||
for (int i = 0; i < bestHeuristicSoFar.length; i++) {
|
||||
bestHeuristicSoFar[i] = Double.MAX_VALUE;
|
||||
}
|
||||
CalculationContext calcContext = new CalculationContext();
|
||||
HashSet<BetterBlockPos> favored = favoredPositions.orElse(null);
|
||||
currentlyRunning = this;
|
||||
long startTime = System.currentTimeMillis();
|
||||
boolean slowPath = Baritone.settings().slowPath.get();
|
||||
long timeoutTime = startTime + (slowPath ? 40000 : 4000);
|
||||
long timeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS : Baritone.settings().pathTimeoutMS).<Long>get();
|
||||
long lastPrintout = 0;
|
||||
int numNodes = 0;
|
||||
CalculationContext calcContext = new CalculationContext();
|
||||
int numEmptyChunk = 0;
|
||||
boolean favoring = favoredPositions.isPresent(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior
|
||||
boolean cache = Baritone.settings().chuckCaching.get();
|
||||
while (!openSet.isEmpty() && numEmptyChunk < 50 && System.currentTimeMillis() < timeoutTime) {
|
||||
int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get();
|
||||
double favorCoeff = Baritone.settings().backtrackCostFavoringCoefficient.get();
|
||||
while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && System.currentTimeMillis() < timeoutTime) {
|
||||
if (slowPath) {
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
Thread.sleep(Baritone.settings().slowPathTimeDelayMS.<Long>get());
|
||||
} catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
@ -109,7 +118,7 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||
return Optional.of(new Path(startNode, currentNode, numNodes));
|
||||
}
|
||||
//long constructStart = System.nanoTime();
|
||||
Movement[] possibleMovements = getConnectedPositions(currentNodePos, calcContext);//movement that we could take that start at myPos, in random order
|
||||
Movement[] possibleMovements = getConnectedPositions(currentNodePos, calcContext);//movement that we could take that start at currentNodePos, in random order
|
||||
shuffle(possibleMovements);
|
||||
//long constructEnd = System.nanoTime();
|
||||
//System.out.println(constructEnd - constructStart);
|
||||
@ -117,16 +126,16 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||
if (movementToGetToNeighbor == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BetterBlockPos dest = (BetterBlockPos) movementToGetToNeighbor.getDest();
|
||||
boolean isPositionCached = false;
|
||||
if (cache) {
|
||||
if (CachedWorldProvider.INSTANCE.getCurrentWorld() != null) {
|
||||
if (CachedWorldProvider.INSTANCE.getCurrentWorld().getBlockType(movementToGetToNeighbor.getDest()) != null) {
|
||||
if (CachedWorldProvider.INSTANCE.getCurrentWorld().getBlockType(dest) != null) {
|
||||
isPositionCached = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isPositionCached && Minecraft.getMinecraft().world.getChunk(movementToGetToNeighbor.getDest()) instanceof EmptyChunk) {
|
||||
if (!isPositionCached && Minecraft.getMinecraft().world.getChunk(dest) instanceof EmptyChunk) {
|
||||
numEmptyChunk++;
|
||||
continue;
|
||||
}
|
||||
@ -141,7 +150,10 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper {
|
||||
if (actionCost <= 0) {
|
||||
throw new IllegalStateException(movementToGetToNeighbor.getClass() + " " + movementToGetToNeighbor + " calculated implausible cost " + actionCost);
|
||||
}
|
||||
PathNode neighbor = getNodeAtPosition((BetterBlockPos) movementToGetToNeighbor.getDest());
|
||||
if (favoring && favored.contains(dest)) {
|
||||
actionCost *= favorCoeff;
|
||||
}
|
||||
PathNode neighbor = getNodeAtPosition(dest);
|
||||
double tentativeCost = currentNode.cost + actionCost;
|
||||
if (tentativeCost < neighbor.cost) {
|
||||
if (tentativeCost < 0) {
|
||||
|
@ -20,6 +20,7 @@ package baritone.bot.pathing.path;
|
||||
import baritone.bot.pathing.movement.Movement;
|
||||
import baritone.bot.utils.Helper;
|
||||
import baritone.bot.utils.Utils;
|
||||
import baritone.bot.utils.pathing.BetterBlockPos;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.Tuple;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@ -44,7 +45,7 @@ public interface IPath extends Helper {
|
||||
* All positions along the way.
|
||||
* Should begin with the same as getSrc and end with the same as getDest
|
||||
*/
|
||||
List<BlockPos> positions();
|
||||
List<BetterBlockPos> positions();
|
||||
|
||||
/**
|
||||
* Number of positions in this path
|
||||
@ -62,7 +63,7 @@ public interface IPath extends Helper {
|
||||
* @return
|
||||
*/
|
||||
default Movement subsequentMovement(BlockPos currentPosition) {
|
||||
List<BlockPos> pos = positions();
|
||||
List<BetterBlockPos> pos = positions();
|
||||
List<Movement> movements = movements();
|
||||
for (int i = 0; i < pos.size(); i++) {
|
||||
if (currentPosition.equals(pos.get(i))) {
|
||||
@ -98,15 +99,15 @@ public interface IPath extends Helper {
|
||||
/**
|
||||
* Where does this path start
|
||||
*/
|
||||
default BlockPos getSrc() {
|
||||
default BetterBlockPos getSrc() {
|
||||
return positions().get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Where does this path end
|
||||
*/
|
||||
default BlockPos getDest() {
|
||||
List<BlockPos> pos = positions();
|
||||
default BetterBlockPos getDest() {
|
||||
List<BetterBlockPos> pos = positions();
|
||||
return pos.get(pos.size() - 1);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user