From 272dd7942650d7fb45510e502f6858a3a628b8d1 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Wed, 30 Jan 2019 15:49:37 -0800 Subject: [PATCH 01/13] much needed pathing overhaul --- .../pathing/calc/AStarPathFinder.java | 58 +++++-------------- .../pathing/calc/AbstractNodeCostSearch.java | 56 ++++++++++++++---- 2 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index b32fc99ff..6f44fac27 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -25,7 +25,6 @@ import baritone.api.utils.BetterBlockPos; import baritone.pathing.calc.openset.BinaryHeapOpenSet; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Moves; -import baritone.utils.Helper; import baritone.utils.pathing.BetterWorldBorder; import baritone.utils.pathing.Favoring; import baritone.utils.pathing.MutableMoveResult; @@ -37,7 +36,7 @@ import java.util.Optional; * * @author leijurv */ -public final class AStarPathFinder extends AbstractNodeCostSearch implements Helper { +public final class AStarPathFinder extends AbstractNodeCostSearch { private final Favoring favoring; private final CalculationContext calcContext; @@ -55,14 +54,12 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel startNode.combinedCost = startNode.estimatedCostToGoal; BinaryHeapOpenSet openSet = new BinaryHeapOpenSet(); openSet.insert(startNode); - 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]; + double[] bestHeuristicSoFar = new double[COEFFICIENTS.length];//keep track of the best node by the metric of (estimatedCostToGoal + cost / COEFFICIENTS[i]) for (int i = 0; i < bestHeuristicSoFar.length; i++) { bestHeuristicSoFar[i] = startNode.estimatedCostToGoal; bestSoFar[i] = startNode; } MutableMoveResult res = new MutableMoveResult(); - Favoring favored = favoring; BetterWorldBorder worldBorder = new BetterWorldBorder(calcContext.world.getWorldBorder()); long startTime = System.currentTimeMillis(); boolean slowPath = Baritone.settings().slowPath.get(); @@ -75,10 +72,10 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel int numNodes = 0; int numMovementsConsidered = 0; int numEmptyChunk = 0; - boolean favoring = !favored.isEmpty(); + boolean isFavoring = !favoring.isEmpty(); int timeCheckInterval = 1 << 6; int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior - boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get(); + double minimumImprovement = Baritone.settings().minimumImprovementRepropagation.get() ? MIN_IMPROVEMENT : 0; while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && !cancelRequested) { if ((numNodes & (timeCheckInterval - 1)) == 0) { // only call this once every 64 nodes (about half a millisecond) long now = System.currentTimeMillis(); // since nanoTime is slow on windows (takes many microseconds) @@ -136,21 +133,13 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset)); } long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z); - if (favoring) { + if (isFavoring) { // see issue #18 - actionCost *= favored.calculate(hashCode); + actionCost *= favoring.calculate(hashCode); } PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode); double tentativeCost = currentNode.cost + actionCost; - if (tentativeCost < neighbor.cost) { - double improvementBy = neighbor.cost - tentativeCost; - // there are floating point errors caused by random combinations of traverse and diagonal over a flat area - // that means that sometimes there's a cost improvement of like 10 ^ -16 - // it's not worth the time to update the costs, decrease-key the heap, potentially repropagate, etc - if (improvementBy < 0.01 && minimumImprovementRepropagation) { - // who cares about a hundredth of a tick? that's half a millisecond for crying out loud! - continue; - } + if (neighbor.cost - tentativeCost > minimumImprovement) { neighbor.previous = currentNode; neighbor.cost = tentativeCost; neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal; @@ -159,12 +148,9 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel } else { openSet.insert(neighbor);//dont double count, dont insert into open set if it's already there } - for (int i = 0; i < bestSoFar.length; i++) { + for (int i = 0; i < COEFFICIENTS.length; i++) { double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i]; - if (heuristic < bestHeuristicSoFar[i]) { - if (bestHeuristicSoFar[i] - heuristic < 0.01 && minimumImprovementRepropagation) { - continue; - } + if (bestHeuristicSoFar[i] - heuristic > minimumImprovement) { bestHeuristicSoFar[i] = heuristic; bestSoFar[i] = neighbor; if (getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) { @@ -182,28 +168,10 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel System.out.println("Open set size: " + openSet.size()); System.out.println("PathNode map size: " + mapSize()); System.out.println((int) (numNodes * 1.0 / ((System.currentTimeMillis() - startTime) / 1000F)) + " nodes per second"); - double bestDist = 0; - for (int i = 0; i < bestSoFar.length; i++) { - if (bestSoFar[i] == null) { - continue; - } - double dist = getDistFromStartSq(bestSoFar[i]); - if (dist > bestDist) { - bestDist = dist; - } - if (dist > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared - logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, A* cost coefficient " + COEFFICIENTS[i] + ", " + numMovementsConsidered + " movements considered"); - if (COEFFICIENTS[i] >= 3) { - System.out.println("Warning: cost coefficient is greater than three! Probably means that"); - System.out.println("the path I found is pretty terrible (like sneak-bridging for dozens of blocks)"); - System.out.println("But I'm going to do it anyway, because yolo"); - } - System.out.println("Path goes for " + Math.sqrt(dist) + " blocks"); - return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal, calcContext)); - } + Optional result = bestSoFar(true, numNodes); + if (result.isPresent()) { + logDebug("Took " + (System.currentTimeMillis() - startTime) + "ms, " + numMovementsConsidered + " movements considered"); } - logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks"); - logDebug("No path found =("); - return Optional.empty(); + return result; } } diff --git a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java index 625e8e592..a9974e8df 100644 --- a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java +++ b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java @@ -34,7 +34,7 @@ import java.util.Optional; * * @author leijurv */ -public abstract class AbstractNodeCostSearch implements IPathFinder { +public abstract class AbstractNodeCostSearch implements IPathFinder, Helper { protected final int startX; protected final int startY; @@ -53,7 +53,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { protected PathNode mostRecentConsidered; - protected PathNode[] bestSoFar; + protected final PathNode[] bestSoFar = new PathNode[COEFFICIENTS.length]; private volatile boolean isFinished; @@ -63,13 +63,23 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { * This is really complicated and hard to explain. I wrote a comment in the old version of MineBot but it was so * long it was easier as a Google Doc (because I could insert charts). * - * @see + * @see here */ - protected static final double[] COEFFICIENTS = {1.5, 2, 2.5, 3, 4, 5, 10}; // big TODO tune + protected static final double[] COEFFICIENTS = {1.5, 2, 2.5, 3, 4, 5, 10}; + /** * If a path goes less than 5 blocks and doesn't make it to its goal, it's not worth considering. */ - protected final static double MIN_DIST_PATH = 5; + protected static final double MIN_DIST_PATH = 5; + + /** + * there are floating point errors caused by random combinations of traverse and diagonal over a flat area + * that means that sometimes there's a cost improvement of like 10 ^ -16 + * it's not worth the time to update the costs, decrease-key the heap, potentially repropagate, etc + *

+ * who cares about a hundredth of a tick? that's half a millisecond for crying out loud! + */ + protected static final double MIN_IMPROVEMENT = 0.01; AbstractNodeCostSearch(int startX, int startY, int startZ, Goal goal, CalculationContext context) { this.startX = startX; @@ -170,25 +180,43 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { return Optional.ofNullable(mostRecentConsidered).map(node -> new Path(startNode, node, 0, goal, context)); } - protected int mapSize() { - return map.size(); + @Override + public Optional bestPathSoFar() { + return bestSoFar(false, 0); } - @Override - public Optional bestPathSoFar() { // TODO cleanup code duplication between here and AStarPathFinder + protected Optional bestSoFar(boolean logInfo, int numNodes) { if (startNode == null || bestSoFar == null) { return Optional.empty(); } - for (int i = 0; i < bestSoFar.length; i++) { + double bestDist = 0; + for (int i = 0; i < COEFFICIENTS.length; i++) { if (bestSoFar[i] == null) { continue; } - if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared - return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context)); + double dist = getDistFromStartSq(bestSoFar[i]); + if (dist > bestDist) { + bestDist = dist; + } + if (dist > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared + if (logInfo) { + if (COEFFICIENTS[i] >= 3) { + System.out.println("Warning: cost coefficient is greater than three! Probably means that"); + System.out.println("the path I found is pretty terrible (like sneak-bridging for dozens of blocks)"); + System.out.println("But I'm going to do it anyway, because yolo"); + } + System.out.println("Path goes for " + Math.sqrt(dist) + " blocks"); + logDebug("A* cost coefficient " + COEFFICIENTS[i]); + } + return Optional.of(new Path(startNode, bestSoFar[i], numNodes, goal, context)); } } // instead of returning bestSoFar[0], be less misleading // if it actually won't find any path, don't make them think it will by rendering a dark blue that will never actually happen + if (logInfo) { + logDebug("Even with a cost coefficient of " + COEFFICIENTS[COEFFICIENTS.length - 1] + ", I couldn't get more than " + Math.sqrt(bestDist) + " blocks"); + logDebug("No path found =("); + } return Optional.empty(); } @@ -205,4 +233,8 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { public BetterBlockPos getStart() { return new BetterBlockPos(startX, startY, startZ); } + + protected int mapSize() { + return map.size(); + } } From 246c00c7733885a6ab8026e6a9088b829d2f34ea Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 31 Jan 2019 19:19:44 -0800 Subject: [PATCH 02/13] dont repeat that --- .../java/baritone/pathing/path/PathExecutor.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java index a2c0e2ff2..8ad0db594 100644 --- a/src/main/java/baritone/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/pathing/path/PathExecutor.java @@ -377,21 +377,21 @@ public class PathExecutor implements IPathExecutor, Helper { } private boolean shouldSprintNextTick() { + boolean requested = behavior.baritone.getInputOverrideHandler().isInputForcedDown(Input.SPRINT); + + // we'll take it from here, no need for minecraft to see we're holding down control and sprint for us + behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false); + // first and foremost, if allowSprint is off, or if we don't have enough hunger, don't try and sprint if (!new CalculationContext(behavior.baritone).canSprint) { - behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false); return false; } // if the movement requested sprinting, then we're done - if (behavior.baritone.getInputOverrideHandler().isInputForcedDown(Input.SPRINT)) { - behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false); + if (requested) { return true; } - // we'll take it from here, no need for minecraft to see we're holding down control and sprint for us - behavior.baritone.getInputOverrideHandler().setInputForceState(Input.SPRINT, false); - // however, descend doesn't request sprinting, beceause it doesn't know the context of what movement comes after it IMovement current = path.movements().get(pathPosition); if (current instanceof MovementDescend) { From 747bee41b75633224a851f249e3cf4c0904f6221 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 31 Jan 2019 20:26:24 -0800 Subject: [PATCH 03/13] holding control shouldnt make all bots sprint --- .../baritone/launch/mixins/MixinEntityPlayerSP.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java index bbf920113..6e0eb3f0b 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java @@ -18,6 +18,7 @@ package baritone.launch.mixins; import baritone.api.BaritoneAPI; +import baritone.api.IBaritone; import baritone.api.behavior.IPathingBehavior; import baritone.api.event.events.ChatEvent; import baritone.api.event.events.PlayerUpdateEvent; @@ -100,8 +101,16 @@ public class MixinEntityPlayerSP { ) private boolean isKeyDown(KeyBinding keyBinding) { SprintStateEvent event = new SprintStateEvent(); - BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerSprintState(event); - return event.getState() == null ? keyBinding.isKeyDown() : event.getState(); + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this); + baritone.getGameEventHandler().onPlayerSprintState(event); + if (event.getState() != null) { + return event.getState(); + } + if (baritone == BaritoneAPI.getProvider().getPrimaryBaritone()) { + // hitting control shouldn't make all bots sprint + return false; + } + return keyBinding.isKeyDown(); } @Inject( From 5c1cf050e2bf5bd83566fb17bdc104d15d83c0c6 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 31 Jan 2019 20:27:14 -0800 Subject: [PATCH 04/13] im idiot --- src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java index 6e0eb3f0b..87cc65624 100644 --- a/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java +++ b/src/launch/java/baritone/launch/mixins/MixinEntityPlayerSP.java @@ -106,7 +106,7 @@ public class MixinEntityPlayerSP { if (event.getState() != null) { return event.getState(); } - if (baritone == BaritoneAPI.getProvider().getPrimaryBaritone()) { + if (baritone != BaritoneAPI.getProvider().getPrimaryBaritone()) { // hitting control shouldn't make all bots sprint return false; } From dc3bab26deb69ccb42159245c2a695521637490a Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 1 Feb 2019 22:54:14 -0800 Subject: [PATCH 05/13] 6 months =D --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7782651ac..1826eb208 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ Baritone is the pathfinding system used in [Impact](https://impactdevelopment.gi This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). +Have committed at least once a day for the last 6 months =D 🦀 + Here are some links to help to get started: - [Features](FEATURES.md) From 913247996e9250d5c734a44dca0fd103f7c5fcfd Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 2 Feb 2019 14:23:01 -0800 Subject: [PATCH 06/13] smh my head. who right clicks gradle tasks?? --- SETUP.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SETUP.md b/SETUP.md index 6400990d4..a479227be 100644 --- a/SETUP.md +++ b/SETUP.md @@ -65,7 +65,7 @@ $ gradlew build ![Image](https://i.imgur.com/PE6r9iN.png) -- Right click on **build** and press **Run** +- Double click on **build** to run it ## Artifacts From d799fac688b345bb66cbac9d76b3795b558340cf Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 3 Feb 2019 19:27:28 -0800 Subject: [PATCH 07/13] epicer gradle output --- .../src/main/java/baritone/gradle/task/ProguardTask.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java index 351ded3a9..4d10e7f54 100644 --- a/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java +++ b/buildSrc/src/main/java/baritone/gradle/task/ProguardTask.java @@ -298,8 +298,8 @@ public class ProguardTask extends BaritoneGradleTask { .start(); // We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this - this.printOutputLog(p.getInputStream()); - this.printOutputLog(p.getErrorStream()); + this.printOutputLog(p.getInputStream(), System.out); + this.printOutputLog(p.getErrorStream(), System.err); // Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception int exitCode = p.waitFor(); @@ -308,12 +308,12 @@ public class ProguardTask extends BaritoneGradleTask { } } - private void printOutputLog(InputStream stream) { + private void printOutputLog(InputStream stream, PrintStream outerr) { new Thread(() -> { try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { String line; while ((line = reader.readLine()) != null) { - System.out.println(line); + outerr.println(line); } } catch (Exception e) { e.printStackTrace(); From 0e1534613cf82b9e98020da9d7c73c73780b686e Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 3 Feb 2019 19:34:24 -0800 Subject: [PATCH 08/13] appease codacy --- .../baritone/pathing/movement/movements/MovementTraverse.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java index 4f9b6b518..74e4b6f39 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java @@ -281,6 +281,8 @@ public class MovementTraverse extends Movement { } return state; } + default: + break; } if (whereAmI.equals(dest)) { // If we are in the block that we are trying to get to, we are sneaking over air and we need to place a block beneath us against the one we just walked off of From 5382d265f2ba13045fcc77af8132293c521ac5dc Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 3 Feb 2019 19:46:59 -0800 Subject: [PATCH 09/13] crucial performance optimization --- src/main/java/baritone/pathing/calc/AStarPathFinder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index 6f44fac27..fda41cfdc 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -153,7 +153,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch { if (bestHeuristicSoFar[i] - heuristic > minimumImprovement) { bestHeuristicSoFar[i] = heuristic; bestSoFar[i] = neighbor; - if (getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) { + if (failing && getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) { failing = false; } } From 04e7da9b73e104052b0493dff7a7bcdd6679d5b4 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 4 Feb 2019 13:07:05 -0800 Subject: [PATCH 10/13] lower walk into can be water, but not upper --- .../baritone/pathing/movement/movements/MovementDiagonal.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java b/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java index a47fc2634..0abaccf7b 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java @@ -114,7 +114,7 @@ public class MovementDiagonal extends Movement { return; } IBlockState pb3 = context.get(destX, y + 1, z); - if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb3.getBlock()) && pb3.getBlock() != Blocks.WATER))) { + if (optionA == 0 && ((MovementHelper.avoidWalkingInto(pb2.getBlock()) && pb2.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb3.getBlock()))) { // at this point we're done calculating optionA, so we can check if it's actually possible to edge around in that direction return; } @@ -123,7 +123,7 @@ public class MovementDiagonal extends Movement { // and finally, if the cost is nonzero for both ways to approach this diagonal, it's not possible return; } - if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || (MovementHelper.avoidWalkingInto(pb1.getBlock()) && pb1.getBlock() != Blocks.WATER))) { + if (optionB == 0 && ((MovementHelper.avoidWalkingInto(pb0.getBlock()) && pb0.getBlock() != Blocks.WATER) || MovementHelper.avoidWalkingInto(pb1.getBlock()))) { // and now that option B is fully calculated, see if we can edge around that way return; } From ee23d59e111ba741aa9a6539c3302897310c2c59 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 4 Feb 2019 13:07:16 -0800 Subject: [PATCH 11/13] now we can cache flowing water properly --- src/main/java/baritone/cache/ChunkPacker.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/cache/ChunkPacker.java b/src/main/java/baritone/cache/ChunkPacker.java index 60ac63315..e2903ceaf 100644 --- a/src/main/java/baritone/cache/ChunkPacker.java +++ b/src/main/java/baritone/cache/ChunkPacker.java @@ -124,12 +124,13 @@ public final class ChunkPacker { private static PathingBlockType getPathingBlockType(IBlockState state) { Block block = state.getBlock(); - if (block == Blocks.WATER && !MovementHelper.isFlowing(state)) { + if ((block == Blocks.WATER || block == Blocks.FLOWING_WATER) && !MovementHelper.isFlowing(state)) { // only water source blocks are plausibly usable, flowing water should be avoid + // FLOWING_WATER is a waterfall, it doesn't really matter and caching it as AVOID just makes it look wrong return PathingBlockType.WATER; } - if (MovementHelper.avoidWalkingInto(block) || block == Blocks.FLOWING_WATER || MovementHelper.isBottomSlab(state)) { + if (MovementHelper.avoidWalkingInto(block) || MovementHelper.isBottomSlab(state)) { return PathingBlockType.AVOID; } // We used to do an AABB check here From 57b2e360ca43cfc1639faf085032621594c9959b Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 4 Feb 2019 13:27:35 -0800 Subject: [PATCH 12/13] dont include current movement cost while deciding when to plan ahead --- .../baritone/api/behavior/IPathingBehavior.java | 15 ++++++++++++++- .../java/baritone/behavior/PathingBehavior.java | 4 +++- .../java/baritone/pathing/path/PathExecutor.java | 2 ++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/api/java/baritone/api/behavior/IPathingBehavior.java b/src/api/java/baritone/api/behavior/IPathingBehavior.java index d28195ae9..64be71d50 100644 --- a/src/api/java/baritone/api/behavior/IPathingBehavior.java +++ b/src/api/java/baritone/api/behavior/IPathingBehavior.java @@ -38,11 +38,24 @@ public interface IPathingBehavior extends IBehavior { * @return The estimated remaining ticks in the current segment. */ default Optional ticksRemainingInSegment() { + return ticksRemainingInSegment(true); + } + + /** + * Returns the estimated remaining ticks in the current pathing + * segment. Given that the return type is an optional, {@link Optional#empty()} + * will be returned in the case that there is no current segment being pathed. + * + * @param includeCurrentMovement whether or not to include the entirety of the cost of the currently executing movement in the total + * @return The estimated remaining ticks in the current segment. + */ + default Optional ticksRemainingInSegment(boolean includeCurrentMovement) { IPathExecutor current = getCurrent(); if (current == null) { return Optional.empty(); } - return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition())); + int start = includeCurrentMovement ? current.getPosition() : current.getPosition() + 1; + return Optional.of(current.getPath().ticksRemainingFrom(start)); } /** diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index ea7520825..8339625d0 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -193,8 +193,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, // and this path doesn't get us all the way there return; } - if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) { + if (ticksRemainingInSegment(false).get() < Baritone.settings().planningTickLookAhead.get()) { // and this path has 7.5 seconds or less left + // don't include the current movement so a very long last movement (e.g. descend) doesn't trip it up + // if we actually included current, it wouldn't start planning ahead until the last movement was done, if the last movement took more than 7.5 seconds on its own logDebug("Path almost over. Planning ahead..."); queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED); findPathInNewThread(current.getPath().getDest(), false); diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java index 8ad0db594..1b59f8e32 100644 --- a/src/main/java/baritone/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/pathing/path/PathExecutor.java @@ -249,6 +249,8 @@ public class PathExecutor implements IPathExecutor, Helper { return true; } if (!movement.calculatedWhileLoaded() && currentCost - currentMovementOriginalCostEstimate > Baritone.settings().maxCostIncrease.get() && canCancel) { + // don't do this if the movement was calculated while loaded + // that means that this isn't a cache error, it's just part of the path interfering with a later part logDebug("Original cost " + currentMovementOriginalCostEstimate + " current cost " + currentCost + ". Cancelling."); cancel(); return true; From 798f25ff81dc767fe69768831aa468827c0c64f0 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 4 Feb 2019 13:52:11 -0800 Subject: [PATCH 13/13] dont glitch weirdly when failing a parkour jump --- .../baritone/pathing/movement/movements/MovementParkour.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java index 38fd510ac..74acac48b 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java @@ -187,6 +187,11 @@ public class MovementParkour extends Movement { logDebug("Pausing parkour since hand is active"); return state; } + if (ctx.playerFeet().y < src.y) { + // we have fallen + logDebug("sorry"); + return state.setStatus(MovementStatus.UNREACHABLE); + } if (dist >= 4) { state.setInput(Input.SPRINT, true); }