cool vine and ladder descending, fixes #159
This commit is contained in:
parent
28c2586452
commit
2760354943
@ -121,7 +121,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel
|
||||
if (actionCost >= ActionCosts.COST_INF) {
|
||||
continue;
|
||||
}
|
||||
if (actionCost <= 0) {
|
||||
if (actionCost <= 0 || Double.isNaN(actionCost)) {
|
||||
throw new IllegalStateException(moves + " calculated implausible cost " + actionCost);
|
||||
}
|
||||
if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218
|
||||
|
@ -73,6 +73,9 @@ public final class PathNode {
|
||||
this.previous = null;
|
||||
this.cost = ActionCosts.COST_INF;
|
||||
this.estimatedCostToGoal = goal.heuristic(x, y, z);
|
||||
if (Double.isNaN(estimatedCostToGoal)) {
|
||||
throw new IllegalStateException(goal + " calculated implausible heuristic");
|
||||
}
|
||||
this.isOpen = false;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
@ -115,66 +115,84 @@ public class MovementDescend extends Movement {
|
||||
res.cost = totalCost;
|
||||
}
|
||||
|
||||
public static void dynamicFallCost(CalculationContext context, int x, int y, int z, int destX, int destZ, double frontBreak, IBlockState below, MutableMoveResult res) {
|
||||
public static boolean dynamicFallCost(CalculationContext context, int x, int y, int z, int destX, int destZ, double frontBreak, IBlockState below, MutableMoveResult res) {
|
||||
if (frontBreak != 0 && context.get(destX, y + 2, destZ).getBlock() instanceof BlockFalling) {
|
||||
// if frontBreak is 0 we can actually get through this without updating the falling block and making it actually fall
|
||||
// but if frontBreak is nonzero, we're breaking blocks in front, so don't let anything fall through this column,
|
||||
// and potentially replace the water we're going to fall into
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (!MovementHelper.canWalkThrough(context.bsi(), destX, y - 2, destZ, below) && below.getBlock() != Blocks.WATER) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
double costSoFar = 0;
|
||||
int effectiveStartHeight = y;
|
||||
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
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
IBlockState ontoBlock = context.get(destX, newY, destZ);
|
||||
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[fallHeight] + frontBreak;
|
||||
if (ontoBlock.getBlock() == Blocks.WATER && !MovementHelper.isFlowing(ontoBlock) && context.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) { // TODO flowing check required here?
|
||||
int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY
|
||||
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
|
||||
if (ontoBlock.getBlock() == Blocks.WATER && context.getBlock(destX, newY + 1, destZ) != Blocks.WATERLILY) {
|
||||
// lilypads are canWalkThrough, but we can't end a fall that should be broken by water if it's covered by a lilypad
|
||||
// however, don't return impossible in the lilypad scenario, because we could still jump right on it (water that's below a lilypad is canWalkOn so it works)
|
||||
if (context.assumeWalkOnWater()) {
|
||||
return; // TODO fix
|
||||
return false; // TODO fix
|
||||
}
|
||||
if (MovementHelper.isFlowing(ontoBlock)) {
|
||||
return false; // TODO flowing check required here?
|
||||
}
|
||||
if (!MovementHelper.canWalkOn(context.bsi(), destX, newY - 1, destZ)) {
|
||||
// we could punch right through the water into something else
|
||||
return false;
|
||||
}
|
||||
// found a fall into water
|
||||
res.x = destX;
|
||||
res.y = newY;
|
||||
res.z = destZ;
|
||||
res.cost = tentativeCost;// TODO incorporate water swim up cost?
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (ontoBlock.getBlock() == Blocks.FLOWING_WATER) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (unprotectedFallHeight <= 11 && (ontoBlock.getBlock() == Blocks.VINE || ontoBlock.getBlock() == Blocks.LADDER)) {
|
||||
// if fall height is greater than or equal to 11, we don't actually grab on to vines or ladders. the more you know
|
||||
// this effectively "resets" our falling speed
|
||||
costSoFar += FALL_N_BLOCKS_COST[unprotectedFallHeight - 1];// we fall until the top of this block (not including this block)
|
||||
costSoFar += LADDER_DOWN_ONE_COST;
|
||||
effectiveStartHeight = newY;
|
||||
continue;
|
||||
}
|
||||
if (MovementHelper.canWalkThrough(context.bsi(), destX, newY, destZ, ontoBlock)) {
|
||||
continue;
|
||||
}
|
||||
if (!MovementHelper.canWalkOn(context.bsi(), destX, newY, destZ, ontoBlock)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (MovementHelper.isBottomSlab(ontoBlock)) {
|
||||
return; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
|
||||
return false; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
|
||||
}
|
||||
if (context.hasWaterBucket() && fallHeight <= context.maxFallHeightBucket() + 1) {
|
||||
if (context.hasWaterBucket() && unprotectedFallHeight <= context.maxFallHeightBucket() + 1) {
|
||||
res.x = destX;
|
||||
res.y = newY + 1;// this is the block we're falling onto, so dest is +1
|
||||
res.z = destZ;
|
||||
res.cost = tentativeCost + context.placeBlockCost();
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (fallHeight <= context.maxFallHeightNoWater() + 1) {
|
||||
if (unprotectedFallHeight <= context.maxFallHeightNoWater() + 1) {
|
||||
// fallHeight = 4 means onto.up() is 3 blocks down, which is the max
|
||||
res.x = destX;
|
||||
res.y = newY + 1;
|
||||
res.z = destZ;
|
||||
res.cost = tentativeCost;
|
||||
return;
|
||||
return false;
|
||||
} else {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
package baritone.pathing.movement.movements;
|
||||
|
||||
import baritone.Baritone;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.pathing.movement.MovementStatus;
|
||||
import baritone.api.utils.BetterBlockPos;
|
||||
@ -31,12 +30,19 @@ import baritone.pathing.movement.MovementHelper;
|
||||
import baritone.pathing.movement.MovementState;
|
||||
import baritone.pathing.movement.MovementState.MovementTarget;
|
||||
import baritone.utils.pathing.MutableMoveResult;
|
||||
import net.minecraft.block.BlockLadder;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class MovementFall extends Movement {
|
||||
|
||||
@ -57,6 +63,12 @@ public class MovementFall extends Movement {
|
||||
return result.cost;
|
||||
}
|
||||
|
||||
private boolean willPlaceBucket() {
|
||||
CalculationContext context = new CalculationContext(baritone);
|
||||
MutableMoveResult result = new MutableMoveResult();
|
||||
return MovementDescend.dynamicFallCost(context, src.x, src.y, src.z, dest.x, dest.z, 0, context.get(dest.x, src.y - 2, dest.z), result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MovementState updateState(MovementState state) {
|
||||
super.updateState(state);
|
||||
@ -67,7 +79,7 @@ public class MovementFall extends Movement {
|
||||
BlockPos playerFeet = ctx.playerFeet();
|
||||
Rotation toDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest));
|
||||
Rotation targetRotation = null;
|
||||
if (!MovementHelper.isWater(ctx, dest) && src.getY() - dest.getY() > Baritone.settings().maxFallHeightNoWater.get() && !playerFeet.equals(dest)) {
|
||||
if (!MovementHelper.isWater(ctx, dest) && willPlaceBucket() && !playerFeet.equals(dest)) {
|
||||
if (!InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().provider.isNether()) {
|
||||
return state.setStatus(MovementStatus.UNREACHABLE);
|
||||
}
|
||||
@ -78,7 +90,7 @@ public class MovementFall extends Movement {
|
||||
targetRotation = new Rotation(toDest.getYaw(), 90.0F);
|
||||
|
||||
RayTraceResult trace = ctx.objectMouseOver();
|
||||
if (trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK && ctx.player().rotationPitch > 89.0F) {
|
||||
if (trace != null && trace.typeOfHit == RayTraceResult.Type.BLOCK && (trace.getBlockPos().equals(dest) || trace.getBlockPos().equals(dest.down()))) {
|
||||
state.setInput(Input.CLICK_RIGHT, true);
|
||||
}
|
||||
}
|
||||
@ -107,12 +119,40 @@ public class MovementFall extends Movement {
|
||||
}
|
||||
}
|
||||
Vec3d destCenter = VecUtils.getBlockPosCenter(dest); // we are moving to the 0.5 center not the edge (like if we were falling on a ladder)
|
||||
if (Math.abs(ctx.player().posX - destCenter.x) > 0.15 || Math.abs(ctx.player().posZ - destCenter.z) > 0.15) {
|
||||
if (Math.abs(ctx.player().posX + ctx.player().motionX - destCenter.x) > 0.1 || Math.abs(ctx.player().posZ + ctx.player().motionZ - destCenter.z) > 0.1) {
|
||||
if (!ctx.player().onGround && Math.abs(ctx.player().motionY) > 0.4) {
|
||||
state.setInput(Input.SNEAK, true);
|
||||
}
|
||||
state.setInput(Input.MOVE_FORWARD, true);
|
||||
}
|
||||
Vec3i avoid = Optional.ofNullable(avoid()).map(EnumFacing::getDirectionVec).orElse(null);
|
||||
if (avoid == null) {
|
||||
avoid = src.subtract(dest);
|
||||
} else {
|
||||
double dist = Math.abs(avoid.getX() * (destCenter.x - avoid.getX() / 2.0 - ctx.player().posX)) + Math.abs(avoid.getZ() * (destCenter.z - avoid.getZ() / 2.0 - ctx.player().posZ));
|
||||
if (dist < 0.6) {
|
||||
state.setInput(Input.MOVE_FORWARD, true);
|
||||
} else {
|
||||
state.setInput(Input.SNEAK, false);
|
||||
}
|
||||
}
|
||||
if (targetRotation == null) {
|
||||
Vec3d destCenterOffset = new Vec3d(destCenter.x + 0.125 * avoid.getX(), destCenter.y, destCenter.z + 0.125 * avoid.getZ());
|
||||
state.setTarget(new MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), destCenterOffset), false));
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
private EnumFacing avoid() {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
IBlockState state = ctx.world().getBlockState(ctx.playerFeet().down(i));
|
||||
if (state.getBlock() == Blocks.LADDER) {
|
||||
return state.getValue(BlockLadder.FACING);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean safeToCancel(MovementState state) {
|
||||
// if we haven't started walking off the edge yet, or if we're in the process of breaking blocks before doing the fall
|
||||
|
Loading…
Reference in New Issue
Block a user