parkour
This commit is contained in:
		@@ -102,7 +102,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                MoveResult res = moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z);
 | 
			
		||||
                if (res.destX != newX || res.destZ != newZ) {
 | 
			
		||||
                if (!moves.dynamicXZ && (res.destX != newX || res.destZ != newZ)) {
 | 
			
		||||
                    throw new IllegalStateException(moves + " " + res.destX + " " + newX + " " + res.destZ + " " + newZ);
 | 
			
		||||
                }
 | 
			
		||||
                numMovementsConsidered++;
 | 
			
		||||
 
 | 
			
		||||
@@ -264,19 +264,76 @@ public enum Moves {
 | 
			
		||||
            return new MoveResult(x - 1, y, z + 1, MovementDiagonal.cost(context, x, y, z, x - 1, z + 1));
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    // TODO parkour
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
    PARKOUR_NORTH(0, -4, true) {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected Movement apply0(BetterBlockPos src) {
 | 
			
		||||
            return MovementParkour.cost(new CalculationContext(), src, EnumFacing.NORTH);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public MoveResult apply(CalculationContext context, int x, int y, int z) {
 | 
			
		||||
            Tuple<Tuple<Integer, Integer>, Double> res = MovementParkour.cost(context, x, y, z, EnumFacing.NORTH);
 | 
			
		||||
            return new MoveResult(res.getFirst().getFirst(), y, res.getFirst().getSecond(), res.getSecond());
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    PARKOUR_SOUTH(0, +4, true) {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected Movement apply0(BetterBlockPos src) {
 | 
			
		||||
            return MovementParkour.cost(new CalculationContext(), src, EnumFacing.SOUTH);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public MoveResult apply(CalculationContext context, int x, int y, int z) {
 | 
			
		||||
            Tuple<Tuple<Integer, Integer>, Double> res = MovementParkour.cost(context, x, y, z, EnumFacing.SOUTH);
 | 
			
		||||
            return new MoveResult(res.getFirst().getFirst(), y, res.getFirst().getSecond(), res.getSecond());
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    PARKOUR_EAST(+4, 0, true) {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected Movement apply0(BetterBlockPos src) {
 | 
			
		||||
            return MovementParkour.cost(new CalculationContext(), src, EnumFacing.EAST);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public MoveResult apply(CalculationContext context, int x, int y, int z) {
 | 
			
		||||
            Tuple<Tuple<Integer, Integer>, Double> res = MovementParkour.cost(context, x, y, z, EnumFacing.EAST);
 | 
			
		||||
            return new MoveResult(res.getFirst().getFirst(), y, res.getFirst().getSecond(), res.getSecond());
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    PARKOUR_WEST(-4, 0, true) {
 | 
			
		||||
        @Override
 | 
			
		||||
        protected Movement apply0(BetterBlockPos src) {
 | 
			
		||||
            return MovementParkour.cost(new CalculationContext(), src, EnumFacing.WEST);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public MoveResult apply(CalculationContext context, int x, int y, int z) {
 | 
			
		||||
            Tuple<Tuple<Integer, Integer>, Double> res = MovementParkour.cost(context, x, y, z, EnumFacing.WEST);
 | 
			
		||||
            return new MoveResult(res.getFirst().getFirst(), y, res.getFirst().getSecond(), res.getSecond());
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    protected abstract Movement apply0(BetterBlockPos src);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public abstract MoveResult apply(CalculationContext context, int x, int y, int z);
 | 
			
		||||
 | 
			
		||||
    public final boolean dynamicXZ;
 | 
			
		||||
 | 
			
		||||
    public final int xOffset;
 | 
			
		||||
    public final int zOffset;
 | 
			
		||||
 | 
			
		||||
    Moves(int x, int z) {
 | 
			
		||||
    Moves(int x, int z, boolean dynamicXZ) {
 | 
			
		||||
        this.xOffset = x;
 | 
			
		||||
        this.zOffset = z;
 | 
			
		||||
        this.dynamicXZ = dynamicXZ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Moves(int x, int z) {
 | 
			
		||||
        this(x, z, false);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,8 +20,6 @@ package baritone.pathing.movement;
 | 
			
		||||
import baritone.Baritone;
 | 
			
		||||
import baritone.behavior.LookBehaviorUtils;
 | 
			
		||||
import baritone.pathing.movement.MovementState.MovementTarget;
 | 
			
		||||
import baritone.pathing.movement.movements.MovementDescend;
 | 
			
		||||
import baritone.pathing.movement.movements.MovementFall;
 | 
			
		||||
import baritone.utils.*;
 | 
			
		||||
import baritone.utils.pathing.BetterBlockPos;
 | 
			
		||||
import net.minecraft.block.*;
 | 
			
		||||
@@ -142,6 +140,10 @@ public interface MovementHelper extends ActionCosts, Helper {
 | 
			
		||||
        return fullyPassable(BlockStateInterface.get(pos));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static boolean fullyPassable(int x, int y, int z) {
 | 
			
		||||
        return fullyPassable(BlockStateInterface.get(x, y, z));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static boolean fullyPassable(IBlockState state) {
 | 
			
		||||
        Block block = state.getBlock();
 | 
			
		||||
        if (block == Blocks.AIR) { // early return for most common case
 | 
			
		||||
@@ -463,48 +465,4 @@ public interface MovementHelper extends ActionCosts, Helper {
 | 
			
		||||
                false
 | 
			
		||||
        )).setInput(InputOverrideHandler.Input.MOVE_FORWARD, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static Movement generateMovementFallOrDescend(BetterBlockPos pos, BetterBlockPos dest, CalculationContext calcContext) {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        int x = dest.x;
 | 
			
		||||
        int y = dest.y;
 | 
			
		||||
        int z = dest.z;
 | 
			
		||||
        if (!canWalkThrough(x, y - 2, z)) {
 | 
			
		||||
            //if B in the diagram aren't air
 | 
			
		||||
            //have to do a descend, because fall is impossible
 | 
			
		||||
 | 
			
		||||
            //this doesn't guarantee descend is possible, it just guarantees fall is impossible
 | 
			
		||||
            return new MovementDescend(pos, dest.down()); // standard move out by 1 and descend by 1
 | 
			
		||||
            // we can't cost shortcut descend because !canWalkThrough doesn't mean canWalkOn
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // we're clear for a fall 2
 | 
			
		||||
        // let's see how far we can fall
 | 
			
		||||
        for (int fallHeight = 3; true; fallHeight++) {
 | 
			
		||||
            int newY = y - fallHeight;
 | 
			
		||||
            if (newY < 0) {
 | 
			
		||||
                // when pathing in the end, where you could plausibly fall into the void
 | 
			
		||||
                // this check prevents it from getting the block at y=-1 and crashing
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            IBlockState ontoBlock = BlockStateInterface.get(x, newY, z);
 | 
			
		||||
            if (ontoBlock.getBlock() == Blocks.WATER) {
 | 
			
		||||
                return new MovementFall(pos, new BetterBlockPos(x, newY, z));
 | 
			
		||||
            }
 | 
			
		||||
            if (canWalkThrough(x, newY, z, ontoBlock)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (!canWalkOn(x, newY, z, ontoBlock)) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            if ((calcContext.hasWaterBucket() && fallHeight <= calcContext.maxFallHeightBucket() + 1) || fallHeight <= calcContext.maxFallHeightNoWater() + 1) {
 | 
			
		||||
                // fallHeight = 4 means onto.up() is 3 blocks down, which is the max
 | 
			
		||||
                return new MovementFall(pos, new BetterBlockPos(x, newY + 1, z));
 | 
			
		||||
            } else {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,19 +27,20 @@ import baritone.utils.BlockStateInterface;
 | 
			
		||||
import baritone.utils.InputOverrideHandler;
 | 
			
		||||
import baritone.utils.Utils;
 | 
			
		||||
import baritone.utils.pathing.BetterBlockPos;
 | 
			
		||||
import net.minecraft.block.Block;
 | 
			
		||||
import net.minecraft.block.state.IBlockState;
 | 
			
		||||
import net.minecraft.client.Minecraft;
 | 
			
		||||
import net.minecraft.init.Blocks;
 | 
			
		||||
import net.minecraft.util.EnumFacing;
 | 
			
		||||
import net.minecraft.util.Tuple;
 | 
			
		||||
import net.minecraft.util.math.BlockPos;
 | 
			
		||||
import net.minecraft.util.math.Vec3d;
 | 
			
		||||
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
public class MovementParkour extends Movement {
 | 
			
		||||
    private static final EnumFacing[] HORIZONTALS_BUT_ALSO_DOWN_SO_EVERY_DIRECTION_EXCEPT_UP = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST, EnumFacing.DOWN};
 | 
			
		||||
    private static final EnumFacing[] HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP = {EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.EAST, EnumFacing.WEST, EnumFacing.DOWN};
 | 
			
		||||
    private static final BetterBlockPos[] EMPTY = new BetterBlockPos[]{};
 | 
			
		||||
    private static final Tuple<Tuple<Integer, Integer>, Double> IMPOSSIBLE = new Tuple<>(new Tuple<>(0, 0), COST_INF);
 | 
			
		||||
 | 
			
		||||
    private final EnumFacing direction;
 | 
			
		||||
    private final int dist;
 | 
			
		||||
@@ -48,79 +49,81 @@ public class MovementParkour extends Movement {
 | 
			
		||||
        super(src, src.offset(dir, dist), EMPTY);
 | 
			
		||||
        this.direction = dir;
 | 
			
		||||
        this.dist = dist;
 | 
			
		||||
        super.override(costFromJumpDistance(dist));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static MovementParkour generate(BetterBlockPos src, EnumFacing dir, CalculationContext context) {
 | 
			
		||||
        // MUST BE KEPT IN SYNC WITH calculateCost
 | 
			
		||||
    public static MovementParkour cost(CalculationContext context, BetterBlockPos src, EnumFacing direction) {
 | 
			
		||||
        Tuple<Tuple<Integer, Integer>, Double> res = cost(context, src.x, src.y, src.z, direction);
 | 
			
		||||
        int dist = Math.abs(res.getFirst().getFirst() - src.x) + Math.abs(res.getFirst().getSecond() - src.z);
 | 
			
		||||
        return new MovementParkour(src, dist, direction);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Tuple<Tuple<Integer, Integer>, Double> cost(CalculationContext context, int x, int y, int z, EnumFacing dir) {
 | 
			
		||||
        if (!Baritone.settings().allowParkour.get()) {
 | 
			
		||||
            return null;
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        IBlockState standingOn = BlockStateInterface.get(src.down());
 | 
			
		||||
        IBlockState standingOn = BlockStateInterface.get(x, y - 1, z);
 | 
			
		||||
        if (standingOn.getBlock() == Blocks.VINE || standingOn.getBlock() == Blocks.LADDER || MovementHelper.isBottomSlab(standingOn)) {
 | 
			
		||||
            return null;
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        BetterBlockPos adjBlock = src.down().offset(dir);
 | 
			
		||||
        IBlockState adj = BlockStateInterface.get(adjBlock);
 | 
			
		||||
        int xDiff = dir.getXOffset();
 | 
			
		||||
        int zDiff = dir.getZOffset();
 | 
			
		||||
        IBlockState adj = BlockStateInterface.get(x + xDiff, y - 1, z + zDiff);
 | 
			
		||||
        if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks
 | 
			
		||||
            return null;
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        if (MovementHelper.canWalkOn(adjBlock, adj)) { // don't parkour if we could just traverse (for now)
 | 
			
		||||
            return null;
 | 
			
		||||
        if (MovementHelper.canWalkOn(x + xDiff, y - 1, z + zDiff, adj)) { // don't parkour if we could just traverse (for now)
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!MovementHelper.fullyPassable(src.offset(dir))) {
 | 
			
		||||
            return null;
 | 
			
		||||
        if (!MovementHelper.fullyPassable(x + xDiff, y, z + zDiff)) {
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        if (!MovementHelper.fullyPassable(src.up().offset(dir))) {
 | 
			
		||||
            return null;
 | 
			
		||||
        if (!MovementHelper.fullyPassable(x + xDiff, y + 1, z + zDiff)) {
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        if (!MovementHelper.fullyPassable(src.up(2).offset(dir))) {
 | 
			
		||||
            return null;
 | 
			
		||||
        if (!MovementHelper.fullyPassable(x + xDiff, y + 2, z + zDiff)) {
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        if (!MovementHelper.fullyPassable(src.up(2))) {
 | 
			
		||||
            return null;
 | 
			
		||||
        if (!MovementHelper.fullyPassable(x, y + 2, z)) {
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 2; i <= (context.canSprint() ? 4 : 3); i++) {
 | 
			
		||||
            BetterBlockPos dest = src.offset(dir, i);
 | 
			
		||||
            // TODO perhaps dest.up(3) doesn't need to be fullyPassable, just canWalkThrough, possibly?
 | 
			
		||||
            for (int y = 0; y < 4; y++) {
 | 
			
		||||
                if (!MovementHelper.fullyPassable(dest.up(y))) {
 | 
			
		||||
                    return null;
 | 
			
		||||
            for (int y2 = 0; y2 < 4; y2++) {
 | 
			
		||||
                if (!MovementHelper.fullyPassable(x + xDiff * i, y + y2, z + zDiff * i)) {
 | 
			
		||||
                    return IMPOSSIBLE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (MovementHelper.canWalkOn(dest.down())) {
 | 
			
		||||
                return new MovementParkour(src, i, dir);
 | 
			
		||||
            if (MovementHelper.canWalkOn(x + xDiff * i, y - 1, z + zDiff * i)) {
 | 
			
		||||
                return new Tuple<>(new Tuple<>(x + xDiff * i, z + zDiff * i), costFromJumpDistance(i));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!context.canSprint()) {
 | 
			
		||||
            return null;
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        if (!Baritone.settings().allowParkourPlace.get()) {
 | 
			
		||||
            return null;
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        BlockPos dest = src.offset(dir, 4);
 | 
			
		||||
        BlockPos positionToPlace = dest.down();
 | 
			
		||||
        IBlockState toPlace = BlockStateInterface.get(positionToPlace);
 | 
			
		||||
        int destX = x + 4 * xDiff;
 | 
			
		||||
        int destZ = z + 4 * zDiff;
 | 
			
		||||
        IBlockState toPlace = BlockStateInterface.get(destX, y - 1, destZ);
 | 
			
		||||
        if (!context.hasThrowaway()) {
 | 
			
		||||
            return null;
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(positionToPlace, toPlace)) {
 | 
			
		||||
            return null;
 | 
			
		||||
        if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) {
 | 
			
		||||
            return IMPOSSIBLE;
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 0; i < 5; i++) {
 | 
			
		||||
            BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN_SO_EVERY_DIRECTION_EXCEPT_UP[i]);
 | 
			
		||||
            if (against1.up().equals(src.offset(dir, 3))) { // we can't turn around that fast
 | 
			
		||||
            int againstX = destX + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getXOffset();
 | 
			
		||||
            int againstZ = destZ + HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i].getZOffset();
 | 
			
		||||
            if (againstX == x + xDiff * 3 && againstZ == z + zDiff * 3) { // we can't turn around that fast
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (MovementHelper.canPlaceAgainst(against1)) {
 | 
			
		||||
                // holy jesus we gonna do it
 | 
			
		||||
                MovementParkour ret = new MovementParkour(src, 4, dir);
 | 
			
		||||
                ret.override(costFromJumpDistance(4) + context.placeBlockCost());
 | 
			
		||||
                return ret;
 | 
			
		||||
            if (MovementHelper.canPlaceAgainst(againstX, y - 1, againstZ)) {
 | 
			
		||||
                return new Tuple<>(new Tuple<>(destX, destZ), costFromJumpDistance(i) + context.placeBlockCost());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
        return IMPOSSIBLE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static double costFromJumpDistance(int dist) {
 | 
			
		||||
@@ -139,54 +142,11 @@ public class MovementParkour extends Movement {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected double calculateCost(CalculationContext context) {
 | 
			
		||||
        // MUST BE KEPT IN SYNC WITH generate
 | 
			
		||||
        if (!context.canSprint() && dist >= 4) {
 | 
			
		||||
        Tuple<Tuple<Integer, Integer>, Double> res = cost(context, src.x, src.y, src.z, direction);
 | 
			
		||||
        if (res.getFirst().getFirst() != dest.x || res.getFirst().getSecond() != dest.z) {
 | 
			
		||||
            return COST_INF;
 | 
			
		||||
        }
 | 
			
		||||
        boolean placing = false;
 | 
			
		||||
        if (!MovementHelper.canWalkOn(dest.down())) {
 | 
			
		||||
            if (dist != 4) {
 | 
			
		||||
                return COST_INF;
 | 
			
		||||
            }
 | 
			
		||||
            if (!Baritone.settings().allowParkourPlace.get()) {
 | 
			
		||||
                return COST_INF;
 | 
			
		||||
            }
 | 
			
		||||
            BlockPos positionToPlace = dest.down();
 | 
			
		||||
            IBlockState toPlace = BlockStateInterface.get(positionToPlace);
 | 
			
		||||
            if (!context.hasThrowaway()) {
 | 
			
		||||
                return COST_INF;
 | 
			
		||||
            }
 | 
			
		||||
            if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(positionToPlace, toPlace)) {
 | 
			
		||||
                return COST_INF;
 | 
			
		||||
            }
 | 
			
		||||
            for (int i = 0; i < 5; i++) {
 | 
			
		||||
                BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN_SO_EVERY_DIRECTION_EXCEPT_UP[i]);
 | 
			
		||||
                if (against1.up().equals(src.offset(direction, 3))) { // we can't turn around that fast
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if (MovementHelper.canPlaceAgainst(against1)) {
 | 
			
		||||
                    // holy jesus we gonna do it
 | 
			
		||||
                    placing = true;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Block walkOff = BlockStateInterface.get(src.down().offset(direction)).getBlock();
 | 
			
		||||
        if (MovementHelper.avoidWalkingInto(walkOff) && walkOff != Blocks.WATER && walkOff != Blocks.FLOWING_WATER) {
 | 
			
		||||
            return COST_INF;
 | 
			
		||||
        }
 | 
			
		||||
        for (int i = 1; i <= 4; i++) {
 | 
			
		||||
            BlockPos d = src.offset(direction, i);
 | 
			
		||||
            for (int y = 0; y < (i == 1 ? 3 : 4); y++) {
 | 
			
		||||
                if (!MovementHelper.fullyPassable(d.up(y))) {
 | 
			
		||||
                    return COST_INF;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (d.equals(dest)) {
 | 
			
		||||
                return costFromJumpDistance(i) + (placing ? context.placeBlockCost() : 0);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        throw new IllegalStateException("invalid jump distance?");
 | 
			
		||||
        return res.getSecond();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -209,7 +169,7 @@ public class MovementParkour extends Movement {
 | 
			
		||||
                if (!MovementHelper.canWalkOn(dest.down())) {
 | 
			
		||||
                    BlockPos positionToPlace = dest.down();
 | 
			
		||||
                    for (int i = 0; i < 5; i++) {
 | 
			
		||||
                        BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN_SO_EVERY_DIRECTION_EXCEPT_UP[i]);
 | 
			
		||||
                        BlockPos against1 = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]);
 | 
			
		||||
                        if (against1.up().equals(src.offset(direction, 3))) { // we can't turn around that fast
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
 
 | 
			
		||||
@@ -83,7 +83,7 @@ public class OpenSetsTest {
 | 
			
		||||
            assertTrue(set.isEmpty());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // generate the pathnodes that we'll be testing the sets on
 | 
			
		||||
        // cost the pathnodes that we'll be testing the sets on
 | 
			
		||||
        PathNode[] toInsert = new PathNode[size];
 | 
			
		||||
        for (int i = 0; i < size; i++) {
 | 
			
		||||
            // can't use an existing goal
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user