mirror of https://github.com/cabaletta/baritone
suggestion for zephreo to make multi destination parkour
This commit is contained in:
parent
6bec994a57
commit
4a489d29de
|
@ -114,50 +114,53 @@ public final class AStarPathFinder extends AbstractNodeCostSearch {
|
|||
}
|
||||
res.reset();
|
||||
moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z, res);
|
||||
numMovementsConsidered++;
|
||||
double actionCost = res.cost;
|
||||
if (actionCost >= ActionCosts.COST_INF) {
|
||||
continue;
|
||||
}
|
||||
if (actionCost <= 0 || Double.isNaN(actionCost)) {
|
||||
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
|
||||
}
|
||||
// check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation
|
||||
if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218
|
||||
continue;
|
||||
}
|
||||
if (!moves.dynamicXZ && (res.x != newX || res.z != newZ)) {
|
||||
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
|
||||
}
|
||||
if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) {
|
||||
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
|
||||
}
|
||||
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
|
||||
if (isFavoring) {
|
||||
// see issue #18
|
||||
actionCost *= favoring.calculate(hashCode);
|
||||
}
|
||||
PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode);
|
||||
double tentativeCost = currentNode.cost + actionCost;
|
||||
if (neighbor.cost - tentativeCost > minimumImprovement) {
|
||||
neighbor.previous = currentNode;
|
||||
neighbor.cost = tentativeCost;
|
||||
neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal;
|
||||
if (neighbor.isOpen()) {
|
||||
openSet.update(neighbor);
|
||||
} else {
|
||||
openSet.insert(neighbor);//dont double count, dont insert into open set if it's already there
|
||||
while (res != null) {
|
||||
numMovementsConsidered++;
|
||||
double actionCost = res.cost;
|
||||
if (actionCost >= ActionCosts.COST_INF) {
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < COEFFICIENTS.length; i++) {
|
||||
double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i];
|
||||
if (bestHeuristicSoFar[i] - heuristic > minimumImprovement) {
|
||||
bestHeuristicSoFar[i] = heuristic;
|
||||
bestSoFar[i] = neighbor;
|
||||
if (failing && getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) {
|
||||
failing = false;
|
||||
if (actionCost <= 0 || Double.isNaN(actionCost)) {
|
||||
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
|
||||
}
|
||||
// check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation
|
||||
if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218
|
||||
continue;
|
||||
}
|
||||
if (!moves.dynamicXZ && (res.x != newX || res.z != newZ)) {
|
||||
throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ);
|
||||
}
|
||||
if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) {
|
||||
throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset));
|
||||
}
|
||||
long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z);
|
||||
if (isFavoring) {
|
||||
// see issue #18
|
||||
actionCost *= favoring.calculate(hashCode);
|
||||
}
|
||||
PathNode neighbor = getNodeAtPosition(res.x, res.y, res.z, hashCode);
|
||||
double tentativeCost = currentNode.cost + actionCost;
|
||||
if (neighbor.cost - tentativeCost > minimumImprovement) {
|
||||
neighbor.previous = currentNode;
|
||||
neighbor.cost = tentativeCost;
|
||||
neighbor.combinedCost = tentativeCost + neighbor.estimatedCostToGoal;
|
||||
if (neighbor.isOpen()) {
|
||||
openSet.update(neighbor);
|
||||
} else {
|
||||
openSet.insert(neighbor);//dont double count, dont insert into open set if it's already there
|
||||
}
|
||||
for (int i = 0; i < COEFFICIENTS.length; i++) {
|
||||
double heuristic = neighbor.estimatedCostToGoal + neighbor.cost / COEFFICIENTS[i];
|
||||
if (bestHeuristicSoFar[i] - heuristic > minimumImprovement) {
|
||||
bestHeuristicSoFar[i] = heuristic;
|
||||
bestSoFar[i] = neighbor;
|
||||
if (failing && getDistFromStartSq(neighbor) > MIN_DIST_PATH * MIN_DIST_PATH) {
|
||||
failing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
res = res.getNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,8 +131,14 @@ public class MovementParkour extends Movement {
|
|||
res.y = y;
|
||||
res.z = destZ;
|
||||
res.cost = costFromJumpDistance(i) + context.jumpPenalty;
|
||||
// for example, right here, we might just do:
|
||||
res = res.nextPotentialDestination();
|
||||
// that like, marks this `res` as "done" and we've put in this movement option's data
|
||||
}
|
||||
// and instead of this return
|
||||
return;
|
||||
// we would just continue onto the rest of the loop, and if we find an alternate landing, we would just update `res` as normal, and everything would Just Work
|
||||
// we could return ANY number of potential movement destinations like this, and as soon as we get each new one, we just pop it into the stack by writing to `res` then doing `res = res.nextPotentialDestination();`
|
||||
}
|
||||
if (!MovementHelper.fullyPassable(context, destX, y + 3, destZ)) {
|
||||
return;
|
||||
|
|
|
@ -30,6 +30,8 @@ public final class MutableMoveResult {
|
|||
public int y;
|
||||
public int z;
|
||||
public double cost;
|
||||
private MutableMoveResult next;
|
||||
private boolean hasNext;
|
||||
|
||||
public MutableMoveResult() {
|
||||
reset();
|
||||
|
@ -40,5 +42,24 @@ public final class MutableMoveResult {
|
|||
y = 0;
|
||||
z = 0;
|
||||
cost = ActionCosts.COST_INF;
|
||||
hasNext = false;
|
||||
if (next != null) {
|
||||
next.reset();
|
||||
}
|
||||
}
|
||||
|
||||
public MutableMoveResult nextPotentialDestination() {
|
||||
if (next == null) {
|
||||
next = new MutableMoveResult(); // this is okay because it's one-time at the beginning (or near the beginning) of the calculation, instead of per-movement
|
||||
}
|
||||
hasNext = true;
|
||||
return next;
|
||||
}
|
||||
|
||||
public MutableMoveResult getNext() {
|
||||
if (!hasNext) {
|
||||
return null;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue