pause when current best is a backtrack, fixes #201

This commit is contained in:
Leijurv 2018-10-06 18:39:30 -07:00
parent e4ef659756
commit 939e9c32d5
No known key found for this signature in database
GPG Key ID: 44A3EA646EADAC6A
5 changed files with 53 additions and 2 deletions

View File

@ -139,11 +139,12 @@ class Path implements IPath {
for (Moves moves : Moves.values()) {
Movement move = moves.apply0(src);
if (move.getDest().equals(dest)) {
// TODO instead of recalculating here, could we take pathNode.cost - pathNode.prevNode.cost to get the cost as-calculated?
move.recalculateCost(); // have to calculate the cost at calculation time so we can accurately judge whether a cost increase happened between cached calculation and real execution
return move;
}
}
// leave this as IllegalStateException; it's caught in AbstractNodeCostSearch
// this is no longer called from bestPathSoFar, now it's in postprocessing
throw new IllegalStateException("Movement became impossible during calculation " + src + " " + dest + " " + dest.subtract(src));
}

View File

@ -114,7 +114,9 @@ public class MovementFall extends Movement {
@Override
public boolean safeToCancel(MovementState state) {
return state.getStatus() != MovementStatus.RUNNING;
// if we haven't started walking off the edge yet, or if we're in the process of breaking blocks before doing the fall
// then it's safe to cancel this
return playerFeet().equals(src) || state.getStatus() != MovementStatus.RUNNING;
}
private static BetterBlockPos[] buildPositionsToBreak(BetterBlockPos src, BetterBlockPos dest) {

View File

@ -163,6 +163,14 @@ public class MovementParkour extends Movement {
return res.cost;
}
@Override
public boolean safeToCancel(MovementState state) {
// once this movement is instantiated, the state is default to PREPPING
// but once it's ticked for the first time it changes to RUNNING
// since we don't really know anything about momentum, it suffices to say Parkour can only be canceled on the 0th tick
return state.getStatus() != MovementState.MovementStatus.RUNNING;
}
@Override
public MovementState updateState(MovementState state) {
super.updateState(state);

View File

@ -319,6 +319,14 @@ public class MovementTraverse extends Movement {
}
}
@Override
public boolean safeToCancel(MovementState state) {
// if we're in the process of breaking blocks before walking forwards
// or if this isn't a sneak place (the block is already there)
// then it's safe to cancel this
return state.getStatus() != MovementState.MovementStatus.RUNNING || MovementHelper.canWalkOn(dest.down());
}
@Override
protected boolean prepared(MovementState state) {
if (playerFeet().equals(src) || playerFeet().equals(src.down())) {

View File

@ -20,6 +20,7 @@ package baritone.pathing.path;
import baritone.Baritone;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.movement.ActionCosts;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.MovementHelper;
@ -33,6 +34,7 @@ import net.minecraft.util.math.BlockPos;
import java.util.Collections;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import static baritone.pathing.movement.MovementState.MovementStatus.*;
@ -242,6 +244,10 @@ public class PathExecutor implements Helper {
cancel();
return true;
}
if (shouldPause()) {
logDebug("Pausing since current best path is a backtrack");
return true;
}
MovementState.MovementStatus movementStatus = movement.update();
if (movementStatus == UNREACHABLE || movementStatus == FAILED) {
logDebug("Movement returns status " + movementStatus);
@ -270,6 +276,32 @@ public class PathExecutor implements Helper {
return false; // movement is in progress
}
private boolean shouldPause() {
Optional<AbstractNodeCostSearch> current = AbstractNodeCostSearch.getCurrentlyRunning();
if (!current.isPresent()) {
return false;
}
if (!player().onGround) {
return false;
}
if (!MovementHelper.canWalkOn(playerFeet().down())) {
// we're in some kind of sketchy situation, maybe parkouring
return false;
}
if (!MovementHelper.canWalkThrough(playerFeet()) || !MovementHelper.canWalkThrough(playerFeet().up())) {
// suffocating?
return false;
}
if (!path.movements().get(pathPosition).safeToCancel()) {
return false;
}
Optional<IPath> currentBest = current.get().bestPathSoFar();
if (!currentBest.isPresent()) {
return false;
}
return currentBest.get().positions().contains(playerFeet());
}
private boolean possiblyOffPath(Tuple<Double, BlockPos> status, double leniency) {
double distanceFromPath = status.getFirst();
if (distanceFromPath > leniency) {