Search in sources :

Example 1 with IMovement

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);
    }
}
Also used : BetterBlockPos(baritone.api.utils.BetterBlockPos) IMovement(baritone.api.pathing.movement.IMovement) HashSet(java.util.HashSet)

Example 2 with IMovement

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);
}
Also used : IMovement(baritone.api.pathing.movement.IMovement) Movement(baritone.pathing.movement.Movement) IMovement(baritone.api.pathing.movement.IMovement) BlockPos(net.minecraft.util.math.BlockPos) Tuple(net.minecraft.util.Tuple)

Example 3 with IMovement

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;
}
Also used : BlockStateInterface(baritone.utils.BlockStateInterface) IMovement(baritone.api.pathing.movement.IMovement) Movement(baritone.pathing.movement.Movement) IMovement(baritone.api.pathing.movement.IMovement) MovementStatus(baritone.api.pathing.movement.MovementStatus) BlockPos(net.minecraft.util.math.BlockPos)

Example 4 with IMovement

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;
}
Also used : BlockStateInterface(baritone.utils.BlockStateInterface) IMovement(baritone.api.pathing.movement.IMovement) Movement(baritone.pathing.movement.Movement) IMovement(baritone.api.pathing.movement.IMovement) MovementStatus(baritone.api.pathing.movement.MovementStatus) BlockPos(net.minecraft.util.math.BlockPos)

Example 5 with IMovement

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)));
}
Also used : Vec3i(net.minecraft.util.math.Vec3i) IMovement(baritone.api.pathing.movement.IMovement) BlockPos(net.minecraft.util.math.BlockPos) Tuple(net.minecraft.util.Tuple) Vec3d(net.minecraft.util.math.Vec3d)

Aggregations

IMovement (baritone.api.pathing.movement.IMovement)11 BlockPos (net.minecraft.util.math.BlockPos)8 Movement (baritone.pathing.movement.Movement)4 Tuple (net.minecraft.util.Tuple)4 Vec3d (net.minecraft.util.math.Vec3d)4 MovementStatus (baritone.api.pathing.movement.MovementStatus)2 BetterBlockPos (baritone.api.utils.BetterBlockPos)2 CalculationContext (baritone.pathing.movement.CalculationContext)2 BlockStateInterface (baritone.utils.BlockStateInterface)2 HashSet (java.util.HashSet)2 Vec3i (net.minecraft.util.math.Vec3i)2 IPathExecutor (baritone.api.pathing.path.IPathExecutor)1 MovementDiagonal (baritone.pathing.movement.movements.MovementDiagonal)1 MovementTraverse (baritone.pathing.movement.movements.MovementTraverse)1