parent
cbc8a6d45b
commit
9c93d3a474
@ -377,6 +377,16 @@ public class Settings {
|
|||||||
*/
|
*/
|
||||||
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we are more than 500 movements into the current path, discard the oldest segments, as they are no longer useful
|
||||||
|
*/
|
||||||
|
public Setting<Integer> maxPathHistoryLength = new Setting<>(500);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the current path is too long, cut off this many movements from the beginning.
|
||||||
|
*/
|
||||||
|
public Setting<Integer> pathHistoryCutoffAmount = new Setting<>(100);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rescan for the goal once every 5 ticks.
|
* Rescan for the goal once every 5 ticks.
|
||||||
* Set to 0 to disable.
|
* Set to 0 to disable.
|
||||||
|
@ -21,6 +21,7 @@ import baritone.api.Settings;
|
|||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
import baritone.api.pathing.movement.IMovement;
|
import baritone.api.pathing.movement.IMovement;
|
||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -132,4 +133,33 @@ public interface IPath {
|
|||||||
default IPath staticCutoff(Goal destination) {
|
default IPath staticCutoff(Goal destination) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a series of checks to ensure that the assembly of the path went as expected.
|
||||||
|
*/
|
||||||
|
default void sanityCheck() {
|
||||||
|
List<BetterBlockPos> path = positions();
|
||||||
|
List<IMovement> movements = movements();
|
||||||
|
if (!getSrc().equals(path.get(0))) {
|
||||||
|
throw new IllegalStateException("Start node does not equal first path element");
|
||||||
|
}
|
||||||
|
if (!getDest().equals(path.get(path.size() - 1))) {
|
||||||
|
throw new IllegalStateException("End node does not equal last path element");
|
||||||
|
}
|
||||||
|
if (path.size() != movements.size() + 1) {
|
||||||
|
throw new IllegalStateException("Size of path array is unexpected");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < path.size() - 1; i++) {
|
||||||
|
BlockPos src = path.get(i);
|
||||||
|
BlockPos dest = path.get(i + 1);
|
||||||
|
IMovement movement = movements.get(i);
|
||||||
|
if (!src.equals(movement.getSrc())) {
|
||||||
|
throw new IllegalStateException("Path source is not equal to the movement source");
|
||||||
|
}
|
||||||
|
if (!dest.equals(movement.getDest())) {
|
||||||
|
throw new IllegalStateException("Path destination is not equal to the movement destination");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,9 @@ import baritone.api.utils.BetterBlockPos;
|
|||||||
import baritone.api.utils.interfaces.IGoalRenderPos;
|
import baritone.api.utils.interfaces.IGoalRenderPos;
|
||||||
import baritone.pathing.calc.AStarPathFinder;
|
import baritone.pathing.calc.AStarPathFinder;
|
||||||
import baritone.pathing.calc.AbstractNodeCostSearch;
|
import baritone.pathing.calc.AbstractNodeCostSearch;
|
||||||
import baritone.pathing.calc.CutoffPath;
|
|
||||||
import baritone.pathing.movement.CalculationContext;
|
import baritone.pathing.movement.CalculationContext;
|
||||||
import baritone.pathing.movement.MovementHelper;
|
import baritone.pathing.movement.MovementHelper;
|
||||||
|
import baritone.pathing.path.CutoffPath;
|
||||||
import baritone.pathing.path.PathExecutor;
|
import baritone.pathing.path.PathExecutor;
|
||||||
import baritone.utils.BlockBreakHelper;
|
import baritone.utils.BlockBreakHelper;
|
||||||
import baritone.utils.Helper;
|
import baritone.utils.Helper;
|
||||||
@ -156,6 +156,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
|
|||||||
current.onTick();
|
current.onTick();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
current = current.trySplice(next);
|
||||||
|
if (next != null && current.getPath().getDest().equals(next.getPath().getDest())) {
|
||||||
|
next = null;
|
||||||
|
}
|
||||||
synchronized (pathCalcLock) {
|
synchronized (pathCalcLock) {
|
||||||
if (isPathCalcInProgress) {
|
if (isPathCalcInProgress) {
|
||||||
// if we aren't calculating right now
|
// if we aren't calculating right now
|
||||||
|
@ -24,6 +24,7 @@ import baritone.api.pathing.movement.IMovement;
|
|||||||
import baritone.api.utils.BetterBlockPos;
|
import baritone.api.utils.BetterBlockPos;
|
||||||
import baritone.pathing.movement.Movement;
|
import baritone.pathing.movement.Movement;
|
||||||
import baritone.pathing.movement.Moves;
|
import baritone.pathing.movement.Moves;
|
||||||
|
import baritone.pathing.path.CutoffPath;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.chunk.EmptyChunk;
|
import net.minecraft.world.chunk.EmptyChunk;
|
||||||
@ -104,32 +105,6 @@ class Path implements IPath {
|
|||||||
path.addAll(tempPath);
|
path.addAll(tempPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs a series of checks to ensure that the assembly of the path went as expected.
|
|
||||||
*/
|
|
||||||
private void sanityCheck() {
|
|
||||||
if (!start.equals(path.get(0))) {
|
|
||||||
throw new IllegalStateException("Start node does not equal first path element");
|
|
||||||
}
|
|
||||||
if (!end.equals(path.get(path.size() - 1))) {
|
|
||||||
throw new IllegalStateException("End node does not equal last path element");
|
|
||||||
}
|
|
||||||
if (path.size() != movements.size() + 1) {
|
|
||||||
throw new IllegalStateException("Size of path array is unexpected");
|
|
||||||
}
|
|
||||||
for (int i = 0; i < path.size() - 1; i++) {
|
|
||||||
BlockPos src = path.get(i);
|
|
||||||
BlockPos dest = path.get(i + 1);
|
|
||||||
Movement movement = movements.get(i);
|
|
||||||
if (!src.equals(movement.getSrc())) {
|
|
||||||
throw new IllegalStateException("Path source is not equal to the movement source");
|
|
||||||
}
|
|
||||||
if (!dest.equals(movement.getDest())) {
|
|
||||||
throw new IllegalStateException("Path destination is not equal to the movement destination");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void assembleMovements() {
|
private void assembleMovements() {
|
||||||
if (path.isEmpty() || !movements.isEmpty()) {
|
if (path.isEmpty() || !movements.isEmpty()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package baritone.pathing.calc;
|
package baritone.pathing.path;
|
||||||
|
|
||||||
import baritone.api.pathing.calc.IPath;
|
import baritone.api.pathing.calc.IPath;
|
||||||
import baritone.api.pathing.goals.Goal;
|
import baritone.api.pathing.goals.Goal;
|
||||||
@ -35,11 +35,16 @@ public class CutoffPath implements IPath {
|
|||||||
|
|
||||||
private final Goal goal;
|
private final Goal goal;
|
||||||
|
|
||||||
CutoffPath(IPath prev, int lastPositionToInclude) {
|
public CutoffPath(IPath prev, int firstPositionToInclude, int lastPositionToInclude) {
|
||||||
path = prev.positions().subList(0, lastPositionToInclude + 1);
|
path = prev.positions().subList(firstPositionToInclude, lastPositionToInclude + 1);
|
||||||
movements = prev.movements().subList(0, lastPositionToInclude + 1);
|
movements = prev.movements().subList(firstPositionToInclude, lastPositionToInclude);
|
||||||
numNodes = prev.getNumNodesConsidered();
|
numNodes = prev.getNumNodesConsidered();
|
||||||
goal = prev.getGoal();
|
goal = prev.getGoal();
|
||||||
|
sanityCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CutoffPath(IPath prev, int lastPositionToInclude) {
|
||||||
|
this(prev, 0, lastPositionToInclude);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -454,6 +454,43 @@ public class PathExecutor implements IPathExecutor, Helper {
|
|||||||
return pathPosition;
|
return pathPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PathExecutor trySplice(PathExecutor next) {
|
||||||
|
if (next == null) {
|
||||||
|
return cutIfTooLong();
|
||||||
|
}
|
||||||
|
return SplicedPath.trySplice(path, next.path).map(path -> {
|
||||||
|
if (!path.getDest().equals(next.getPath().getDest())) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
PathExecutor ret = new PathExecutor(path);
|
||||||
|
ret.pathPosition = pathPosition;
|
||||||
|
ret.currentMovementOriginalCostEstimate = currentMovementOriginalCostEstimate;
|
||||||
|
ret.costEstimateIndex = costEstimateIndex;
|
||||||
|
ret.ticksOnCurrent = ticksOnCurrent;
|
||||||
|
return ret;
|
||||||
|
}).orElse(cutIfTooLong());
|
||||||
|
}
|
||||||
|
|
||||||
|
private PathExecutor cutIfTooLong() {
|
||||||
|
if (pathPosition > Baritone.settings().maxPathHistoryLength.get()) {
|
||||||
|
int cutoffAmt = Baritone.settings().pathHistoryCutoffAmount.get();
|
||||||
|
CutoffPath newPath = new CutoffPath(path, cutoffAmt, path.length() - 1);
|
||||||
|
if (!newPath.getDest().equals(path.getDest())) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
logDebug("Discarding earliest segment movements, length cut from " + path.length() + " to " + newPath.length());
|
||||||
|
PathExecutor ret = new PathExecutor(newPath);
|
||||||
|
ret.pathPosition = pathPosition - cutoffAmt;
|
||||||
|
ret.currentMovementOriginalCostEstimate = currentMovementOriginalCostEstimate;
|
||||||
|
if (costEstimateIndex != null) {
|
||||||
|
ret.costEstimateIndex = costEstimateIndex - cutoffAmt;
|
||||||
|
}
|
||||||
|
ret.ticksOnCurrent = ticksOnCurrent;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IPath getPath() {
|
public IPath getPath() {
|
||||||
return path;
|
return path;
|
||||||
|
88
src/main/java/baritone/pathing/path/SplicedPath.java
Normal file
88
src/main/java/baritone/pathing/path/SplicedPath.java
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package baritone.pathing.path;
|
||||||
|
|
||||||
|
import baritone.api.pathing.calc.IPath;
|
||||||
|
import baritone.api.pathing.goals.Goal;
|
||||||
|
import baritone.api.pathing.movement.IMovement;
|
||||||
|
import baritone.api.utils.BetterBlockPos;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class SplicedPath implements IPath {
|
||||||
|
private final List<BetterBlockPos> path;
|
||||||
|
|
||||||
|
private final List<IMovement> movements;
|
||||||
|
|
||||||
|
private final int numNodes;
|
||||||
|
|
||||||
|
private final Goal goal;
|
||||||
|
|
||||||
|
private SplicedPath(List<BetterBlockPos> path, List<IMovement> movements, int numNodesConsidered, Goal goal) {
|
||||||
|
this.path = path;
|
||||||
|
this.movements = movements;
|
||||||
|
this.numNodes = numNodesConsidered;
|
||||||
|
this.goal = goal;
|
||||||
|
sanityCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Goal getGoal() {
|
||||||
|
return goal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IMovement> movements() {
|
||||||
|
return Collections.unmodifiableList(movements);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<BetterBlockPos> positions() {
|
||||||
|
return Collections.unmodifiableList(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumNodesConsidered() {
|
||||||
|
return numNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Optional<SplicedPath> trySplice(IPath first, IPath second) {
|
||||||
|
if (second == null || first == null) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
if (!Objects.equals(first.getGoal(), second.getGoal())) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
if (!first.getDest().equals(second.getSrc())) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
HashSet<BetterBlockPos> a = new HashSet<>(first.positions());
|
||||||
|
for (int i = 1; i < second.length(); i++) {
|
||||||
|
if (a.contains(second.positions().get(i))) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<BetterBlockPos> positions = new ArrayList<>();
|
||||||
|
List<IMovement> movements = new ArrayList<>();
|
||||||
|
positions.addAll(first.positions());
|
||||||
|
positions.addAll(second.positions().subList(1, second.length()));
|
||||||
|
movements.addAll(first.movements());
|
||||||
|
movements.addAll(second.movements());
|
||||||
|
return Optional.of(new SplicedPath(positions, movements, first.getNumNodesConsidered() + second.getNumNodesConsidered(), first.getGoal()));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user