diff --git a/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java b/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java index 06c300e8..6bf61989 100644 --- a/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java +++ b/src/main/java/baritone/bot/behavior/impl/PathingBehavior.java @@ -45,6 +45,7 @@ public class PathingBehavior extends Behavior { private PathingBehavior() {} private PathExecutor current; + private PathExecutor next; private Goal goal; diff --git a/src/main/java/baritone/bot/pathing/path/IPath.java b/src/main/java/baritone/bot/pathing/path/IPath.java index 8185fff7..0a8c3ca2 100644 --- a/src/main/java/baritone/bot/pathing/path/IPath.java +++ b/src/main/java/baritone/bot/pathing/path/IPath.java @@ -17,16 +17,13 @@ package baritone.bot.pathing.path; +import baritone.bot.pathing.movement.CalculationContext; import baritone.bot.pathing.movement.Movement; import baritone.bot.utils.Utils; import net.minecraft.util.Tuple; import net.minecraft.util.math.BlockPos; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; import java.util.List; -import java.util.stream.Collectors; /** * @author leijurv @@ -111,22 +108,13 @@ public interface IPath { return pos.get(pos.size() - 1); } - /** - * For rendering purposes, what blocks should be highlighted in red - * - * @return an unordered collection of positions - */ - default Collection getBlocksToBreak() { - return movements().stream().map(Movement::toBreak).flatMap(ArrayList::stream).collect(Collectors.toCollection(HashSet::new)); - } - - /** - * For rendering purposes, what blocks should be highlighted in green - * - * @return an unordered collection of positions - */ - default Collection getBlocksToPlace() { - return movements().stream().map(Movement::toPlace).flatMap(ArrayList::stream).collect(Collectors.toCollection(HashSet::new)); + default double ticksRemaining(int pathPosition) { + double sum = 0; + CalculationContext ctx = new CalculationContext(); + for (int i = pathPosition; i < movements().size(); i++) { + sum += movements().get(i).getCost(ctx); + } + return sum; } int getNumNodesConsidered(); diff --git a/src/main/java/baritone/bot/pathing/path/PathExecutor.java b/src/main/java/baritone/bot/pathing/path/PathExecutor.java index d37fa3cc..0e444599 100644 --- a/src/main/java/baritone/bot/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/bot/pathing/path/PathExecutor.java @@ -48,6 +48,8 @@ public class PathExecutor extends Behavior { private int pathPosition; private int ticksAway; private int ticksOnCurrent; + private Double currentMovementInitialCostEstimate; + private Integer costEstimateIndex; private boolean failed; private boolean recalcBP = true; private HashSet toBreak = new HashSet<>(); @@ -171,7 +173,7 @@ public class PathExecutor extends Behavior { HashSet newBreak = new HashSet<>(); HashSet newPlace = new HashSet<>(); HashSet newWalkInto = new HashSet<>(); - for (int i = 0; i < path.movements().size(); i++) { + for (int i = pathPosition; i < path.movements().size(); i++) { newBreak.addAll(path.movements().get(i).toBreak()); newPlace.addAll(path.movements().get(i).toPlace()); newWalkInto.addAll(path.movements().get(i).toWalkInto()); @@ -186,13 +188,18 @@ public class PathExecutor extends Behavior { //displayChatMessageRaw("Recalculating break and place took " + (end - start) + "ms"); } Movement movement = path.movements().get(pathPosition); - if (movement.recalculateCost() >= ActionCosts.COST_INF) { + double currentCost = movement.recalculateCost(); + if (currentCost >= ActionCosts.COST_INF) { displayChatMessageRaw("Something has changed in the world and this movement has become impossible. Cancelling."); pathPosition = path.length() + 3; failed = true; Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys(); return; } + if (costEstimateIndex == null || costEstimateIndex != pathPosition) { + costEstimateIndex = pathPosition; + currentMovementInitialCostEstimate = currentCost; // do this only once, when the movement starts + } MovementState.MovementStatus movementStatus = movement.update(); if (movementStatus == UNREACHABLE || movementStatus == FAILED) { displayChatMessageRaw("Movement returns status " + movementStatus); @@ -209,7 +216,11 @@ public class PathExecutor extends Behavior { onTick(event); } else { ticksOnCurrent++; - if (ticksOnCurrent > movement.recalculateCost() + 100) { + if (ticksOnCurrent > currentMovementInitialCostEstimate + 100) { + // only fail if the total time has exceeded the initial estimate + // as you break the blocks required, the remaining cost goes down, to the point where + // ticksOnCurrent is greater than recalculateCost + 1000 + // this is why we cache cost at the beginning, and don't recalculate for this comparison every tick displayChatMessageRaw("This movement has taken too long (" + ticksOnCurrent + " ticks, expected " + movement.getCost(null) + "). Cancelling."); movement.cancel(); Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();