diff --git a/src/api/java/baritone/api/behavior/IPathingBehavior.java b/src/api/java/baritone/api/behavior/IPathingBehavior.java index e21d999d..cfc93d2d 100644 --- a/src/api/java/baritone/api/behavior/IPathingBehavior.java +++ b/src/api/java/baritone/api/behavior/IPathingBehavior.java @@ -17,7 +17,10 @@ package baritone.api.behavior; +import baritone.api.pathing.calc.IPathFinder; import baritone.api.pathing.goals.Goal; +import baritone.api.pathing.calc.IPath; +import baritone.api.pathing.path.IPathExecutor; import java.util.Optional; @@ -65,4 +68,30 @@ public interface IPathingBehavior extends IBehavior { * Cancels the pathing behavior or the current path calculation. */ void cancel(); + + /** + * Returns the current path, from the current path executor, if there is one. + * + * @return The current path + */ + default Optional getPath() { + return Optional.ofNullable(getCurrent()).map(IPathExecutor::getPath); + } + + /** + * @return The current path finder being executed + */ + Optional getPathFinder(); + + /** + * @return The current path executor + */ + IPathExecutor getCurrent(); + + /** + * Returns the next path executor, created when planning ahead. + * + * @return The next path executor + */ + IPathExecutor getNext(); } diff --git a/src/main/java/baritone/pathing/path/IPath.java b/src/api/java/baritone/api/pathing/calc/IPath.java similarity index 51% rename from src/main/java/baritone/pathing/path/IPath.java rename to src/api/java/baritone/api/pathing/calc/IPath.java index 0701abf6..c9d58818 100644 --- a/src/main/java/baritone/pathing/path/IPath.java +++ b/src/api/java/baritone/api/pathing/calc/IPath.java @@ -15,37 +15,35 @@ * along with Baritone. If not, see . */ -package baritone.pathing.path; +package baritone.api.pathing.calc; -import baritone.Baritone; +import baritone.api.Settings; import baritone.api.pathing.goals.Goal; -import baritone.pathing.movement.Movement; -import baritone.utils.Helper; -import baritone.utils.Utils; -import baritone.utils.pathing.BetterBlockPos; -import net.minecraft.client.Minecraft; -import net.minecraft.util.Tuple; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.chunk.EmptyChunk; +import baritone.api.pathing.movement.IMovement; +import baritone.api.utils.BetterBlockPos; import java.util.List; /** - * @author leijurv + * @author leijurv, Brady */ -public interface IPath extends Helper { +public interface IPath { /** * Ordered list of movements to carry out. * movements.get(i).getSrc() should equal positions.get(i) * movements.get(i).getDest() should equal positions.get(i+1) * movements.size() should equal positions.size()-1 + * + * @return All of the movements to carry out */ - List movements(); + List movements(); /** * All positions along the way. * Should begin with the same as getSrc and end with the same as getDest + * + * @return All of the positions along this path */ List positions(); @@ -53,10 +51,10 @@ public interface IPath extends Helper { * 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 void postProcess() {} /** - * Number of positions in this path + * Returns the number of positions in this path. Equivalent to {@code positions().size()}. * * @return Number of positions in this path */ @@ -65,74 +63,74 @@ public interface IPath extends Helper { } /** - * What goal was this path calculated towards? - * - * @return + * @return The goal that this path was calculated towards */ Goal getGoal(); - default Tuple closestPathPos() { - double best = -1; - BlockPos bestPos = null; - for (BlockPos pos : positions()) { - double dist = Utils.playerDistanceToCenter(pos); - if (dist < best || best == -1) { - best = dist; - bestPos = pos; - } - } - return new Tuple<>(best, bestPos); - } + /** + * Returns the number of nodes that were considered during calculation before + * this path was found. + * + * @return The number of nodes that were considered before finding this path + */ + int getNumNodesConsidered(); /** - * Where does this path start + * Returns the start position of this path. This is the first element in the + * {@link List} that is returned by {@link IPath#positions()}. + * + * @return The start position of this path */ default BetterBlockPos getSrc() { return positions().get(0); } /** - * Where does this path end + * Returns the end position of this path. This is the last element in the + * {@link List} that is returned by {@link IPath#positions()}. + * + * @return The end position of this path. */ default BetterBlockPos getDest() { List pos = positions(); return pos.get(pos.size() - 1); } + /** + * Returns the estimated number of ticks to complete the path from the given node index. + * + * @param pathPosition The index of the node we're calculating from + * @return The estimated number of ticks remaining frm the given position + */ default double ticksRemainingFrom(int pathPosition) { double sum = 0; //this is fast because we aren't requesting recalculation, it's just cached for (int i = pathPosition; i < movements().size(); i++) { - sum += movements().get(i).getCost(null); + sum += movements().get(i).getCost(); } return sum; } - int getNumNodesConsidered(); - + /** + * Cuts off this path at the loaded chunk border, and returns the resulting path. Default + * implementation just returns this path, without the intended functionality. + * + * @return The result of this cut-off operation + */ default IPath cutoffAtLoadedChunks() { - for (int i = 0; i < positions().size(); i++) { - BlockPos pos = positions().get(i); - if (Minecraft.getMinecraft().world.getChunk(pos) instanceof EmptyChunk) { - logDebug("Cutting off path at edge of loaded chunks"); - logDebug("Length decreased by " + (positions().size() - i - 1)); - return new CutoffPath(this, i); - } - } - logDebug("Path ends within loaded chunks"); return this; } + /** + * Cuts off this path using the min length and cutoff factor settings, and returns the resulting path. + * Default implementation just returns this path, without the intended functionality. + * + * @see Settings#pathCutoffMinimumLength + * @see Settings#pathCutoffFactor + * + * @return The result of this cut-off operation + */ default IPath staticCutoff(Goal destination) { - if (length() < Baritone.settings().pathCutoffMinimumLength.get()) { - return this; - } - if (destination == null || destination.isInGoal(getDest())) { - return this; - } - double factor = Baritone.settings().pathCutoffFactor.get(); - int newLength = (int) (length() * factor); - logDebug("Static cutoff " + length() + " to " + newLength); - return new CutoffPath(this, newLength); + return this; } } diff --git a/src/main/java/baritone/pathing/calc/IPathFinder.java b/src/api/java/baritone/api/pathing/calc/IPathFinder.java similarity index 96% rename from src/main/java/baritone/pathing/calc/IPathFinder.java rename to src/api/java/baritone/api/pathing/calc/IPathFinder.java index e6f3be06..446f7e05 100644 --- a/src/main/java/baritone/pathing/calc/IPathFinder.java +++ b/src/api/java/baritone/api/pathing/calc/IPathFinder.java @@ -15,10 +15,9 @@ * along with Baritone. If not, see . */ -package baritone.pathing.calc; +package baritone.api.pathing.calc; import baritone.api.pathing.goals.Goal; -import baritone.pathing.path.IPath; import java.util.Optional; diff --git a/src/api/java/baritone/api/pathing/movement/IMovement.java b/src/api/java/baritone/api/pathing/movement/IMovement.java new file mode 100644 index 00000000..7b3eca5f --- /dev/null +++ b/src/api/java/baritone/api/pathing/movement/IMovement.java @@ -0,0 +1,67 @@ +/* + * 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.pathing.movement; + +import baritone.api.utils.BetterBlockPos; +import net.minecraft.util.math.BlockPos; + +import java.util.List; + +/** + * @author Brady + * @since 10/8/2018 + */ +public interface IMovement { + + double getCost(); + + MovementStatus update(); + + /** + * Resets the current state status to {@link MovementStatus#PREPPING} + */ + void reset(); + + /** + * Resets the cache for special break, place, and walk into blocks + */ + void resetBlockCache(); + + /** + * @return Whether or not it is safe to cancel the current movement state + */ + boolean safeToCancel(); + + double recalculateCost(); + + double calculateCostWithoutCaching(); + + boolean calculatedWhileLoaded(); + + BetterBlockPos getSrc(); + + BetterBlockPos getDest(); + + BlockPos getDirection(); + + List toBreak(); + + List toPlace(); + + List toWalkInto(); +} diff --git a/src/api/java/baritone/api/pathing/movement/MovementStatus.java b/src/api/java/baritone/api/pathing/movement/MovementStatus.java new file mode 100644 index 00000000..0190f8e1 --- /dev/null +++ b/src/api/java/baritone/api/pathing/movement/MovementStatus.java @@ -0,0 +1,74 @@ +/* + * 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.pathing.movement; + +/** + * @author Brady + * @since 10/8/2018 + */ +public enum MovementStatus { + + /** + * We are preparing the movement to be executed. This is when any blocks obstructing the destination are broken. + */ + PREPPING(false), + + /** + * We are waiting for the movement to begin, after {@link MovementStatus#PREPPING}. + */ + WAITING(false), + + /** + * The movement is currently in progress, after {@link MovementStatus#WAITING} + */ + RUNNING(false), + + /** + * The movement has been completed and we are at our destination + */ + SUCCESS(true), + + /** + * There was a change in state between calculation and actual + * movement execution, and the movement has now become impossible. + */ + UNREACHABLE(true), + + /** + * Unused + */ + FAILED(true), + + /** + * "Unused" + */ + CANCELED(true); + + /** + * Whether or not this status indicates a complete movement. + */ + private final boolean complete; + + MovementStatus(boolean complete) { + this.complete = complete; + } + + public final boolean isComplete() { + return this.complete; + } +} diff --git a/src/api/java/baritone/api/pathing/path/IPathExecutor.java b/src/api/java/baritone/api/pathing/path/IPathExecutor.java new file mode 100644 index 00000000..f72060dc --- /dev/null +++ b/src/api/java/baritone/api/pathing/path/IPathExecutor.java @@ -0,0 +1,29 @@ +/* + * 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.pathing.path; + +import baritone.api.pathing.calc.IPath; + +/** + * @author Brady + * @since 10/8/2018 + */ +public interface IPathExecutor { + + IPath getPath(); +} diff --git a/src/main/java/baritone/utils/pathing/BetterBlockPos.java b/src/api/java/baritone/api/utils/BetterBlockPos.java similarity index 86% rename from src/main/java/baritone/utils/pathing/BetterBlockPos.java rename to src/api/java/baritone/api/utils/BetterBlockPos.java index e81319db..a1a3cb32 100644 --- a/src/main/java/baritone/utils/pathing/BetterBlockPos.java +++ b/src/api/java/baritone/api/utils/BetterBlockPos.java @@ -15,9 +15,8 @@ * along with Baritone. If not, see . */ -package baritone.utils.pathing; +package baritone.api.utils; -import baritone.pathing.calc.AbstractNodeCostSearch; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; @@ -54,11 +53,30 @@ public final class BetterBlockPos extends BlockPos { @Override public int hashCode() { - return (int) AbstractNodeCostSearch.posHash(x, y, z); + return (int) longHash(x, y, z); } public static long longHash(BetterBlockPos pos) { - return AbstractNodeCostSearch.posHash(pos.x, pos.y, pos.z); + return longHash(pos.x, pos.y, pos.z); + } + + public static long longHash(int x, int y, int z) { + /* + * This is the hashcode implementation of Vec3i (the superclass of the class which I shall not name) + * + * public int hashCode() { + * return (this.getY() + this.getZ() * 31) * 31 + this.getX(); + * } + * + * That is terrible and has tons of collisions and makes the HashMap terribly inefficient. + * + * That's why we grab out the X, Y, Z and calculate our own hashcode + */ + long hash = 3241; + hash = 3457689L * hash + x; + hash = 8734625L * hash + y; + hash = 2873465L * hash + z; + return hash; } @Override diff --git a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java index 2f0d1ab4..5d2ed420 100644 --- a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java +++ b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java @@ -40,7 +40,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; /** diff --git a/src/main/java/baritone/behavior/MineBehavior.java b/src/main/java/baritone/behavior/MineBehavior.java index 0f1a6b34..205c677d 100644 --- a/src/main/java/baritone/behavior/MineBehavior.java +++ b/src/main/java/baritone/behavior/MineBehavior.java @@ -22,13 +22,13 @@ import baritone.api.behavior.IMineBehavior; import baritone.api.event.events.PathEvent; import baritone.api.event.events.TickEvent; import baritone.api.pathing.goals.Goal; +import baritone.api.pathing.goals.GoalBlock; +import baritone.api.pathing.goals.GoalComposite; +import baritone.api.pathing.goals.GoalTwoBlocks; import baritone.cache.CachedChunk; import baritone.cache.ChunkPacker; import baritone.cache.WorldProvider; import baritone.cache.WorldScanner; -import baritone.api.pathing.goals.GoalBlock; -import baritone.api.pathing.goals.GoalComposite; -import baritone.api.pathing.goals.GoalTwoBlocks; import baritone.utils.BlockStateInterface; import baritone.utils.Helper; import net.minecraft.block.Block; diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 2092c656..e91769b8 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -25,18 +25,19 @@ import baritone.api.event.events.RenderEvent; import baritone.api.event.events.TickEvent; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalXZ; +import baritone.pathing.calc.CutoffPath; +import baritone.api.pathing.calc.IPath; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.pathing.calc.AStarPathFinder; import baritone.pathing.calc.AbstractNodeCostSearch; -import baritone.pathing.calc.IPathFinder; +import baritone.api.pathing.calc.IPathFinder; import baritone.pathing.movement.MovementHelper; -import baritone.pathing.path.IPath; import baritone.pathing.path.PathExecutor; import baritone.utils.BlockBreakHelper; import baritone.utils.BlockStateInterface; import baritone.utils.Helper; import baritone.utils.PathRenderer; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.world.chunk.EmptyChunk; @@ -190,19 +191,19 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, return goal; } + @Override public PathExecutor getCurrent() { return current; } + @Override public PathExecutor getNext() { return next; } - // TODO: Expose this method in the API? - // In order to do so, we'd need to move over IPath which has a whole lot of references to other - // things that may not need to be exposed necessarily, so we'll need to figure that out. - public Optional getPath() { - return Optional.ofNullable(current).map(PathExecutor::getPath); + @Override + public Optional getPathFinder() { + return Optional.ofNullable(AbstractNodeCostSearch.currentlyRunning()); } @Override @@ -283,9 +284,30 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, Optional path = findPath(start, previous); if (Baritone.settings().cutoffAtLoadBoundary.get()) { - path = path.map(IPath::cutoffAtLoadedChunks); + path = path.map(p -> { + IPath result = p.cutoffAtLoadedChunks(); + + if (result instanceof CutoffPath) { + logDebug("Cutting off path at edge of loaded chunks"); + logDebug("Length decreased by " + (p.length() - result.length())); + } else { + logDebug("Path ends within loaded chunks"); + } + + return result; + }); } - Optional executor = path.map(p -> p.staticCutoff(goal)).map(PathExecutor::new); + + Optional executor = path.map(p -> { + IPath result = p.staticCutoff(goal); + + if (result instanceof CutoffPath) { + logDebug("Static cutoff " + p.length() + " to " + result.length()); + } + + return result; + }).map(PathExecutor::new); + synchronized (pathPlanLock) { if (current == null) { if (executor.isPresent()) { diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index 583428e9..f4adc7e2 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -20,10 +20,11 @@ package baritone.pathing.calc; import baritone.Baritone; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.movement.ActionCosts; +import baritone.api.pathing.calc.IPath; +import baritone.api.utils.BetterBlockPos; import baritone.pathing.calc.openset.BinaryHeapOpenSet; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Moves; -import baritone.pathing.path.IPath; import baritone.utils.BlockStateInterface; import baritone.utils.Helper; import baritone.utils.pathing.MutableMoveResult; @@ -47,7 +48,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel @Override protected Optional calculate0(long timeout) { - startNode = getNodeAtPosition(startX, startY, startZ, posHash(startX, startY, startZ)); + startNode = getNodeAtPosition(startX, startY, startZ, BetterBlockPos.longHash(startX, startY, startZ)); startNode.cost = 0; startNode.combinedCost = startNode.estimatedCostToGoal; BinaryHeapOpenSet openSet = new BinaryHeapOpenSet(); @@ -122,7 +123,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel if (actionCost <= 0) { throw new IllegalStateException(moves + " calculated implausible cost " + actionCost); } - long hashCode = posHash(res.x, res.y, res.z); + long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z); if (favoring && favored.contains(hashCode)) { // see issue #18 actionCost *= favorCoeff; diff --git a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java index 68a523fa..424c512e 100644 --- a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java +++ b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java @@ -18,8 +18,9 @@ package baritone.pathing.calc; import baritone.Baritone; +import baritone.api.pathing.calc.IPathFinder; import baritone.api.pathing.goals.Goal; -import baritone.pathing.path.IPath; +import baritone.api.pathing.calc.IPath; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import java.util.Optional; @@ -88,7 +89,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { this.cancelRequested = false; try { Optional path = calculate0(timeout); - path.ifPresent(IPath::postprocess); + path.ifPresent(IPath::postProcess); isFinished = true; return path; } finally { @@ -140,25 +141,6 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { return node; } - public static long posHash(int x, int y, int z) { - /* - * This is the hashcode implementation of Vec3i (the superclass of the class which I shall not name) - * - * public int hashCode() { - * return (this.getY() + this.getZ() * 31) * 31 + this.getX(); - * } - * - * That is terrible and has tons of collisions and makes the HashMap terribly inefficient. - * - * That's why we grab out the X, Y, Z and calculate our own hashcode - */ - long hash = 3241; - hash = 3457689L * hash + x; - hash = 8734625L * hash + y; - hash = 2873465L * hash + z; - return hash; - } - public static void forceCancel() { currentlyRunning = null; } @@ -225,4 +207,8 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { public static Optional getCurrentlyRunning() { return Optional.ofNullable(currentlyRunning); } + + public static AbstractNodeCostSearch currentlyRunning() { + return currentlyRunning; + } } diff --git a/src/main/java/baritone/pathing/path/CutoffPath.java b/src/main/java/baritone/pathing/calc/CutoffPath.java similarity index 83% rename from src/main/java/baritone/pathing/path/CutoffPath.java rename to src/main/java/baritone/pathing/calc/CutoffPath.java index e517452e..bcf66b79 100644 --- a/src/main/java/baritone/pathing/path/CutoffPath.java +++ b/src/main/java/baritone/pathing/calc/CutoffPath.java @@ -15,11 +15,12 @@ * along with Baritone. If not, see . */ -package baritone.pathing.path; +package baritone.pathing.calc; import baritone.api.pathing.goals.Goal; -import baritone.pathing.movement.Movement; -import baritone.utils.pathing.BetterBlockPos; +import baritone.api.pathing.movement.IMovement; +import baritone.api.pathing.calc.IPath; +import baritone.api.utils.BetterBlockPos; import java.util.Collections; import java.util.List; @@ -28,13 +29,13 @@ public class CutoffPath implements IPath { private final List path; - private final List movements; + private final List movements; private final int numNodes; private final Goal goal; - public CutoffPath(IPath prev, int lastPositionToInclude) { + CutoffPath(IPath prev, int lastPositionToInclude) { path = prev.positions().subList(0, lastPositionToInclude + 1); movements = prev.movements().subList(0, lastPositionToInclude + 1); numNodes = prev.getNumNodesConsidered(); @@ -47,7 +48,7 @@ public class CutoffPath implements IPath { } @Override - public List movements() { + public List movements() { return Collections.unmodifiableList(movements); } diff --git a/src/main/java/baritone/pathing/calc/Path.java b/src/main/java/baritone/pathing/calc/Path.java index f1a31553..f7bf9638 100644 --- a/src/main/java/baritone/pathing/calc/Path.java +++ b/src/main/java/baritone/pathing/calc/Path.java @@ -17,12 +17,16 @@ package baritone.pathing.calc; +import baritone.api.BaritoneAPI; import baritone.api.pathing.goals.Goal; +import baritone.api.pathing.movement.IMovement; +import baritone.api.pathing.calc.IPath; +import baritone.api.utils.BetterBlockPos; import baritone.pathing.movement.Movement; import baritone.pathing.movement.Moves; -import baritone.pathing.path.IPath; -import baritone.utils.pathing.BetterBlockPos; +import net.minecraft.client.Minecraft; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.chunk.EmptyChunk; import java.util.ArrayList; import java.util.Collections; @@ -149,7 +153,7 @@ class Path implements IPath { } @Override - public void postprocess() { + public void postProcess() { if (verified) { throw new IllegalStateException(); } @@ -161,7 +165,7 @@ class Path implements IPath { } @Override - public List movements() { + public List movements() { if (!verified) { throw new IllegalStateException(); } @@ -187,4 +191,28 @@ 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/calc/PathNode.java b/src/main/java/baritone/pathing/calc/PathNode.java index 207b3d65..e12a2458 100644 --- a/src/main/java/baritone/pathing/calc/PathNode.java +++ b/src/main/java/baritone/pathing/calc/PathNode.java @@ -19,6 +19,7 @@ package baritone.pathing.calc; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.movement.ActionCosts; +import baritone.api.utils.BetterBlockPos; /** * A node in the path, containing the cost and steps to get to it. @@ -85,7 +86,7 @@ public final class PathNode { */ @Override public int hashCode() { - return (int) AbstractNodeCostSearch.posHash(x, y, z); + return (int) BetterBlockPos.longHash(x, y, z); } @Override diff --git a/src/main/java/baritone/pathing/movement/Movement.java b/src/main/java/baritone/pathing/movement/Movement.java index 2b87c1e0..92a1f4db 100644 --- a/src/main/java/baritone/pathing/movement/Movement.java +++ b/src/main/java/baritone/pathing/movement/Movement.java @@ -18,12 +18,13 @@ package baritone.pathing.movement; import baritone.Baritone; +import baritone.api.pathing.movement.IMovement; +import baritone.api.pathing.movement.MovementStatus; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Rotation; import baritone.behavior.LookBehavior; import baritone.behavior.LookBehaviorUtils; -import baritone.pathing.movement.MovementState.MovementStatus; import baritone.utils.*; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.block.BlockLiquid; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; @@ -36,7 +37,7 @@ import java.util.Optional; import static baritone.utils.InputOverrideHandler.Input; -public abstract class Movement implements Helper, MovementHelper { +public abstract class Movement implements IMovement, Helper, MovementHelper { protected static final EnumFacing[] HORIZONTALS = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST}; @@ -77,24 +78,27 @@ public abstract class Movement implements Helper, MovementHelper { this(src, dest, toBreak, null); } - public double getCost(CalculationContext context) { + @Override + public double getCost() { if (cost == null) { - cost = calculateCost(context != null ? context : new CalculationContext()); + cost = calculateCost(new CalculationContext()); } return cost; } protected abstract double calculateCost(CalculationContext context); + @Override public double recalculateCost() { cost = null; - return getCost(null); + return getCost(); } protected void override(double cost) { this.cost = cost; } + @Override public double calculateCostWithoutCaching() { return calculateCost(new CalculationContext()); } @@ -105,6 +109,7 @@ public abstract class Movement implements Helper, MovementHelper { * * @return Status */ + @Override public MovementStatus update() { player().capabilities.allowFlying = false; MovementState latestState = updateState(currentState); @@ -147,7 +152,8 @@ public abstract class Movement implements Helper, MovementHelper { currentState = latestState; - if (isFinished()) { + // If the current status indicates a completed movement + if (currentState.getStatus().isComplete()) { onFinish(latestState); } @@ -187,6 +193,7 @@ public abstract class Movement implements Helper, MovementHelper { return true; } + @Override public boolean safeToCancel() { return safeToCancel(currentState); } @@ -195,16 +202,12 @@ public abstract class Movement implements Helper, MovementHelper { return true; } - public boolean isFinished() { - return (currentState.getStatus() != MovementStatus.RUNNING - && currentState.getStatus() != MovementStatus.PREPPING - && currentState.getStatus() != MovementStatus.WAITING); - } - + @Override public BetterBlockPos getSrc() { return src; } + @Override public BetterBlockPos getDest() { return dest; } @@ -223,6 +226,7 @@ public abstract class Movement implements Helper, MovementHelper { currentState.setStatus(MovementStatus.CANCELED); } + @Override public void reset() { currentState = new MovementState().setStatus(MovementStatus.PREPPING); } @@ -247,6 +251,7 @@ public abstract class Movement implements Helper, MovementHelper { return state; } + @Override public BlockPos getDirection() { return getDest().subtract(getSrc()); } @@ -255,10 +260,19 @@ public abstract class Movement implements Helper, MovementHelper { calculatedWhileLoaded = !(world().getChunk(getDest()) instanceof EmptyChunk); } + @Override public boolean calculatedWhileLoaded() { return calculatedWhileLoaded; } + @Override + public void resetBlockCache() { + toBreakCached = null; + toPlaceCached = null; + toWalkIntoCached = null; + } + + @Override public List toBreak() { if (toBreakCached != null) { return toBreakCached; @@ -273,6 +287,7 @@ public abstract class Movement implements Helper, MovementHelper { return result; } + @Override public List toPlace() { if (toPlaceCached != null) { return toPlaceCached; @@ -285,6 +300,7 @@ public abstract class Movement implements Helper, MovementHelper { return result; } + @Override public List toWalkInto() { // overridden by movementdiagonal if (toWalkIntoCached == null) { toWalkIntoCached = new ArrayList<>(); diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index 28b14e9e..5b5be77e 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -19,11 +19,11 @@ package baritone.pathing.movement; import baritone.Baritone; import baritone.api.pathing.movement.ActionCosts; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Rotation; import baritone.behavior.LookBehaviorUtils; import baritone.pathing.movement.MovementState.MovementTarget; import baritone.utils.*; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.block.*; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.state.IBlockState; diff --git a/src/main/java/baritone/pathing/movement/MovementState.java b/src/main/java/baritone/pathing/movement/MovementState.java index 6d0262e6..db99ce5d 100644 --- a/src/main/java/baritone/pathing/movement/MovementState.java +++ b/src/main/java/baritone/pathing/movement/MovementState.java @@ -17,6 +17,7 @@ package baritone.pathing.movement; +import baritone.api.pathing.movement.MovementStatus; import baritone.api.utils.Rotation; import baritone.utils.InputOverrideHandler.Input; import net.minecraft.util.math.Vec3d; @@ -72,10 +73,6 @@ public class MovementState { return this.inputState; } - public enum MovementStatus { - PREPPING, WAITING, RUNNING, SUCCESS, UNREACHABLE, FAILED, CANCELED - } - public static class MovementTarget { /** diff --git a/src/main/java/baritone/pathing/movement/Moves.java b/src/main/java/baritone/pathing/movement/Moves.java index c5b1069d..3d53ff5b 100644 --- a/src/main/java/baritone/pathing/movement/Moves.java +++ b/src/main/java/baritone/pathing/movement/Moves.java @@ -17,8 +17,8 @@ package baritone.pathing.movement; +import baritone.api.utils.BetterBlockPos; import baritone.pathing.movement.movements.*; -import baritone.utils.pathing.BetterBlockPos; import baritone.utils.pathing.MutableMoveResult; import net.minecraft.util.EnumFacing; diff --git a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java index b5e21eea..6989179b 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java @@ -18,16 +18,16 @@ package baritone.pathing.movement.movements; import baritone.Baritone; +import baritone.api.pathing.movement.MovementStatus; +import baritone.api.utils.BetterBlockPos; import baritone.behavior.LookBehaviorUtils; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementState; -import baritone.pathing.movement.MovementState.MovementStatus; import baritone.utils.BlockStateInterface; import baritone.utils.InputOverrideHandler; import baritone.utils.Utils; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.block.BlockFalling; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java index 3bba5f1d..ba3deb7d 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java @@ -18,14 +18,14 @@ package baritone.pathing.movement.movements; import baritone.Baritone; +import baritone.api.pathing.movement.MovementStatus; +import baritone.api.utils.BetterBlockPos; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementState; -import baritone.pathing.movement.MovementState.MovementStatus; import baritone.utils.BlockStateInterface; import baritone.utils.InputOverrideHandler; -import baritone.utils.pathing.BetterBlockPos; import baritone.utils.pathing.MutableMoveResult; import net.minecraft.block.Block; import net.minecraft.block.BlockFalling; diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java b/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java index 58027a8d..8ff681c6 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDiagonal.java @@ -17,13 +17,14 @@ package baritone.pathing.movement.movements; +import baritone.api.pathing.movement.MovementStatus; +import baritone.api.utils.BetterBlockPos; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementState; import baritone.utils.BlockStateInterface; import baritone.utils.InputOverrideHandler; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; @@ -140,12 +141,12 @@ public class MovementDiagonal extends Movement { @Override public MovementState updateState(MovementState state) { super.updateState(state); - if (state.getStatus() != MovementState.MovementStatus.RUNNING) { + if (state.getStatus() != MovementStatus.RUNNING) { return state; } if (playerFeet().equals(dest)) { - state.setStatus(MovementState.MovementStatus.SUCCESS); + state.setStatus(MovementStatus.SUCCESS); return state; } if (!BlockStateInterface.isLiquid(playerFeet())) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDownward.java b/src/main/java/baritone/pathing/movement/movements/MovementDownward.java index 148dc3b3..0ac4f2b0 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDownward.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDownward.java @@ -17,12 +17,13 @@ package baritone.pathing.movement.movements; +import baritone.api.pathing.movement.MovementStatus; +import baritone.api.utils.BetterBlockPos; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementState; import baritone.utils.BlockStateInterface; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; @@ -64,12 +65,12 @@ public class MovementDownward extends Movement { @Override public MovementState updateState(MovementState state) { super.updateState(state); - if (state.getStatus() != MovementState.MovementStatus.RUNNING) { + if (state.getStatus() != MovementStatus.RUNNING) { return state; } if (playerFeet().equals(dest)) { - return state.setStatus(MovementState.MovementStatus.SUCCESS); + return state.setStatus(MovementStatus.SUCCESS); } double diffX = player().posX - (dest.getX() + 0.5); double diffZ = player().posZ - (dest.getZ() + 0.5); diff --git a/src/main/java/baritone/pathing/movement/movements/MovementFall.java b/src/main/java/baritone/pathing/movement/movements/MovementFall.java index f901c61f..e09eb579 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementFall.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementFall.java @@ -18,18 +18,18 @@ package baritone.pathing.movement.movements; import baritone.Baritone; +import baritone.api.pathing.movement.MovementStatus; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Rotation; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementState; -import baritone.pathing.movement.MovementState.MovementStatus; import baritone.pathing.movement.MovementState.MovementTarget; import baritone.utils.BlockStateInterface; import baritone.utils.InputOverrideHandler; import baritone.utils.RayTraceUtils; import baritone.utils.Utils; -import baritone.utils.pathing.BetterBlockPos; import baritone.utils.pathing.MutableMoveResult; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Items; diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java index e128bb3c..94b7dfea 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java @@ -18,6 +18,8 @@ package baritone.pathing.movement.movements; import baritone.Baritone; +import baritone.api.pathing.movement.MovementStatus; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Rotation; import baritone.behavior.LookBehaviorUtils; import baritone.pathing.movement.CalculationContext; @@ -25,7 +27,6 @@ import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.MovementState; import baritone.utils.*; -import baritone.utils.pathing.BetterBlockPos; import baritone.utils.pathing.MutableMoveResult; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; @@ -168,13 +169,13 @@ public class MovementParkour extends Movement { // 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; + return state.getStatus() != MovementStatus.RUNNING; } @Override public MovementState updateState(MovementState state) { super.updateState(state); - if (state.getStatus() != MovementState.MovementStatus.RUNNING) { + if (state.getStatus() != MovementStatus.RUNNING) { return state; } if (dist >= 4) { @@ -186,10 +187,10 @@ public class MovementParkour extends Movement { if (d == Blocks.VINE || d == Blocks.LADDER) { // it physically hurt me to add support for parkour jumping onto a vine // but i did it anyway - return state.setStatus(MovementState.MovementStatus.SUCCESS); + return state.setStatus(MovementStatus.SUCCESS); } if (player().posY - playerFeet().getY() < 0.094) { // lilypads - state.setStatus(MovementState.MovementStatus.SUCCESS); + state.setStatus(MovementStatus.SUCCESS); } } else if (!playerFeet().equals(src)) { if (playerFeet().equals(src.offset(direction)) || player().posY - playerFeet().getY() > 0.0001) { @@ -203,7 +204,7 @@ public class MovementParkour extends Movement { } if (MovementHelper.canPlaceAgainst(against1)) { if (!MovementHelper.throwaway(true)) {//get ready to place a throwaway block - return state.setStatus(MovementState.MovementStatus.UNREACHABLE); + return state.setStatus(MovementStatus.UNREACHABLE); } double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D; double faceY = (dest.getY() + against1.getY()) * 0.5D; diff --git a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java index be524185..60803a3c 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java @@ -17,6 +17,8 @@ package baritone.pathing.movement.movements; +import baritone.api.pathing.movement.MovementStatus; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Rotation; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; @@ -25,7 +27,6 @@ import baritone.pathing.movement.MovementState; import baritone.utils.BlockStateInterface; import baritone.utils.InputOverrideHandler; import baritone.utils.Utils; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.block.*; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -148,7 +149,7 @@ public class MovementPillar extends Movement { @Override public MovementState updateState(MovementState state) { super.updateState(state); - if (state.getStatus() != MovementState.MovementStatus.RUNNING) { + if (state.getStatus() != MovementStatus.RUNNING) { return state; } @@ -161,7 +162,7 @@ public class MovementPillar extends Movement { state.setInput(InputOverrideHandler.Input.MOVE_FORWARD, true); } if (playerFeet().equals(dest)) { - return state.setStatus(MovementState.MovementStatus.SUCCESS); + return state.setStatus(MovementStatus.SUCCESS); } return state; } @@ -178,11 +179,11 @@ public class MovementPillar extends Movement { BlockPos against = vine ? getAgainst(src) : src.offset(fromDown.getValue(BlockLadder.FACING).getOpposite()); if (against == null) { logDebug("Unable to climb vines"); - return state.setStatus(MovementState.MovementStatus.UNREACHABLE); + return state.setStatus(MovementStatus.UNREACHABLE); } if (playerFeet().equals(against.up()) || playerFeet().equals(dest)) { - return state.setStatus(MovementState.MovementStatus.SUCCESS); + return state.setStatus(MovementStatus.SUCCESS); } if (MovementHelper.isBottomSlab(src.down())) { state.setInput(InputOverrideHandler.Input.JUMP, true); @@ -198,7 +199,7 @@ public class MovementPillar extends Movement { } else { // Get ready to place a throwaway block if (!MovementHelper.throwaway(true)) { - return state.setStatus(MovementState.MovementStatus.UNREACHABLE); + return state.setStatus(MovementStatus.UNREACHABLE); } numTicks++; @@ -233,7 +234,7 @@ public class MovementPillar extends Movement { // If we are at our goal and the block below us is placed if (playerFeet().equals(dest) && blockIsThere) { - return state.setStatus(MovementState.MovementStatus.SUCCESS); + return state.setStatus(MovementStatus.SUCCESS); } return state; diff --git a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java index 7c4ba237..f029619a 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java @@ -18,6 +18,8 @@ package baritone.pathing.movement.movements; import baritone.Baritone; +import baritone.api.pathing.movement.MovementStatus; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Rotation; import baritone.behavior.LookBehaviorUtils; import baritone.pathing.movement.CalculationContext; @@ -27,7 +29,6 @@ import baritone.pathing.movement.MovementState; import baritone.utils.BlockStateInterface; import baritone.utils.InputOverrideHandler; import baritone.utils.Utils; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.block.*; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -144,13 +145,13 @@ public class MovementTraverse extends Movement { @Override public MovementState updateState(MovementState state) { super.updateState(state); - if (state.getStatus() != MovementState.MovementStatus.RUNNING) { + if (state.getStatus() != MovementStatus.RUNNING) { // if the setting is enabled if (!Baritone.settings().walkWhileBreaking.get()) { return state; } // and if we're prepping (aka mining the block in front) - if (state.getStatus() != MovementState.MovementStatus.PREPPING) { + if (state.getStatus() != MovementStatus.PREPPING) { return state; } // and if it's fine to walk into the blocks in front @@ -225,7 +226,7 @@ public class MovementTraverse extends Movement { if (isTheBridgeBlockThere) { if (playerFeet().equals(dest)) { - return state.setStatus(MovementState.MovementStatus.SUCCESS); + return state.setStatus(MovementStatus.SUCCESS); } if (wasTheBridgeBlockAlwaysThere && !BlockStateInterface.isLiquid(playerFeet())) { state.setInput(InputOverrideHandler.Input.SPRINT, true); @@ -248,7 +249,7 @@ public class MovementTraverse extends Movement { if (MovementHelper.canPlaceAgainst(against1)) { if (!MovementHelper.throwaway(true)) { // get ready to place a throwaway block logDebug("bb pls get me some blocks. dirt or cobble"); - return state.setStatus(MovementState.MovementStatus.UNREACHABLE); + return state.setStatus(MovementStatus.UNREACHABLE); } if (!Baritone.settings().assumeSafeWalk.get()) { state.setInput(InputOverrideHandler.Input.SNEAK, true); @@ -287,7 +288,7 @@ public class MovementTraverse extends Movement { // Out.log(from + " " + to + " " + faceX + "," + faceY + "," + faceZ + " " + whereAmI); if (!MovementHelper.throwaway(true)) {// get ready to place a throwaway block logDebug("bb pls get me some blocks. dirt or cobble"); - return state.setStatus(MovementState.MovementStatus.UNREACHABLE); + return state.setStatus(MovementStatus.UNREACHABLE); } double faceX = (dest.getX() + src.getX() + 1.0D) * 0.5D; double faceY = (dest.getY() + src.getY() - 1.0D) * 0.5D; @@ -324,7 +325,7 @@ public class MovementTraverse extends Movement { // 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()); + return state.getStatus() != MovementStatus.RUNNING || MovementHelper.canWalkOn(dest.down()); } @Override diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java index 4afd8b76..6fba09a3 100644 --- a/src/main/java/baritone/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/pathing/path/PathExecutor.java @@ -20,21 +20,23 @@ package baritone.pathing.path; import baritone.Baritone; import baritone.api.event.events.TickEvent; import baritone.api.pathing.movement.ActionCosts; +import baritone.api.pathing.movement.IMovement; +import baritone.api.pathing.movement.MovementStatus; +import baritone.api.pathing.calc.IPath; +import baritone.api.pathing.path.IPathExecutor; +import baritone.api.utils.BetterBlockPos; import baritone.pathing.calc.AbstractNodeCostSearch; import baritone.pathing.movement.CalculationContext; -import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; -import baritone.pathing.movement.MovementState; import baritone.pathing.movement.movements.*; import baritone.utils.*; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.init.Blocks; import net.minecraft.util.Tuple; import net.minecraft.util.math.BlockPos; import java.util.*; -import static baritone.pathing.movement.MovementState.MovementStatus.*; +import static baritone.api.pathing.movement.MovementStatus.*; /** * Behavior to execute a precomputed path. Does not (yet) deal with path segmentation or stitching @@ -42,7 +44,7 @@ import static baritone.pathing.movement.MovementState.MovementStatus.*; * * @author leijurv */ -public class PathExecutor implements Helper { +public class PathExecutor implements IPathExecutor, Helper { private static final double MAX_MAX_DIST_FROM_PATH = 3; private static final double MAX_DIST_FROM_PATH = 2; @@ -128,7 +130,7 @@ public class PathExecutor implements Helper { } } } - Tuple status = path.closestPathPos(); + Tuple status = closestPathPos(path); if (possiblyOffPath(status, MAX_DIST_FROM_PATH)) { ticksAway++; System.out.println("FAR AWAY FROM PATH FOR " + ticksAway + " TICKS. Current distance: " + status.getFirst() + ". Threshold: " + MAX_DIST_FROM_PATH); @@ -182,13 +184,11 @@ public class PathExecutor implements Helper { if (i < 0 || i >= path.movements().size()) { continue; } - Movement m = path.movements().get(i); + IMovement m = path.movements().get(i); HashSet prevBreak = new HashSet<>(m.toBreak()); HashSet prevPlace = new HashSet<>(m.toPlace()); HashSet prevWalkInto = new HashSet<>(m.toWalkInto()); - m.toBreakCached = null; - m.toPlaceCached = null; - m.toWalkIntoCached = null; + m.resetBlockCache(); if (!prevBreak.equals(new HashSet<>(m.toBreak()))) { recalcBP = true; } @@ -217,12 +217,12 @@ public class PathExecutor implements Helper { if (end - start > 0) { System.out.println("Recalculating break and place took " + (end - start) + "ms"); }*/ - Movement movement = path.movements().get(pathPosition); + IMovement movement = path.movements().get(pathPosition); boolean canCancel = movement.safeToCancel(); if (costEstimateIndex == null || costEstimateIndex != pathPosition) { costEstimateIndex = pathPosition; // do this only once, when the movement starts, and deliberately get the cost as cached when this path was calculated, not the cost as it is right now - currentMovementOriginalCostEstimate = movement.getCost(null); + currentMovementOriginalCostEstimate = movement.getCost(); for (int i = 1; i < Baritone.settings().costVerificationLookahead.get() && pathPosition + i < path.length() - 1; i++) { if (path.movements().get(pathPosition + i).calculateCostWithoutCaching() >= ActionCosts.COST_INF && canCancel) { logDebug("Something has changed in the world and a future movement has become impossible. Cancelling."); @@ -246,7 +246,7 @@ public class PathExecutor implements Helper { logDebug("Pausing since current best path is a backtrack"); return true; } - MovementState.MovementStatus movementStatus = movement.update(); + MovementStatus movementStatus = movement.update(); if (movementStatus == UNREACHABLE || movementStatus == FAILED) { logDebug("Movement returns status " + movementStatus); cancel(); @@ -274,6 +274,19 @@ public class PathExecutor implements Helper { return false; // movement is in progress } + private Tuple closestPathPos(IPath path) { + double best = -1; + BlockPos bestPos = null; + for (BlockPos pos : path.positions()) { + double dist = Utils.playerDistanceToCenter(pos); + if (dist < best || best == -1) { + best = dist; + bestPos = pos; + } + } + return new Tuple<>(best, bestPos); + } + private boolean shouldPause() { Optional current = AbstractNodeCostSearch.getCurrentlyRunning(); if (!current.isPresent()) { @@ -346,7 +359,7 @@ public class PathExecutor implements Helper { Baritone.INSTANCE.getInputOverrideHandler().setInputForceState(InputOverrideHandler.Input.SPRINT,false); // however, descend doesn't request sprinting, beceause it doesn't know the context of what movement comes after it - Movement current = path.movements().get(pathPosition); + IMovement current = path.movements().get(pathPosition); if (current instanceof MovementDescend && pathPosition < path.length() - 2) { // (dest - src) + dest is offset 1 more in the same direction @@ -361,7 +374,7 @@ public class PathExecutor implements Helper { } } - Movement next = path.movements().get(pathPosition + 1); + IMovement next = path.movements().get(pathPosition + 1); if (next instanceof MovementAscend && current.getDirection().up().equals(next.getDirection().down())) { // a descend then an ascend in the same direction if (!player().isSprinting()) { @@ -385,7 +398,7 @@ public class PathExecutor implements Helper { //logDebug("Turning off sprinting " + movement + " " + next + " " + movement.getDirection() + " " + next.getDirection().down() + " " + next.getDirection().down().equals(movement.getDirection())); } if (current instanceof MovementAscend && pathPosition != 0) { - Movement prev = path.movements().get(pathPosition - 1); + IMovement prev = path.movements().get(pathPosition - 1); if (prev instanceof MovementDescend && prev.getDirection().up().equals(current.getDirection().down())) { BlockPos center = current.getSrc().up(); if (player().posY >= center.getY()) { // playerFeet adds 0.1251 to account for soul sand @@ -400,7 +413,7 @@ public class PathExecutor implements Helper { player().setSprinting(false); } - private static boolean canSprintInto(Movement current, Movement next) { + private static boolean canSprintInto(IMovement current, IMovement next) { if (next instanceof MovementDescend) { if (next.getDirection().equals(current.getDirection())) { return true; @@ -438,6 +451,7 @@ public class PathExecutor implements Helper { return pathPosition; } + @Override public IPath getPath() { return path; } diff --git a/src/main/java/baritone/utils/ExampleBaritoneControl.java b/src/main/java/baritone/utils/ExampleBaritoneControl.java index 683ec62b..5f532b46 100644 --- a/src/main/java/baritone/utils/ExampleBaritoneControl.java +++ b/src/main/java/baritone/utils/ExampleBaritoneControl.java @@ -32,7 +32,6 @@ import baritone.cache.ChunkPacker; import baritone.cache.Waypoint; import baritone.cache.WorldProvider; import baritone.pathing.calc.AbstractNodeCostSearch; -import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; import baritone.pathing.movement.Moves; @@ -470,10 +469,10 @@ public class ExampleBaritoneControl extends Behavior implements Helper { while (moves.contains(null)) { moves.remove(null); } - moves.sort(Comparator.comparingDouble(movement -> movement.getCost(new CalculationContext()))); + moves.sort(Comparator.comparingDouble(Movement::getCost)); for (Movement move : moves) { String[] parts = move.getClass().toString().split("\\."); - double cost = move.getCost(new CalculationContext()); + double cost = move.getCost(); String strCost = cost + ""; if (cost >= ActionCosts.COST_INF) { strCost = "IMPOSSIBLE"; diff --git a/src/main/java/baritone/utils/Helper.java b/src/main/java/baritone/utils/Helper.java index a0ffdb96..f026ec38 100755 --- a/src/main/java/baritone/utils/Helper.java +++ b/src/main/java/baritone/utils/Helper.java @@ -18,8 +18,8 @@ package baritone.utils; import baritone.Baritone; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.Rotation; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.block.BlockSlab; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 6891a299..841876d8 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -23,12 +23,12 @@ import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalComposite; import baritone.api.pathing.goals.GoalTwoBlocks; import baritone.api.pathing.goals.GoalXZ; +import baritone.api.pathing.calc.IPath; +import baritone.api.utils.BetterBlockPos; import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.behavior.PathingBehavior; import baritone.pathing.calc.AbstractNodeCostSearch; -import baritone.pathing.path.IPath; import baritone.pathing.path.PathExecutor; -import baritone.utils.pathing.BetterBlockPos; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; diff --git a/src/test/java/baritone/utils/pathing/BetterBlockPosTest.java b/src/test/java/baritone/utils/pathing/BetterBlockPosTest.java index 13b76c73..a21f0cd4 100644 --- a/src/test/java/baritone/utils/pathing/BetterBlockPosTest.java +++ b/src/test/java/baritone/utils/pathing/BetterBlockPosTest.java @@ -17,6 +17,7 @@ package baritone.utils.pathing; +import baritone.api.utils.BetterBlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import org.junit.Test;