From a98c5d7d9987f7511e70ea28cfbe02e411264aa0 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:25:02 -0800 Subject: [PATCH 1/9] my house --- src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java index ac4efa4d2..26601b13e 100644 --- a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java +++ b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java @@ -87,7 +87,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { if (isFinished) { throw new IllegalStateException("Path Finder is currently in use, and cannot be reused!"); } - this.cancelRequested = false; + cancelRequested = false; try { IPath path = calculate0(timeout).map(IPath::postProcess).orElse(null); isFinished = true; From d854750ee8a088a540caffca5819f2c2c18a2428 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:52:56 -0800 Subject: [PATCH 2/9] improve accuracy of GoalGetToBlock heuristic --- .../java/baritone/api/pathing/goals/GoalGetToBlock.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java index 959b6fcc6..c4856cdd6 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java +++ b/src/api/java/baritone/api/pathing/goals/GoalGetToBlock.java @@ -48,10 +48,7 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos { int xDiff = x - this.x; int yDiff = y - this.y; int zDiff = z - this.z; - if (yDiff < 0) { - yDiff++; - } - return Math.abs(xDiff) + Math.abs(yDiff) + Math.abs(zDiff) <= 1; + return Math.abs(xDiff) + Math.abs(yDiff < 0 ? yDiff + 1 : yDiff) + Math.abs(zDiff) <= 1; } @Override @@ -59,7 +56,7 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos { int xDiff = x - this.x; int yDiff = y - this.y; int zDiff = z - this.z; - return GoalBlock.calculate(xDiff, yDiff, zDiff); + return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff); } @Override From b7052791531cf502a99015388e2c7a86986eb3bf Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:55:02 -0800 Subject: [PATCH 3/9] consistency --- src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java index 4ed1bf5ee..b1dc07a1d 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java +++ b/src/api/java/baritone/api/pathing/goals/GoalTwoBlocks.java @@ -63,10 +63,7 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos { int xDiff = x - this.x; int yDiff = y - this.y; int zDiff = z - this.z; - if (yDiff < 0) { - yDiff++; - } - return GoalBlock.calculate(xDiff, yDiff, zDiff); + return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff); } @Override From 84cd4b1acb5ab1d82035d7c983c942f88a3a8555 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:58:23 -0800 Subject: [PATCH 4/9] unused --- .../baritone/api/pathing/goals/GoalComposite.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/api/java/baritone/api/pathing/goals/GoalComposite.java b/src/api/java/baritone/api/pathing/goals/GoalComposite.java index 2926b8528..415f74e56 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalComposite.java +++ b/src/api/java/baritone/api/pathing/goals/GoalComposite.java @@ -17,10 +17,7 @@ package baritone.api.pathing.goals; -import net.minecraft.util.math.BlockPos; - import java.util.Arrays; -import java.util.Collection; /** * A composite of many goals, any one of which satisfies the composite. @@ -40,14 +37,6 @@ public class GoalComposite implements Goal { this.goals = goals; } - public GoalComposite(BlockPos... blocks) { - this(Arrays.asList(blocks)); - } - - public GoalComposite(Collection blocks) { - this(blocks.stream().map(GoalBlock::new).toArray(Goal[]::new)); - } - @Override public boolean isInGoal(int x, int y, int z) { for (Goal goal : goals) { From 5aa78cd478acf8b907be25c0e6ff3230ec504df5 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 11:22:49 -0800 Subject: [PATCH 5/9] crucial performance optimization --- 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 0627ebb4c..cd072bb6f 100644 --- a/src/main/java/baritone/cache/ChunkPacker.java +++ b/src/main/java/baritone/cache/ChunkPacker.java @@ -92,7 +92,8 @@ public final class ChunkPacker { for (int z = 0; z < 16; z++) { // @formatter:off - https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html + https: +//www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html // @formatter:on for (int x = 0; x < 16; x++) { for (int y = 255; y >= 0; y--) { @@ -124,7 +125,7 @@ public final class ChunkPacker { private static PathingBlockType getPathingBlockType(IBlockState state) { Block block = state.getBlock(); - if (block.equals(Blocks.WATER) && !MovementHelper.isFlowing(state)) { + if (block == Blocks.WATER && !MovementHelper.isFlowing(state)) { // only water source blocks are plausibly usable, flowing water should be avoid return PathingBlockType.WATER; } From 7632d667c9711dbe687b4105ebfa273636549d40 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 22 Nov 2018 09:39:54 -0800 Subject: [PATCH 6/9] add a secondary failure cutoff --- src/api/java/baritone/api/Settings.java | 18 ++++++++++++---- .../api/pathing/calc/IPathFinder.java | 2 +- .../baritone/behavior/PathingBehavior.java | 16 +++++++++----- .../pathing/calc/AStarPathFinder.java | 21 ++++++++++++++----- .../pathing/calc/AbstractNodeCostSearch.java | 16 ++++++-------- 5 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 7fce02540..f4fd7db14 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -247,14 +247,24 @@ public class Settings { public Setting movementTimeoutTicks = new Setting<>(100); /** - * Pathing can never take longer than this + * Pathing ends after this amount of time, if a path has been found */ - public Setting pathTimeoutMS = new Setting<>(2000L); + public Setting primaryTimeoutMS = new Setting<>(500L); /** - * Planning ahead while executing a segment can never take longer than this + * Pathing can never take longer than this, even if that means failing to find any path at all */ - public Setting planAheadTimeoutMS = new Setting<>(4000L); + public Setting failureTimeoutMS = new Setting<>(2000L); + + /** + * Planning ahead while executing a segment ends after this amount of time, if a path has been found + */ + public Setting planAheadPrimaryTimeoutMS = new Setting<>(4000L); + + /** + * Planning ahead while executing a segment can never take longer than this, even if that means failing to find any path at all + */ + public Setting planAheadFailureTimeoutMS = new Setting<>(5000L); /** * For debugging, consider nodes much much slower diff --git a/src/api/java/baritone/api/pathing/calc/IPathFinder.java b/src/api/java/baritone/api/pathing/calc/IPathFinder.java index f70196a69..fa83295f7 100644 --- a/src/api/java/baritone/api/pathing/calc/IPathFinder.java +++ b/src/api/java/baritone/api/pathing/calc/IPathFinder.java @@ -36,7 +36,7 @@ public interface IPathFinder { * * @return The final path */ - PathCalculationResult calculate(long timeout); + PathCalculationResult calculate(long primaryTimeout, long failureTimeout); /** * Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 1943b215e..f2017eefc 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -40,7 +40,10 @@ import baritone.utils.PathRenderer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.EmptyChunk; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Optional; import java.util.concurrent.LinkedBlockingQueue; import java.util.stream.Collectors; @@ -396,11 +399,14 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, logDebug("no goal"); // TODO should this be an exception too? definitely should be checked by caller return; } - long timeout; + long primaryTimeout; + long failureTimeout; if (current == null) { - timeout = Baritone.settings().pathTimeoutMS.get(); + primaryTimeout = Baritone.settings().primaryTimeoutMS.get(); + failureTimeout = Baritone.settings().failureTimeoutMS.get(); } else { - timeout = Baritone.settings().planAheadTimeoutMS.get(); + primaryTimeout = Baritone.settings().planAheadPrimaryTimeoutMS.get(); + failureTimeout = Baritone.settings().planAheadFailureTimeoutMS.get(); } CalculationContext context = new CalculationContext(baritone); // not safe to create on the other thread, it looks up a lot of stuff in minecraft AbstractNodeCostSearch pathfinder = createPathfinder(start, goal, current == null ? null : current.getPath(), context); @@ -410,7 +416,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, logDebug("Starting to search for path from " + start + " to " + goal); } - PathCalculationResult calcResult = pathfinder.calculate(timeout); + PathCalculationResult calcResult = pathfinder.calculate(primaryTimeout, failureTimeout); Optional path = calcResult.getPath(); if (Baritone.settings().cutoffAtLoadBoundary.get()) { path = path.map(p -> { diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index f65920945..aa83bc442 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -49,7 +49,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel } @Override - protected Optional calculate0(long timeout) { + protected Optional calculate0(long primaryTimeout, long failureTimeout) { startNode = getNodeAtPosition(startX, startY, startZ, BetterBlockPos.longHash(startX, startY, startZ)); startNode.cost = 0; startNode.combinedCost = startNode.estimatedCostToGoal; @@ -68,10 +68,11 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel long startTime = System.nanoTime() / 1000000L; boolean slowPath = Baritone.settings().slowPath.get(); if (slowPath) { - logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.get() + "ms instead of " + timeout + "ms"); + logDebug("slowPath is on, path timeout will be " + Baritone.settings().slowPathTimeoutMS.get() + "ms instead of " + primaryTimeout + "ms"); } - long timeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.get() : timeout); - //long lastPrintout = 0; + long primaryTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.get() : primaryTimeout); + long failureTimeoutTime = startTime + (slowPath ? Baritone.settings().slowPathTimeoutMS.get() : failureTimeout); + boolean failing = true; int numNodes = 0; int numMovementsConsidered = 0; int numEmptyChunk = 0; @@ -79,7 +80,14 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior double favorCoeff = Baritone.settings().backtrackCostFavoringCoefficient.get(); boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get(); - while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && System.nanoTime() / 1000000L - timeoutTime < 0 && !cancelRequested) { + while (!openSet.isEmpty() && numEmptyChunk < pathingMaxChunkBorderFetch && !cancelRequested) { + long now = System.nanoTime() / 1000000L; + if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) { + break; + } + if (failing == bestPathSoFar().isPresent()) { + throw new IllegalStateException(); + } if (slowPath) { try { Thread.sleep(Baritone.settings().slowPathTimeDelayMS.get()); @@ -166,6 +174,9 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel } bestHeuristicSoFar[i] = heuristic; bestSoFar[i] = neighbor; + if (getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) { + failing = false; + } } } } diff --git a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java index 26601b13e..f2dcf4b19 100644 --- a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java +++ b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java @@ -83,13 +83,14 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { cancelRequested = true; } - public synchronized PathCalculationResult calculate(long timeout) { + @Override + public synchronized PathCalculationResult calculate(long primaryTimeout, long failureTimeout) { if (isFinished) { throw new IllegalStateException("Path Finder is currently in use, and cannot be reused!"); } cancelRequested = false; try { - IPath path = calculate0(timeout).map(IPath::postProcess).orElse(null); + IPath path = calculate0(primaryTimeout, failureTimeout).map(IPath::postProcess).orElse(null); isFinished = true; if (cancelRequested) { return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, path); @@ -112,7 +113,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { } } - protected abstract Optional calculate0(long timeout); + protected abstract Optional calculate0(long primaryTimeout, long failureTimeout); /** * Determines the distance squared from the specified node to the start @@ -157,7 +158,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { @Override public Optional bestPathSoFar() { - if (startNode == null || bestSoFar == null || bestSoFar[0] == null) { + if (startNode == null || bestSoFar == null) { return Optional.empty(); } for (int i = 0; i < bestSoFar.length; i++) { @@ -165,12 +166,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { continue; } if (getDistFromStartSq(bestSoFar[i]) > MIN_DIST_PATH * MIN_DIST_PATH) { // square the comparison since distFromStartSq is squared - try { - return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context)); - } catch (IllegalStateException ex) { - System.out.println("Unable to construct path to render"); - return Optional.empty(); - } + return Optional.of(new Path(startNode, bestSoFar[i], 0, goal, context)); } } // instead of returning bestSoFar[0], be less misleading From 50d4b5b4ed8324822eda7900f62dab1afea5dca1 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 22 Nov 2018 10:08:55 -0800 Subject: [PATCH 7/9] unneeded --- src/main/java/baritone/pathing/calc/AStarPathFinder.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index aa83bc442..d00619211 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -85,9 +85,6 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel if (now - failureTimeoutTime >= 0 || (!failing && now - primaryTimeoutTime >= 0)) { break; } - if (failing == bestPathSoFar().isPresent()) { - throw new IllegalStateException(); - } if (slowPath) { try { Thread.sleep(Baritone.settings().slowPathTimeDelayMS.get()); From 038533c33f1cb3d2c44f87ebd3c64f0e2c537049 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 10:50:03 -0800 Subject: [PATCH 8/9] explain documentation more --- src/api/java/baritone/api/Settings.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index f4fd7db14..a835ed73f 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -247,7 +247,9 @@ public class Settings { public Setting movementTimeoutTicks = new Setting<>(100); /** - * Pathing ends after this amount of time, if a path has been found + * Pathing ends after this amount of time, but only if a path has been found + *

+ * If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout */ public Setting primaryTimeoutMS = new Setting<>(500L); @@ -257,7 +259,9 @@ public class Settings { public Setting failureTimeoutMS = new Setting<>(2000L); /** - * Planning ahead while executing a segment ends after this amount of time, if a path has been found + * Planning ahead while executing a segment ends after this amount of time, but only if a path has been found + *

+ * If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout */ public Setting planAheadPrimaryTimeoutMS = new Setting<>(4000L); From 9c5274dde41a5bb546b2cb3f8040e6f4f01a744f Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 23 Nov 2018 13:12:18 -0800 Subject: [PATCH 9/9] runnable conversion --- src/main/java/baritone/behavior/PathingBehavior.java | 5 +---- .../java/baritone/utils/pathing/SegmentedCalculator.java | 8 ++++++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 26e8687c5..42186b5b2 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -40,10 +40,7 @@ import baritone.utils.PathRenderer; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.EmptyChunk; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Optional; +import java.util.*; import java.util.concurrent.LinkedBlockingQueue; import java.util.stream.Collectors; diff --git a/src/main/java/baritone/utils/pathing/SegmentedCalculator.java b/src/main/java/baritone/utils/pathing/SegmentedCalculator.java index a0b8e27c1..75dd0282a 100644 --- a/src/main/java/baritone/utils/pathing/SegmentedCalculator.java +++ b/src/main/java/baritone/utils/pathing/SegmentedCalculator.java @@ -72,7 +72,7 @@ public class SegmentedCalculator { return search.calculate(Baritone.settings().primaryTimeoutMS.get(), Baritone.settings().failureTimeoutMS.get()); // use normal time settings, not the plan ahead settings, so as to not overwhelm the computer } - public static void calculateSegmentsThreaded(BetterBlockPos start, Goal goal, CalculationContext context, Consumer> onCompletion) { + public static void calculateSegmentsThreaded(BetterBlockPos start, Goal goal, CalculationContext context, Consumer onCompletion, Runnable onFailure) { Baritone.getExecutor().execute(() -> { Optional result; try { @@ -81,7 +81,11 @@ public class SegmentedCalculator { ex.printStackTrace(); result = Optional.empty(); } - onCompletion.accept(result); + if (result.isPresent()) { + onCompletion.accept(result.get()); + } else { + onFailure.run(); + } }); } }