diff --git a/README.md b/README.md
index ef568f0cd..d88647f3c 100644
--- a/README.md
+++ b/README.md
@@ -7,11 +7,13 @@
[](https://github.com/cabaletta/baritone/issues)
[](https://minecraft.gamepedia.com/1.12.2)
-A Minecraft pathfinder bot. 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 [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
+A Minecraft pathfinder bot.
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
+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 [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
+
Here are some links to help to get started:
- [Features](FEATURES.md)
diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java
index 419e8e712..e2e4604d2 100644
--- a/src/api/java/baritone/api/Settings.java
+++ b/src/api/java/baritone/api/Settings.java
@@ -411,7 +411,7 @@ public class Settings {
*
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
*/
- public Setting cancelOnGoalInvalidation = new Setting<>(false);
+ public Setting cancelOnGoalInvalidation = new Setting<>(true);
/**
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
diff --git a/src/api/java/baritone/api/pathing/calc/IPath.java b/src/api/java/baritone/api/pathing/calc/IPath.java
index f2309e0e6..ad25911a8 100644
--- a/src/api/java/baritone/api/pathing/calc/IPath.java
+++ b/src/api/java/baritone/api/pathing/calc/IPath.java
@@ -52,7 +52,9 @@ public interface IPath {
* This path is actually going to be executed in the world. Do whatever additional processing is required.
* (as opposed to Path objects that are just constructed every frame for rendering)
*/
- default void postProcess() {}
+ default IPath postProcess() {
+ throw new UnsupportedOperationException();
+ }
/**
* Returns the number of positions in this path. Equivalent to {@code positions().size()}.
@@ -119,7 +121,7 @@ public interface IPath {
* @return The result of this cut-off operation
*/
default IPath cutoffAtLoadedChunks() {
- return this;
+ throw new UnsupportedOperationException();
}
/**
@@ -131,7 +133,7 @@ public interface IPath {
* @see Settings#pathCutoffFactor
*/
default IPath staticCutoff(Goal destination) {
- return this;
+ throw new UnsupportedOperationException();
}
diff --git a/src/api/java/baritone/api/pathing/calc/IPathFinder.java b/src/api/java/baritone/api/pathing/calc/IPathFinder.java
index 446f7e051..f70196a69 100644
--- a/src/api/java/baritone/api/pathing/calc/IPathFinder.java
+++ b/src/api/java/baritone/api/pathing/calc/IPathFinder.java
@@ -18,6 +18,7 @@
package baritone.api.pathing.calc;
import baritone.api.pathing.goals.Goal;
+import baritone.api.utils.PathCalculationResult;
import java.util.Optional;
@@ -35,7 +36,7 @@ public interface IPathFinder {
*
* @return The final path
*/
- Optional calculate(long timeout);
+ PathCalculationResult calculate(long timeout);
/**
* Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet
diff --git a/src/api/java/baritone/api/process/PathingCommandType.java b/src/api/java/baritone/api/process/PathingCommandType.java
index f2336d261..da64748aa 100644
--- a/src/api/java/baritone/api/process/PathingCommandType.java
+++ b/src/api/java/baritone/api/process/PathingCommandType.java
@@ -49,7 +49,7 @@ public enum PathingCommandType {
/**
* Set the goal and path.
*
- * Revalidate the current goal, and cancel if it's no longer valid, or if the new goal is {@code null}.
+ * Cancel the current path if the goals are not equal
*/
FORCE_REVALIDATE_GOAL_AND_PATH
}
diff --git a/src/api/java/baritone/api/utils/PathCalculationResult.java b/src/api/java/baritone/api/utils/PathCalculationResult.java
new file mode 100644
index 000000000..69d2a9b3e
--- /dev/null
+++ b/src/api/java/baritone/api/utils/PathCalculationResult.java
@@ -0,0 +1,41 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.api.utils;
+
+import baritone.api.pathing.calc.IPath;
+
+import java.util.Optional;
+
+public class PathCalculationResult {
+
+ public final Optional path;
+ public final Type type;
+
+ public PathCalculationResult(Type type, Optional path) {
+ this.path = path;
+ this.type = type;
+ }
+
+ public enum Type {
+ SUCCESS_TO_GOAL,
+ SUCCESS_SEGMENT,
+ FAILURE,
+ CANCELLATION,
+ EXCEPTION,
+ }
+}
diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java
index 53b771da9..515509954 100644
--- a/src/main/java/baritone/behavior/PathingBehavior.java
+++ b/src/main/java/baritone/behavior/PathingBehavior.java
@@ -28,6 +28,7 @@ import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.utils.BetterBlockPos;
+import baritone.api.utils.PathCalculationResult;
import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.pathing.calc.AStarPathFinder;
import baritone.pathing.calc.AbstractNodeCostSearch;
@@ -379,7 +380,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
logDebug("Starting to search for path from " + start + " to " + goal);
}
- Optional path = findPath(start, previous, context);
+ PathCalculationResult calcResult = findPath(start, previous, context);
+ Optional path = calcResult.path;
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
path = path.map(p -> {
IPath result = p.cutoffAtLoadedChunks();
@@ -411,7 +413,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
current = executor.get();
} else {
- queuePathEvent(PathEvent.CALC_FAILED);
+ if (calcResult.type != PathCalculationResult.Type.CANCELLATION && calcResult.type != PathCalculationResult.Type.EXCEPTION) {
+ // don't dispatch CALC_FAILED on cancellation
+ queuePathEvent(PathEvent.CALC_FAILED);
+ }
}
} else {
if (next == null) {
@@ -425,18 +430,16 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
throw new IllegalStateException("I have no idea what to do with this path");
}
}
- }
-
- if (talkAboutIt && current != null && current.getPath() != null) {
- if (goal == null || goal.isInGoal(current.getPath().getDest())) {
- logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
- } else {
- logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
-
+ if (talkAboutIt && current != null && current.getPath() != null) {
+ if (goal == null || goal.isInGoal(current.getPath().getDest())) {
+ logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
+ } else {
+ logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
+ }
+ }
+ synchronized (pathCalcLock) {
+ isPathCalcInProgress = false;
}
- }
- synchronized (pathCalcLock) {
- isPathCalcInProgress = false;
}
});
}
@@ -447,11 +450,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
* @param start
* @return
*/
- private Optional findPath(BlockPos start, Optional previous, CalculationContext context) {
+ private PathCalculationResult findPath(BlockPos start, Optional previous, CalculationContext context) {
Goal goal = this.goal;
if (goal == null) {
logDebug("no goal");
- return Optional.empty();
+ return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, Optional.empty());
}
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
@@ -478,7 +481,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
} catch (Exception e) {
logDebug("Pathing exception: " + e);
e.printStackTrace();
- return Optional.empty();
+ return new PathCalculationResult(PathCalculationResult.Type.EXCEPTION, Optional.empty());
}
}
diff --git a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java
index bbbe32add..708b5ab05 100644
--- a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java
+++ b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java
@@ -21,6 +21,7 @@ import baritone.Baritone;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
+import baritone.api.utils.PathCalculationResult;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import java.util.Optional;
@@ -82,16 +83,26 @@ public abstract class AbstractNodeCostSearch implements IPathFinder {
cancelRequested = true;
}
- public synchronized Optional calculate(long timeout) {
+ public synchronized PathCalculationResult calculate(long timeout) {
if (isFinished) {
throw new IllegalStateException("Path Finder is currently in use, and cannot be reused!");
}
this.cancelRequested = false;
try {
Optional path = calculate0(timeout);
- path.ifPresent(IPath::postProcess);
+ path = path.map(IPath::postProcess);
isFinished = true;
- return path;
+ if (cancelRequested) {
+ return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, path);
+ }
+ if (!path.isPresent()) {
+ return new PathCalculationResult(PathCalculationResult.Type.FAILURE, path);
+ }
+ if (goal.isInGoal(path.get().getDest())) {
+ return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_TO_GOAL, path);
+ } else {
+ return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_SEGMENT, path);
+ }
} finally {
// this is run regardless of what exception may or may not be raised by calculate0
currentlyRunning = null;
diff --git a/src/main/java/baritone/pathing/calc/Path.java b/src/main/java/baritone/pathing/calc/Path.java
index 93f021c6a..873fef641 100644
--- a/src/main/java/baritone/pathing/calc/Path.java
+++ b/src/main/java/baritone/pathing/calc/Path.java
@@ -17,7 +17,6 @@
package baritone.pathing.calc;
-import baritone.api.BaritoneAPI;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
@@ -25,9 +24,8 @@ import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves;
import baritone.pathing.path.CutoffPath;
-import net.minecraft.client.Minecraft;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.chunk.EmptyChunk;
+import baritone.utils.Helper;
+import baritone.utils.pathing.PathBase;
import java.util.ArrayList;
import java.util.Collections;
@@ -39,7 +37,7 @@ import java.util.List;
*
* @author leijurv
*/
-class Path implements IPath {
+class Path extends PathBase {
/**
* The start position of this path
@@ -59,6 +57,8 @@ class Path implements IPath {
private final List movements;
+ private final List nodes;
+
private final Goal goal;
private final int numNodes;
@@ -71,8 +71,9 @@ class Path implements IPath {
this.numNodes = numNodes;
this.path = new ArrayList<>();
this.movements = new ArrayList<>();
+ this.nodes = new ArrayList<>();
this.goal = goal;
- assemblePath(start, end);
+ assemblePath(end);
}
@Override
@@ -81,62 +82,80 @@ class Path implements IPath {
}
/**
- * Assembles this path given the start and end nodes.
+ * Assembles this path given the end node.
*
- * @param start The start node
- * @param end The end node
+ * @param end The end node
*/
- private void assemblePath(PathNode start, PathNode end) {
+ private void assemblePath(PathNode end) {
if (!path.isEmpty() || !movements.isEmpty()) {
throw new IllegalStateException();
}
PathNode current = end;
LinkedList tempPath = new LinkedList<>();
+ LinkedList tempNodes = new LinkedList();
// Repeatedly inserting to the beginning of an arraylist is O(n^2)
// Instead, do it into a linked list, then convert at the end
- while (!current.equals(start)) {
+ while (current != null) {
+ tempNodes.addFirst(current);
tempPath.addFirst(new BetterBlockPos(current.x, current.y, current.z));
current = current.previous;
}
- tempPath.addFirst(this.start);
// Can't directly convert from the PathNode pseudo linked list to an array because we don't know how long it is
// inserting into a LinkedList keeps track of length, then when we addall (which calls .toArray) it's able
// to performantly do that conversion since it knows the length.
path.addAll(tempPath);
+ nodes.addAll(tempNodes);
}
- private void assembleMovements() {
+ private boolean assembleMovements() {
if (path.isEmpty() || !movements.isEmpty()) {
throw new IllegalStateException();
}
for (int i = 0; i < path.size() - 1; i++) {
- movements.add(runBackwards(path.get(i), path.get(i + 1)));
+ double cost = nodes.get(i + 1).cost - nodes.get(i).cost;
+ Movement move = runBackwards(path.get(i), path.get(i + 1), cost);
+ if (move == null) {
+ return true;
+ } else {
+ movements.add(move);
+ }
}
+ return false;
}
- private static Movement runBackwards(BetterBlockPos src, BetterBlockPos dest) { // TODO this is horrifying
+ private static Movement runBackwards(BetterBlockPos src, BetterBlockPos dest, double cost) {
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
+ // have to calculate the cost at calculation time so we can accurately judge whether a cost increase happened between cached calculation and real execution
+ move.override(cost);
return move;
}
}
// 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));
+ Helper.HELPER.logDebug("Movement became impossible during calculation " + src + " " + dest + " " + dest.subtract(src));
+ return null;
}
@Override
- public void postProcess() {
+ public IPath postProcess() {
if (verified) {
throw new IllegalStateException();
}
verified = true;
- assembleMovements();
- // more post processing here
+ boolean failed = assembleMovements();
movements.forEach(Movement::checkLoadedChunk);
+
+ if (failed) { // at least one movement became impossible during calculation
+ CutoffPath res = new CutoffPath(this, movements().size());
+ if (res.movements().size() != movements.size()) {
+ throw new IllegalStateException();
+ }
+ return res;
+ }
+ // more post processing here
sanityCheck();
+ return this;
}
@Override
@@ -166,28 +185,4 @@ class Path implements IPath {
public BetterBlockPos getDest() {
return end;
}
-
- @Override
- public IPath cutoffAtLoadedChunks() {
- for (int i = 0; i < positions().size(); i++) {
- BlockPos pos = positions().get(i);
- if (Minecraft.getMinecraft().world.getChunk(pos) instanceof EmptyChunk) {
- return new CutoffPath(this, i);
- }
- }
- return this;
- }
-
- @Override
- public IPath staticCutoff(Goal destination) {
- if (length() < BaritoneAPI.getSettings().pathCutoffMinimumLength.get()) {
- return this;
- }
- if (destination == null || destination.isInGoal(getDest())) {
- return this;
- }
- double factor = BaritoneAPI.getSettings().pathCutoffFactor.get();
- int newLength = (int) (length() * factor);
- return new CutoffPath(this, newLength);
- }
}
diff --git a/src/main/java/baritone/pathing/movement/Movement.java b/src/main/java/baritone/pathing/movement/Movement.java
index fb316ed36..31dd952bf 100644
--- a/src/main/java/baritone/pathing/movement/Movement.java
+++ b/src/main/java/baritone/pathing/movement/Movement.java
@@ -95,7 +95,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
return getCost();
}
- protected void override(double cost) {
+ public void override(double cost) {
this.cost = cost;
}
diff --git a/src/main/java/baritone/pathing/path/CutoffPath.java b/src/main/java/baritone/pathing/path/CutoffPath.java
index 9714d8ce7..30b2d4e93 100644
--- a/src/main/java/baritone/pathing/path/CutoffPath.java
+++ b/src/main/java/baritone/pathing/path/CutoffPath.java
@@ -21,11 +21,12 @@ import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
import baritone.api.utils.BetterBlockPos;
+import baritone.utils.pathing.PathBase;
import java.util.Collections;
import java.util.List;
-public class CutoffPath implements IPath {
+public class CutoffPath extends PathBase {
private final List path;
diff --git a/src/main/java/baritone/pathing/path/SplicedPath.java b/src/main/java/baritone/pathing/path/SplicedPath.java
index 33b0b97f5..5048a84a0 100644
--- a/src/main/java/baritone/pathing/path/SplicedPath.java
+++ b/src/main/java/baritone/pathing/path/SplicedPath.java
@@ -21,10 +21,11 @@ import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
import baritone.api.utils.BetterBlockPos;
+import baritone.utils.pathing.PathBase;
import java.util.*;
-public class SplicedPath implements IPath {
+public class SplicedPath extends PathBase {
private final List path;
private final List movements;
diff --git a/src/main/java/baritone/process/GetToBlockProcess.java b/src/main/java/baritone/process/GetToBlockProcess.java
index 94e02e03a..241fafa18 100644
--- a/src/main/java/baritone/process/GetToBlockProcess.java
+++ b/src/main/java/baritone/process/GetToBlockProcess.java
@@ -28,6 +28,7 @@ import baritone.utils.BaritoneProcessHelper;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -44,7 +45,8 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
@Override
public void getToBlock(Block block) {
gettingTo = block;
- rescan();
+ knownLocations = null;
+ rescan(new ArrayList<>());
}
@Override
@@ -55,7 +57,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
@Override
public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) {
if (knownLocations == null) {
- rescan();
+ rescan(new ArrayList<>());
}
if (knownLocations.isEmpty()) {
logDirect("No known locations of " + gettingTo + ", canceling GetToBlock");
@@ -73,7 +75,8 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
}
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
- Baritone.getExecutor().execute(this::rescan);
+ List current = new ArrayList<>(knownLocations);
+ Baritone.getExecutor().execute(() -> rescan(current));
}
Goal goal = new GoalComposite(knownLocations.stream().map(GoalGetToBlock::new).toArray(Goal[]::new));
if (goal.isInGoal(playerFeet())) {
@@ -93,7 +96,7 @@ public class GetToBlockProcess extends BaritoneProcessHelper implements IGetToBl
return "Get To Block " + gettingTo;
}
- private void rescan() {
- knownLocations = MineProcess.searchWorld(Collections.singletonList(gettingTo), 64, world());
+ private void rescan(List known) {
+ knownLocations = MineProcess.searchWorld(Collections.singletonList(gettingTo), 64, world(), known);
}
}
\ No newline at end of file
diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java
index bfceac75d..1db47fc88 100644
--- a/src/main/java/baritone/process/MineProcess.java
+++ b/src/main/java/baritone/process/MineProcess.java
@@ -56,6 +56,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
private List mining;
private List knownOreLocations;
private BlockPos branchPoint;
+ private GoalRunAway branchPointRunaway;
private int desiredQuantity;
private int tickCount;
@@ -87,7 +88,8 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
}
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
if (mineGoalUpdateInterval != 0 && tickCount++ % mineGoalUpdateInterval == 0) { // big brain
- baritone.getExecutor().execute(this::rescan);
+ List curr = new ArrayList<>(knownOreLocations);
+ baritone.getExecutor().execute(() -> rescan(curr));
}
if (Baritone.settings().legitMine.get()) {
addNearby();
@@ -99,7 +101,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
cancel();
return null;
}
- return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH);
+ return new PathingCommand(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH);
}
@Override
@@ -126,31 +128,37 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return null;
}
// only in non-Xray mode (aka legit mode) do we do this
+ int y = Baritone.settings().legitMineYLevel.get();
if (branchPoint == null) {
- int y = Baritone.settings().legitMineYLevel.get();
if (!baritone.getPathingBehavior().isPathing() && playerFeet().y == y) {
// cool, path is over and we are at desired y
branchPoint = playerFeet();
+ branchPointRunaway = null;
} else {
return new GoalYLevel(y);
}
}
-
- if (playerFeet().equals(branchPoint)) {
- // TODO mine 1x1 shafts to either side
- branchPoint = branchPoint.north(10);
+ // TODO shaft mode, mine 1x1 shafts to either side
+ // TODO also, see if the GoalRunAway with maintain Y at 11 works even from the surface
+ if (branchPointRunaway == null) {
+ branchPointRunaway = new GoalRunAway(1, Optional.of(y), branchPoint) {
+ @Override
+ public boolean isInGoal(int x, int y, int z) {
+ return false;
+ }
+ };
}
- return new GoalBlock(branchPoint);
+ return branchPointRunaway;
}
- private void rescan() {
+ private void rescan(List already) {
if (mining == null) {
return;
}
if (Baritone.settings().legitMine.get()) {
return;
}
- List locs = searchWorld(mining, ORE_LOCATIONS_COUNT, world());
+ List locs = searchWorld(mining, ORE_LOCATIONS_COUNT, world(), already);
locs.addAll(droppedItemsScan(mining, world()));
if (locs.isEmpty()) {
logDebug("No locations for " + mining + " known, cancelling");
@@ -205,7 +213,10 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
return ret;
}
- public static List searchWorld(List mining, int max, World world) {
+ /*public static List searchWorld(List mining, int max, World world) {
+
+ }*/
+ public static List searchWorld(List mining, int max, World world, List alreadyKnown) {
List locs = new ArrayList<>();
List uninteresting = new ArrayList<>();
//long b = System.currentTimeMillis();
@@ -225,6 +236,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
}
+ locs.addAll(alreadyKnown);
return prune(locs, mining, max, world);
}
@@ -283,6 +295,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro
this.desiredQuantity = quantity;
this.knownOreLocations = new ArrayList<>();
this.branchPoint = null;
- rescan();
+ this.branchPointRunaway = null;
+ rescan(new ArrayList<>());
}
}
diff --git a/src/main/java/baritone/utils/PathingControlManager.java b/src/main/java/baritone/utils/PathingControlManager.java
index e75f7796f..5d1b03038 100644
--- a/src/main/java/baritone/utils/PathingControlManager.java
+++ b/src/main/java/baritone/utils/PathingControlManager.java
@@ -78,7 +78,7 @@ public class PathingControlManager {
break;
case FORCE_REVALIDATE_GOAL_AND_PATH:
p.secretInternalSetGoalAndPath(cmd.goal);
- if (cmd.goal == null || revalidateGoal(cmd.goal)) {
+ if (cmd.goal == null || forceRevalidate(cmd.goal) || revalidateGoal(cmd.goal)) {
// pwnage
p.cancelSegmentIfSafe();
}
@@ -100,6 +100,17 @@ public class PathingControlManager {
}
}
+ public boolean forceRevalidate(Goal newGoal) {
+ PathExecutor current = baritone.getPathingBehavior().getCurrent();
+ if (current != null) {
+ if (newGoal.isInGoal(current.getPath().getDest())) {
+ return false;
+ }
+ return !newGoal.toString().equals(current.getPath().getGoal().toString());
+ }
+ return false;
+ }
+
public boolean revalidateGoal(Goal newGoal) {
PathExecutor current = baritone.getPathingBehavior().getCurrent();
if (current != null) {
diff --git a/src/main/java/baritone/utils/pathing/PathBase.java b/src/main/java/baritone/utils/pathing/PathBase.java
new file mode 100644
index 000000000..57ee941d4
--- /dev/null
+++ b/src/main/java/baritone/utils/pathing/PathBase.java
@@ -0,0 +1,52 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.utils.pathing;
+
+import baritone.api.BaritoneAPI;
+import baritone.api.pathing.calc.IPath;
+import baritone.api.pathing.goals.Goal;
+import baritone.pathing.path.CutoffPath;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.chunk.EmptyChunk;
+
+public abstract class PathBase implements IPath {
+ @Override
+ public IPath cutoffAtLoadedChunks() {
+ for (int i = 0; i < positions().size(); i++) {
+ BlockPos pos = positions().get(i);
+ if (Minecraft.getMinecraft().world.getChunk(pos) instanceof EmptyChunk) {
+ return new CutoffPath(this, i);
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public IPath staticCutoff(Goal destination) {
+ if (length() < BaritoneAPI.getSettings().pathCutoffMinimumLength.get()) {
+ return this;
+ }
+ if (destination == null || destination.isInGoal(getDest())) {
+ return this;
+ }
+ double factor = BaritoneAPI.getSettings().pathCutoffFactor.get();
+ int newLength = (int) ((length() - 1) * factor);
+ return new CutoffPath(this, newLength);
+ }
+}