use of baritone.api.pathing.movement.IMovement in project baritone by cabaletta.
the class IPath method sanityCheck.
/**
* 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");
}
HashSet<BetterBlockPos> seenSoFar = new HashSet<>();
for (int i = 0; i < path.size() - 1; i++) {
BetterBlockPos src = path.get(i);
BetterBlockPos 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");
}
if (seenSoFar.contains(src)) {
throw new IllegalStateException("Path doubles back on itself, making a loop");
}
seenSoFar.add(src);
}
}
use of baritone.api.pathing.movement.IMovement in project baritone by cabaletta.
the class PathExecutor method closestPathPos.
private Tuple<Double, BlockPos> closestPathPos(IPath path) {
double best = -1;
BlockPos bestPos = null;
for (IMovement movement : path.movements()) {
for (BlockPos pos : ((Movement) movement).getValidPositions()) {
double dist = VecUtils.entityDistanceToCenter(ctx.player(), pos);
if (dist < best || best == -1) {
best = dist;
bestPos = pos;
}
}
}
return new Tuple<>(best, bestPos);
}
use of baritone.api.pathing.movement.IMovement in project baritone by cabaletta.
the class PathExecutor method onTick.
/**
* Tick this executor
*
* @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() {
if (pathPosition == path.length() - 1) {
pathPosition++;
}
if (pathPosition >= path.length()) {
// stop bugging me, I'm done
return true;
}
Movement movement = (Movement) path.movements().get(pathPosition);
BetterBlockPos whereAmI = ctx.playerFeet();
if (!movement.getValidPositions().contains(whereAmI)) {
for (int i = 0; i < pathPosition && i < path.length(); i++) {
// this happens for example when you lag out and get teleported back a couple blocks
if (((Movement) path.movements().get(i)).getValidPositions().contains(whereAmI)) {
int previousPos = pathPosition;
pathPosition = i;
for (int j = pathPosition; j <= previousPos; j++) {
path.movements().get(j).reset();
}
onChangeInPathPosition();
onTick();
return false;
}
}
for (int i = pathPosition + 3; i < path.length() - 1; i++) {
// also don't check pathPosition+2 because reasons
if (((Movement) path.movements().get(i)).getValidPositions().contains(whereAmI)) {
if (i - pathPosition > 2) {
logDebug("Skipping forward " + (i - pathPosition) + " steps, to " + i);
}
// System.out.println("Double skip sundae");
pathPosition = i - 1;
onChangeInPathPosition();
onTick();
return false;
}
}
}
Tuple<Double, BlockPos> 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);
if (ticksAway > MAX_TICKS_AWAY) {
logDebug("Too far away from path for too long, cancelling path");
cancel();
return false;
}
} else {
ticksAway = 0;
}
if (possiblyOffPath(status, MAX_MAX_DIST_FROM_PATH)) {
// ok, stop right away, we're way too far.
logDebug("too far from path");
cancel();
return false;
}
// long start = System.nanoTime() / 1000000L;
BlockStateInterface bsi = new BlockStateInterface(ctx);
for (int i = pathPosition - 10; i < pathPosition + 10; i++) {
if (i < 0 || i >= path.movements().size()) {
continue;
}
Movement m = (Movement) path.movements().get(i);
List<BlockPos> prevBreak = m.toBreak(bsi);
List<BlockPos> prevPlace = m.toPlace(bsi);
List<BlockPos> prevWalkInto = m.toWalkInto(bsi);
m.resetBlockCache();
if (!prevBreak.equals(m.toBreak(bsi))) {
recalcBP = true;
}
if (!prevPlace.equals(m.toPlace(bsi))) {
recalcBP = true;
}
if (!prevWalkInto.equals(m.toWalkInto(bsi))) {
recalcBP = true;
}
}
if (recalcBP) {
HashSet<BlockPos> newBreak = new HashSet<>();
HashSet<BlockPos> newPlace = new HashSet<>();
HashSet<BlockPos> newWalkInto = new HashSet<>();
for (int i = pathPosition; i < path.movements().size(); i++) {
Movement m = (Movement) path.movements().get(i);
newBreak.addAll(m.toBreak(bsi));
newPlace.addAll(m.toPlace(bsi));
newWalkInto.addAll(m.toWalkInto(bsi));
}
toBreak = newBreak;
toPlace = newPlace;
toWalkInto = newWalkInto;
recalcBP = false;
}
/*long end = System.nanoTime() / 1000000L;
if (end - start > 0) {
System.out.println("Recalculating break and place took " + (end - start) + "ms");
}*/
if (pathPosition < path.movements().size() - 1) {
IMovement next = path.movements().get(pathPosition + 1);
if (!behavior.baritone.bsi.worldContainsLoadedChunk(next.getDest().x, next.getDest().z)) {
logDebug("Pausing since destination is at edge of loaded chunks");
clearKeys();
return true;
}
}
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();
for (int i = 1; i < Baritone.settings().costVerificationLookahead.value && pathPosition + i < path.length() - 1; i++) {
if (((Movement) path.movements().get(pathPosition + i)).calculateCost(behavior.secretInternalGetCalculationContext()) >= ActionCosts.COST_INF && canCancel) {
logDebug("Something has changed in the world and a future movement has become impossible. Cancelling.");
cancel();
return true;
}
}
}
double currentCost = movement.recalculateCost(behavior.secretInternalGetCalculationContext());
if (currentCost >= ActionCosts.COST_INF && canCancel) {
logDebug("Something has changed in the world and this movement has become impossible. Cancelling.");
cancel();
return true;
}
if (!movement.calculatedWhileLoaded() && currentCost - currentMovementOriginalCostEstimate > Baritone.settings().maxCostIncrease.value && canCancel) {
// don't do this if the movement was calculated while loaded
// that means that this isn't a cache error, it's just part of the path interfering with a later part
logDebug("Original cost " + currentMovementOriginalCostEstimate + " current cost " + currentCost + ". Cancelling.");
cancel();
return true;
}
if (shouldPause()) {
logDebug("Pausing since current best path is a backtrack");
clearKeys();
return true;
}
MovementStatus movementStatus = movement.update();
if (movementStatus == UNREACHABLE || movementStatus == FAILED) {
logDebug("Movement returns status " + movementStatus);
cancel();
return true;
}
if (movementStatus == SUCCESS) {
// System.out.println("Movement done, next path");
pathPosition++;
onChangeInPathPosition();
onTick();
return true;
} else {
sprintNextTick = shouldSprintNextTick();
if (!sprintNextTick) {
// letting go of control doesn't make you stop sprinting actually
ctx.player().setSprinting(false);
}
ticksOnCurrent++;
if (ticksOnCurrent > currentMovementOriginalCostEstimate + Baritone.settings().movementTimeoutTicks.value) {
// only cancel if the total time has exceeded the initial estimate
// as you break the blocks required, the remaining cost goes down, to the point where
// ticksOnCurrent is greater than recalculateCost + 100
// this is why we cache cost at the beginning, and don't recalculate for this comparison every tick
logDebug("This movement has taken too long (" + ticksOnCurrent + " ticks, expected " + currentMovementOriginalCostEstimate + "). Cancelling.");
cancel();
return true;
}
}
// movement is in progress, but if it reports cancellable, PathingBehavior is good to cut onto the next path
return canCancel;
}
use of baritone.api.pathing.movement.IMovement in project Spark-Client by Spark-Client-Development.
the class PathExecutor method onTick.
/**
* Tick this executor
*
* @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() {
if (pathPosition == path.length() - 1) {
pathPosition++;
}
if (pathPosition >= path.length()) {
// stop bugging me, I'm done
return true;
}
Movement movement = (Movement) path.movements().get(pathPosition);
BetterBlockPos whereAmI = ctx.playerFeet();
if (!movement.getValidPositions().contains(whereAmI)) {
for (int i = 0; i < pathPosition && i < path.length(); i++) {
// this happens for example when you lag out and get teleported back a couple blocks
if (((Movement) path.movements().get(i)).getValidPositions().contains(whereAmI)) {
int previousPos = pathPosition;
pathPosition = i;
for (int j = pathPosition; j <= previousPos; j++) {
path.movements().get(j).reset();
}
onChangeInPathPosition();
onTick();
return false;
}
}
for (int i = pathPosition + 3; i < path.length() - 1; i++) {
// also don't check pathPosition+2 because reasons
if (((Movement) path.movements().get(i)).getValidPositions().contains(whereAmI)) {
if (i - pathPosition > 2) {
logDebug("Skipping forward " + (i - pathPosition) + " steps, to " + i);
}
// System.out.println("Double skip sundae");
pathPosition = i - 1;
onChangeInPathPosition();
onTick();
return false;
}
}
}
Tuple<Double, BlockPos> 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);
if (ticksAway > MAX_TICKS_AWAY) {
logDebug("Too far away from path for too long, cancelling path");
cancel();
return false;
}
} else {
ticksAway = 0;
}
if (possiblyOffPath(status, MAX_MAX_DIST_FROM_PATH)) {
// ok, stop right away, we're way too far.
logDebug("too far from path");
cancel();
return false;
}
// long start = System.nanoTime() / 1000000L;
BlockStateInterface bsi = new BlockStateInterface(ctx);
for (int i = pathPosition - 10; i < pathPosition + 10; i++) {
if (i < 0 || i >= path.movements().size()) {
continue;
}
Movement m = (Movement) path.movements().get(i);
List<BlockPos> prevBreak = m.toBreak(bsi);
List<BlockPos> prevPlace = m.toPlace(bsi);
List<BlockPos> prevWalkInto = m.toWalkInto(bsi);
m.resetBlockCache();
if (!prevBreak.equals(m.toBreak(bsi))) {
recalcBP = true;
}
if (!prevPlace.equals(m.toPlace(bsi))) {
recalcBP = true;
}
if (!prevWalkInto.equals(m.toWalkInto(bsi))) {
recalcBP = true;
}
}
if (recalcBP) {
HashSet<BlockPos> newBreak = new HashSet<>();
HashSet<BlockPos> newPlace = new HashSet<>();
HashSet<BlockPos> newWalkInto = new HashSet<>();
for (int i = pathPosition; i < path.movements().size(); i++) {
Movement m = (Movement) path.movements().get(i);
newBreak.addAll(m.toBreak(bsi));
newPlace.addAll(m.toPlace(bsi));
newWalkInto.addAll(m.toWalkInto(bsi));
}
toBreak = newBreak;
toPlace = newPlace;
toWalkInto = newWalkInto;
recalcBP = false;
}
/*long end = System.nanoTime() / 1000000L;
if (end - start > 0) {
System.out.println("Recalculating break and place took " + (end - start) + "ms");
}*/
if (pathPosition < path.movements().size() - 1) {
IMovement next = path.movements().get(pathPosition + 1);
if (!behavior.baritone.bsi.worldContainsLoadedChunk(next.getDest().x, next.getDest().z)) {
logDebug("Pausing since destination is at edge of loaded chunks");
clearKeys();
return true;
}
}
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();
for (int i = 1; i < Baritone.settings().costVerificationLookahead.getValue() && pathPosition + i < path.length() - 1; i++) {
if (((Movement) path.movements().get(pathPosition + i)).calculateCost(behavior.secretInternalGetCalculationContext()) >= ActionCosts.COST_INF && canCancel) {
logDebug("Something has changed in the world and a future movement has become impossible. Cancelling.");
cancel();
return true;
}
}
}
double currentCost = movement.recalculateCost(behavior.secretInternalGetCalculationContext());
if (currentCost >= ActionCosts.COST_INF && canCancel) {
logDebug("Something has changed in the world and this movement has become impossible. Cancelling.");
cancel();
return true;
}
if (!movement.calculatedWhileLoaded() && currentCost - currentMovementOriginalCostEstimate > Baritone.settings().maxCostIncrease.getValue() && canCancel) {
// don't do this if the movement was calculated while loaded
// that means that this isn't a cache error, it's just part of the path interfering with a later part
logDebug("Original cost " + currentMovementOriginalCostEstimate + " current cost " + currentCost + ". Cancelling.");
cancel();
return true;
}
if (shouldPause()) {
logDebug("Pausing since current best path is a backtrack");
clearKeys();
return true;
}
MovementStatus movementStatus = movement.update();
if (movementStatus == UNREACHABLE || movementStatus == FAILED) {
logDebug("Movement returns status " + movementStatus);
cancel();
return true;
}
if (movementStatus == SUCCESS) {
// System.out.println("Movement done, next path");
pathPosition++;
onChangeInPathPosition();
onTick();
return true;
} else {
sprintNextTick = shouldSprintNextTick();
if (!sprintNextTick) {
// letting go of control doesn't make you stop sprinting actually
ctx.player().setSprinting(false);
}
ticksOnCurrent++;
if (ticksOnCurrent > currentMovementOriginalCostEstimate + Baritone.settings().movementTimeoutTicks.getValue()) {
// only cancel if the total time has exceeded the initial estimate
// as you break the blocks required, the remaining cost goes down, to the point where
// ticksOnCurrent is greater than recalculateCost + 100
// this is why we cache cost at the beginning, and don't recalculate for this comparison every tick
logDebug("This movement has taken too long (" + ticksOnCurrent + " ticks, expected " + currentMovementOriginalCostEstimate + "). Cancelling.");
cancel();
return true;
}
}
// movement is in progress, but if it reports cancellable, PathingBehavior is good to cut onto the next path
return canCancel;
}
use of baritone.api.pathing.movement.IMovement in project Spark-Client by Spark-Client-Development.
the class PathExecutor method overrideFall.
private Tuple<Vec3d, BlockPos> overrideFall(MovementFall movement) {
Vec3i dir = movement.getDirection();
if (dir.getY() < -3) {
return null;
}
if (!movement.toBreakCached.isEmpty()) {
// it's breaking
return null;
}
Vec3i flatDir = new Vec3i(dir.getX(), 0, dir.getZ());
int i;
outer: for (i = pathPosition + 1; i < path.length() - 1 && i < pathPosition + 3; i++) {
IMovement next = path.movements().get(i);
if (!(next instanceof MovementTraverse)) {
break;
}
if (!flatDir.equals(next.getDirection())) {
break;
}
for (int y = next.getDest().y; y <= movement.getSrc().y + 1; y++) {
BlockPos chk = new BlockPos(next.getDest().x, y, next.getDest().z);
if (!MovementHelper.fullyPassable(ctx, chk)) {
break outer;
}
}
if (!MovementHelper.canWalkOn(ctx, next.getDest().down())) {
break;
}
}
i--;
if (i == pathPosition) {
// no valid extension exists
return null;
}
double len = i - pathPosition - 0.4;
return new Tuple<>(new Vec3d(flatDir.getX() * len + movement.getDest().x + 0.5, movement.getDest().y, flatDir.getZ() * len + movement.getDest().z + 0.5), movement.getDest().add(flatDir.getX() * (i - pathPosition), 0, flatDir.getZ() * (i - pathPosition)));
}
Aggregations