cutoff path up until movement failure, don't throw exception and fail entire path
This commit is contained in:
parent
4a1951b027
commit
96da078219
@ -52,7 +52,9 @@ public interface IPath {
|
|||||||
* This path is actually going to be executed in the world. Do whatever additional processing is required.
|
* 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)
|
* (as opposed to Path objects that are just constructed every frame for rendering)
|
||||||
*/
|
*/
|
||||||
default void postProcess() {}
|
default IPath postProcess() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of positions in this path. Equivalent to {@code positions().size()}.
|
* Returns the number of positions in this path. Equivalent to {@code positions().size()}.
|
||||||
|
@ -25,6 +25,7 @@ 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 baritone.pathing.path.CutoffPath;
|
||||||
|
import baritone.utils.Helper;
|
||||||
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;
|
||||||
@ -59,6 +60,8 @@ class Path implements IPath {
|
|||||||
|
|
||||||
private final List<Movement> movements;
|
private final List<Movement> movements;
|
||||||
|
|
||||||
|
private final List<PathNode> nodes;
|
||||||
|
|
||||||
private final Goal goal;
|
private final Goal goal;
|
||||||
|
|
||||||
private final int numNodes;
|
private final int numNodes;
|
||||||
@ -71,8 +74,9 @@ class Path implements IPath {
|
|||||||
this.numNodes = numNodes;
|
this.numNodes = numNodes;
|
||||||
this.path = new ArrayList<>();
|
this.path = new ArrayList<>();
|
||||||
this.movements = new ArrayList<>();
|
this.movements = new ArrayList<>();
|
||||||
|
this.nodes = new ArrayList<>();
|
||||||
this.goal = goal;
|
this.goal = goal;
|
||||||
assemblePath(start, end);
|
assemblePath(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -81,62 +85,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()) {
|
if (!path.isEmpty() || !movements.isEmpty()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
PathNode current = end;
|
PathNode current = end;
|
||||||
LinkedList<BetterBlockPos> tempPath = new LinkedList<>();
|
LinkedList<BetterBlockPos> tempPath = new LinkedList<>();
|
||||||
|
LinkedList<PathNode> tempNodes = new LinkedList();
|
||||||
// Repeatedly inserting to the beginning of an arraylist is O(n^2)
|
// Repeatedly inserting to the beginning of an arraylist is O(n^2)
|
||||||
// Instead, do it into a linked list, then convert at the end
|
// 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));
|
tempPath.addFirst(new BetterBlockPos(current.x, current.y, current.z));
|
||||||
current = current.previous;
|
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
|
// 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<E> keeps track of length, then when we addall (which calls .toArray) it's able
|
// inserting into a LinkedList<E> keeps track of length, then when we addall (which calls .toArray) it's able
|
||||||
// to performantly do that conversion since it knows the length.
|
// to performantly do that conversion since it knows the length.
|
||||||
path.addAll(tempPath);
|
path.addAll(tempPath);
|
||||||
|
nodes.addAll(tempNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assembleMovements() {
|
private boolean assembleMovements() {
|
||||||
if (path.isEmpty() || !movements.isEmpty()) {
|
if (path.isEmpty() || !movements.isEmpty()) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < path.size() - 1; i++) {
|
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()) {
|
for (Moves moves : Moves.values()) {
|
||||||
Movement move = moves.apply0(src);
|
Movement move = moves.apply0(src);
|
||||||
if (move.getDest().equals(dest)) {
|
if (move.getDest().equals(dest)) {
|
||||||
// TODO instead of recalculating here, could we take pathNode.cost - pathNode.prevNode.cost to get the cost as-calculated?
|
// 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.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
|
move.override(cost);
|
||||||
return move;
|
return move;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this is no longer called from bestPathSoFar, now it's in postprocessing
|
// 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
|
@Override
|
||||||
public void postProcess() {
|
public IPath postProcess() {
|
||||||
if (verified) {
|
if (verified) {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
verified = true;
|
verified = true;
|
||||||
assembleMovements();
|
boolean failed = assembleMovements();
|
||||||
// more post processing here
|
|
||||||
movements.forEach(Movement::checkLoadedChunk);
|
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();
|
sanityCheck();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -95,7 +95,7 @@ public abstract class Movement implements IMovement, Helper, MovementHelper {
|
|||||||
return getCost();
|
return getCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void override(double cost) {
|
public void override(double cost) {
|
||||||
this.cost = cost;
|
this.cost = cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user