planning ahead
This commit is contained in:
parent
88c81a9635
commit
85fdc2df34
@ -49,17 +49,80 @@ public class PathingBehavior extends Behavior {
|
||||
|
||||
private Goal goal;
|
||||
|
||||
private volatile boolean isPathCalcInProgress;
|
||||
private final Object pathCalcLock = new Object();
|
||||
|
||||
private final Object pathPlanLock = new Object();
|
||||
|
||||
@Override
|
||||
public void onTick(TickEvent event) {
|
||||
if (event.getType() == TickEvent.Type.OUT || current == null) {
|
||||
return;
|
||||
}
|
||||
current.onTick(event);
|
||||
boolean safe = current.onTick(event);
|
||||
synchronized (pathPlanLock) {
|
||||
if (current.failed() || current.finished()) {
|
||||
current = null;
|
||||
if (!goal.isInGoal(playerFeet()))
|
||||
if (next != null && !next.getPath().positions().contains(playerFeet())) {
|
||||
// if the current path failed, we may not actually be on the next one, so make sure
|
||||
displayChatMessageRaw("Discarding next path as it does not contain current position");
|
||||
// for example if we had a nicely planned ahead path that starts where current ends
|
||||
// that's all fine and good
|
||||
// but if we fail in the middle of current
|
||||
// we're nowhere close to our planned ahead path
|
||||
// so need to discard it sadly.
|
||||
next = null;
|
||||
}
|
||||
if (next != null) {
|
||||
current = next;
|
||||
next = null;
|
||||
return;
|
||||
}
|
||||
if (goal.isInGoal(playerFeet())) {
|
||||
return;
|
||||
}
|
||||
// at this point, current just ended, but we aren't in the goal and have no plan for the future
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
// if we aren't calculating right now
|
||||
return;
|
||||
}
|
||||
findPathInNewThread(playerFeet(), true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// at this point, we know current is in progress
|
||||
if (safe) {
|
||||
// a movement just ended
|
||||
if (next != null) {
|
||||
if (next.getPath().positions().contains(playerFeet())) {
|
||||
// jump directly onto the next path
|
||||
current = next;
|
||||
next = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
// if we aren't calculating right now
|
||||
return;
|
||||
}
|
||||
if (next != null) {
|
||||
// and we have no plan for what to do next
|
||||
return;
|
||||
}
|
||||
if (goal.isInGoal(current.getPath().getDest())) {
|
||||
// and this path dosen't get us all the way there
|
||||
return;
|
||||
}
|
||||
if (current.getPath().ticksRemainingFrom(current.getPosition()) < 100) {
|
||||
// and this path has 5 seconds or less left
|
||||
displayChatMessageRaw("Path almost over; planning ahead");
|
||||
findPathInNewThread(current.getPath().getDest(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -136,12 +199,30 @@ public class PathingBehavior extends Behavior {
|
||||
* @param talkAboutIt
|
||||
*/
|
||||
public void findPathInNewThread(final BlockPos start, final boolean talkAboutIt) {
|
||||
synchronized (pathCalcLock) {
|
||||
if (isPathCalcInProgress) {
|
||||
throw new IllegalStateException("Already doing it");
|
||||
}
|
||||
isPathCalcInProgress = true;
|
||||
}
|
||||
new Thread(() -> {
|
||||
if (talkAboutIt) {
|
||||
displayChatMessageRaw("Starting to search for path from " + start + " to " + goal);
|
||||
}
|
||||
|
||||
findPath(start).map(PathExecutor::new).ifPresent(path -> current = path);
|
||||
findPath(start).map(PathExecutor::new).ifPresent(path -> {
|
||||
synchronized (pathPlanLock) {
|
||||
if (current == null) {
|
||||
current = path;
|
||||
} else {
|
||||
if (next == null) {
|
||||
next = path;
|
||||
} else {
|
||||
throw new IllegalStateException("I have no idea what to do with this path");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
/*
|
||||
isThereAnythingInProgress = false;
|
||||
if (!currentPath.goal.isInGoal(currentPath.end)) {
|
||||
@ -156,6 +237,9 @@ public class PathingBehavior extends Behavior {
|
||||
if (talkAboutIt && current != null && current.getPath() != null) {
|
||||
displayChatMessageRaw("Finished finding a path from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
|
||||
}
|
||||
synchronized (pathCalcLock) {
|
||||
isPathCalcInProgress = false;
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package baritone.bot.pathing.path;
|
||||
|
||||
import baritone.bot.pathing.movement.CalculationContext;
|
||||
import baritone.bot.pathing.movement.Movement;
|
||||
import baritone.bot.utils.Utils;
|
||||
import net.minecraft.util.Tuple;
|
||||
@ -108,11 +107,11 @@ public interface IPath {
|
||||
return pos.get(pos.size() - 1);
|
||||
}
|
||||
|
||||
default double ticksRemaining(int pathPosition) {
|
||||
default double ticksRemainingFrom(int pathPosition) {
|
||||
double sum = 0;
|
||||
CalculationContext ctx = new CalculationContext();
|
||||
//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(ctx);
|
||||
sum += movements().get(i).getCost(null);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
@ -18,12 +18,12 @@
|
||||
package baritone.bot.pathing.path;
|
||||
|
||||
import baritone.bot.Baritone;
|
||||
import baritone.bot.behavior.Behavior;
|
||||
import baritone.bot.event.events.TickEvent;
|
||||
import baritone.bot.pathing.movement.ActionCosts;
|
||||
import baritone.bot.pathing.movement.Movement;
|
||||
import baritone.bot.pathing.movement.MovementState;
|
||||
import baritone.bot.utils.BlockStateInterface;
|
||||
import baritone.bot.utils.Helper;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.Tuple;
|
||||
@ -41,7 +41,7 @@ import static baritone.bot.pathing.movement.MovementState.MovementStatus.*;
|
||||
*
|
||||
* @author leijurv
|
||||
*/
|
||||
public class PathExecutor extends Behavior {
|
||||
public class PathExecutor implements Helper {
|
||||
private static final double MAX_DIST_FROM_PATH = 2;
|
||||
private static final double MAX_TICKS_AWAY = 200; // ten seconds
|
||||
private final IPath path;
|
||||
@ -61,15 +61,21 @@ public class PathExecutor extends Behavior {
|
||||
this.pathPosition = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick(TickEvent event) {
|
||||
/**
|
||||
* Tick this executor
|
||||
*
|
||||
* @param event
|
||||
* @return True if a movement just finished (and the player is therefore in a "stable" state, like,
|
||||
* not sneaking out over lava), false otherwise
|
||||
*/
|
||||
public boolean onTick(TickEvent event) {
|
||||
if (event.getType() == TickEvent.Type.OUT) {
|
||||
return;
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (pathPosition >= path.length()) {
|
||||
//stop bugging me, I'm done
|
||||
//TODO Baritone.INSTANCE.behaviors.remove(this)
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
BlockPos whereShouldIBe = path.positions().get(pathPosition);
|
||||
EntityPlayerSP thePlayer = mc.player;
|
||||
@ -77,7 +83,7 @@ public class PathExecutor extends Behavior {
|
||||
if (pathPosition == path.length() - 1) {
|
||||
displayChatMessageRaw("On last position, ending this path.");
|
||||
pathPosition++;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (!whereShouldIBe.equals(whereAmI)) {
|
||||
System.out.println("Should be at " + whereShouldIBe + " actually am at " + whereAmI);
|
||||
@ -86,7 +92,7 @@ public class PathExecutor extends Behavior {
|
||||
if (whereAmI.equals(path.positions().get(i))) {
|
||||
displayChatMessageRaw("Skipping back " + (pathPosition - i) + " steps, to " + i);
|
||||
pathPosition = Math.max(i - 1, 0); // previous step might not actually be done
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = pathPosition + 2; i < path.length(); i++) { //dont check pathPosition+1. the movement tells us when it's done (e.g. sneak placing)
|
||||
@ -95,7 +101,7 @@ public class PathExecutor extends Behavior {
|
||||
displayChatMessageRaw("Skipping forward " + (i - pathPosition) + " steps, to " + i);
|
||||
}
|
||||
pathPosition = i - 1;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -111,7 +117,7 @@ public class PathExecutor extends Behavior {
|
||||
pathPosition = path.length() + 3;
|
||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||
failed = true;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ticksAway = 0;
|
||||
@ -194,7 +200,7 @@ public class PathExecutor extends Behavior {
|
||||
pathPosition = path.length() + 3;
|
||||
failed = true;
|
||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (costEstimateIndex == null || costEstimateIndex != pathPosition) {
|
||||
costEstimateIndex = pathPosition;
|
||||
@ -206,7 +212,7 @@ public class PathExecutor extends Behavior {
|
||||
pathPosition = path.length() + 3;
|
||||
failed = true;
|
||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (movementStatus == SUCCESS) {
|
||||
System.out.println("Movement done, next path");
|
||||
@ -214,6 +220,7 @@ public class PathExecutor extends Behavior {
|
||||
ticksOnCurrent = 0;
|
||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||
onTick(event);
|
||||
return true;
|
||||
} else {
|
||||
ticksOnCurrent++;
|
||||
if (ticksOnCurrent > currentMovementInitialCostEstimate + 100) {
|
||||
@ -226,9 +233,10 @@ public class PathExecutor extends Behavior {
|
||||
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
|
||||
pathPosition = path.length() + 3;
|
||||
failed = true;
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false; // movement is in progress
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
|
Loading…
Reference in New Issue
Block a user