diff --git a/build.gradle b/build.gradle index 8583642d2..f356a3b22 100755 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,7 @@ apply plugin: 'org.spongepowered.mixin' sourceCompatibility = targetCompatibility = '1.8' compileJava { sourceCompatibility = targetCompatibility = '1.8' + options.encoding = "UTF-8" // allow emoji in comments :^) } sourceSets { @@ -101,6 +102,7 @@ mixin { javadoc { options.addStringOption('Xwerror', '-quiet') // makes the build fail on travis when there is a javadoc error options.linkSource true + options.encoding "UTF-8" // allow emoji in comments :^) source += sourceSets.api.allJava classpath += sourceSets.api.compileClasspath } diff --git a/src/api/java/baritone/api/behavior/IPathingBehavior.java b/src/api/java/baritone/api/behavior/IPathingBehavior.java index 0f44f2ee0..d28195ae9 100644 --- a/src/api/java/baritone/api/behavior/IPathingBehavior.java +++ b/src/api/java/baritone/api/behavior/IPathingBehavior.java @@ -37,7 +37,13 @@ public interface IPathingBehavior extends IBehavior { * * @return The estimated remaining ticks in the current segment. */ - Optional ticksRemainingInSegment(); + default Optional ticksRemainingInSegment() { + IPathExecutor current = getCurrent(); + if (current == null) { + return Optional.empty(); + } + return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition())); + } /** * @return The current pathing goal @@ -47,7 +53,9 @@ public interface IPathingBehavior extends IBehavior { /** * @return Whether or not a path is currently being executed. */ - boolean isPathing(); + default boolean isPathing() { + return getCurrent() != null; + } /** * Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path. diff --git a/src/api/java/baritone/api/pathing/path/IPathExecutor.java b/src/api/java/baritone/api/pathing/path/IPathExecutor.java index f72060dc0..a5c3108e1 100644 --- a/src/api/java/baritone/api/pathing/path/IPathExecutor.java +++ b/src/api/java/baritone/api/pathing/path/IPathExecutor.java @@ -26,4 +26,6 @@ import baritone.api.pathing.calc.IPath; public interface IPathExecutor { IPath getPath(); + + int getPosition(); } diff --git a/src/launch/java/baritone/launch/mixins/MixinKeyBinding.java b/src/launch/java/baritone/launch/mixins/MixinKeyBinding.java index cf8325335..6e215547e 100644 --- a/src/launch/java/baritone/launch/mixins/MixinKeyBinding.java +++ b/src/launch/java/baritone/launch/mixins/MixinKeyBinding.java @@ -34,7 +34,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; public class MixinKeyBinding { @Shadow - public int pressTime; + private int pressTime; @Inject( method = "isKeyDown", @@ -57,7 +57,7 @@ public class MixinKeyBinding { private void isPressed(CallbackInfoReturnable cir) { // only the primary baritone forces keys Boolean force = BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this); - if (force != null && force == false) { // <-- cursed + if (force != null && !force) { // <-- cursed if (pressTime > 0) { Helper.HELPER.logDirect("You're trying to press this mouse button but I won't let you"); pressTime--; diff --git a/src/main/java/baritone/behavior/PathingBehavior.java b/src/main/java/baritone/behavior/PathingBehavior.java index 74cc46eef..ea7520825 100644 --- a/src/main/java/baritone/behavior/PathingBehavior.java +++ b/src/main/java/baritone/behavior/PathingBehavior.java @@ -30,7 +30,6 @@ import baritone.pathing.calc.AStarPathFinder; import baritone.pathing.calc.AbstractNodeCostSearch; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.MovementHelper; -import baritone.pathing.path.CutoffPath; import baritone.pathing.path.PathExecutor; import baritone.utils.Helper; import baritone.utils.PathRenderer; @@ -125,7 +124,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, next = null; return; } - if (next != null && !next.getPath().positions().contains(ctx.playerFeet())) { + if (next != null && !next.getPath().positions().contains(ctx.playerFeet()) && !next.getPath().positions().contains(pathStart())) { // can contain either one // if the current path failed, we may not actually be on the next one, so make sure logDebug("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 @@ -141,16 +140,27 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, queuePathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT); current = next; next = null; - current.onTick(); + current.onTick(); // don't waste a tick doing nothing, get started right away return; } // at this point, current just ended, but we aren't in the goal and have no plan for the future synchronized (pathCalcLock) { if (inProgress != null) { - queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING); - // if we aren't calculating right now - return; + // we are calculating + // are we calculating the right thing though? 🤔 + BetterBlockPos calcFrom = inProgress.getStart(); + // if current just succeeded, we should be standing in calcFrom, so that's cool and good + // but if current just failed, we should discard this calculation since it doesn't start from where we're standing + if (calcFrom.equals(ctx.playerFeet()) || calcFrom.equals(pathStart())) { + // cool and good + queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING); + return; + } + // oh noes + inProgress.cancel(); // cancellation doesn't dispatch any events + inProgress = null; // this is safe since we hold both locks } + // we aren't calculating queuePathEvent(PathEvent.CALC_STARTED); findPathInNewThread(pathStart(), true); } @@ -180,11 +190,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, return; } if (goal == null || goal.isInGoal(current.getPath().getDest())) { - // and this path dosen't get us all the way there + // and this path doesn't get us all the way there return; } if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) { - // and this path has 5 seconds or less left + // and this path has 7.5 seconds or less left logDebug("Path almost over. Planning ahead..."); queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED); findPathInNewThread(current.getPath().getDest(), false); @@ -210,14 +220,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, } } - @Override - public Optional ticksRemainingInSegment() { - if (current == null) { - return Optional.empty(); - } - return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition())); - } - public void secretInternalSetGoal(Goal goal) { this.goal = goal; } @@ -247,11 +249,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, return Optional.ofNullable(inProgress); } - @Override - public boolean isPathing() { - return this.current != null; - } - public boolean isSafeToCancel() { return current == null || safeToCancel; } @@ -274,7 +271,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, if (doIt) { secretInternalSegmentCancel(); } - baritone.getPathingControlManager().cancelEverything(); + baritone.getPathingControlManager().cancelEverything(); // regardless of if we can stop the current segment, we can still stop the processes return doIt; } @@ -310,7 +307,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, public void forceCancel() { // NOT exposed on public api cancelEverything(); secretInternalSegmentCancel(); - inProgress = null; + synchronized (pathCalcLock) { + inProgress = null; + } } /** @@ -433,33 +432,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior, } PathCalculationResult calcResult = pathfinder.calculate(primaryTimeout, failureTimeout); - Optional path = calcResult.getPath(); - if (Baritone.settings().cutoffAtLoadBoundary.get()) { - path = path.map(p -> { - IPath result = p.cutoffAtLoadedChunks(context.bsi); - - if (result instanceof CutoffPath) { - logDebug("Cutting off path at edge of loaded chunks"); - logDebug("Length decreased by " + (p.length() - result.length())); - } else { - logDebug("Path ends within loaded chunks"); - } - - return result; - }); - } - - Optional executor = path.map(p -> { - IPath result = p.staticCutoff(goal); - - if (result instanceof CutoffPath) { - logDebug("Static cutoff " + p.length() + " to " + result.length()); - } - - return result; - }).map(p -> new PathExecutor(this, p)); - synchronized (pathPlanLock) { + Optional executor = calcResult.getPath().map(p -> new PathExecutor(PathingBehavior.this, p)); if (current == null) { if (executor.isPresent()) { queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING); diff --git a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java index 78710204f..625e8e592 100644 --- a/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java +++ b/src/main/java/baritone/pathing/calc/AbstractNodeCostSearch.java @@ -92,13 +92,25 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { cancelRequested = false; try { IPath path = calculate0(primaryTimeout, failureTimeout).map(IPath::postProcess).orElse(null); - isFinished = true; if (cancelRequested) { - return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION, path); + return new PathCalculationResult(PathCalculationResult.Type.CANCELLATION); } if (path == null) { return new PathCalculationResult(PathCalculationResult.Type.FAILURE); } + int previousLength = path.length(); + path = path.cutoffAtLoadedChunks(context.bsi); + if (path.length() < previousLength) { + Helper.HELPER.logDebug("Cutting off path at edge of loaded chunks"); + Helper.HELPER.logDebug("Length decreased by " + (previousLength - path.length())); + } else { + Helper.HELPER.logDebug("Path ends within loaded chunks"); + } + previousLength = path.length(); + path = path.staticCutoff(goal); + if (path.length() < previousLength) { + Helper.HELPER.logDebug("Static cutoff " + previousLength + " to " + path.length()); + } if (goal.isInGoal(path.getDest())) { return new PathCalculationResult(PathCalculationResult.Type.SUCCESS_TO_GOAL, path); } else { @@ -163,7 +175,7 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { } @Override - public Optional bestPathSoFar() { + public Optional bestPathSoFar() { // TODO cleanup code duplication between here and AStarPathFinder if (startNode == null || bestSoFar == null) { return Optional.empty(); } @@ -189,4 +201,8 @@ public abstract class AbstractNodeCostSearch implements IPathFinder { public final Goal getGoal() { return goal; } + + public BetterBlockPos getStart() { + return new BetterBlockPos(startX, startY, startZ); + } } diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index d07f05e78..f91103d08 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -18,7 +18,9 @@ package baritone.pathing.movement; import baritone.Baritone; +import baritone.api.IBaritone; import baritone.api.pathing.movement.ActionCosts; +import baritone.api.pathing.movement.MovementStatus; import baritone.api.utils.*; import baritone.api.utils.input.Input; import baritone.pathing.movement.MovementState.MovementTarget; @@ -35,6 +37,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; + +import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP; /** * Static helpers for cost calculation @@ -485,4 +491,48 @@ public interface MovementHelper extends ActionCosts, Helper { return state.getBlock() instanceof BlockLiquid && state.getValue(BlockLiquid.LEVEL) != 0; } + + static PlaceResult attemptToPlaceABlock(MovementState state, IBaritone baritone, BlockPos placeAt, boolean preferDown) { + IPlayerContext ctx = baritone.getPlayerContext(); + boolean found = false; + for (int i = 0; i < 5; i++) { + BlockPos against1 = placeAt.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]); + if (MovementHelper.canPlaceAgainst(ctx, against1)) { + //if (!((Baritone) baritone).getInventoryBehavior().selectThrowawayForLocation(placeAt.getX(), placeAt.getY(), placeAt.getZ())) { // get ready to place a throwaway block + if (!throwaway(ctx, true)) { + Helper.HELPER.logDebug("bb pls get me some blocks. dirt or cobble"); + state.setStatus(MovementStatus.UNREACHABLE); + return PlaceResult.NO_OPTION; + } + double faceX = (placeAt.getX() + against1.getX() + 1.0D) * 0.5D; + double faceY = (placeAt.getY() + against1.getY() + 1.0D) * 0.5D; + double faceZ = (placeAt.getZ() + against1.getZ() + 1.0D) * 0.5D; + Rotation place = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations()); + RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), place, ctx.playerController().getBlockReachDistance()); + if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(placeAt)) { + state.setTarget(new MovementState.MovementTarget(place, true)); + found = true; + + if (!preferDown) { + // if preferDown is true, we want the last option + // if preferDown is false, we want the first + break; + } + } + } + } + if (ctx.getSelectedBlock().isPresent()) { + BlockPos selectedBlock = ctx.getSelectedBlock().get(); + EnumFacing side = ctx.objectMouseOver().sideHit; + // only way for selectedBlock.equals(placeAt) to be true is if it's replacable + if (selectedBlock.equals(placeAt) || (MovementHelper.canPlaceAgainst(ctx, selectedBlock) && selectedBlock.offset(side).equals(placeAt))) { + return PlaceResult.READY_TO_PLACE; + } + } + return found ? PlaceResult.ATTEMPTING : PlaceResult.NO_OPTION; + } + + enum PlaceResult { + READY_TO_PLACE, ATTEMPTING, NO_OPTION; + } } diff --git a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java index 2e20dd6e1..97eaa7fb0 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java @@ -21,7 +21,6 @@ import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.pathing.movement.MovementStatus; import baritone.api.utils.BetterBlockPos; -import baritone.api.utils.RotationUtils; import baritone.api.utils.input.Input; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; @@ -32,10 +31,6 @@ import net.minecraft.block.BlockFalling; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; - -import java.util.Objects; public class MovementAscend extends Movement { @@ -162,55 +157,30 @@ public class MovementAscend extends Movement { IBlockState jumpingOnto = BlockStateInterface.get(ctx, positionToPlace); if (!MovementHelper.canWalkOn(ctx, positionToPlace, jumpingOnto)) { - for (int i = 0; i < 5; i++) { - BlockPos anAgainst = positionToPlace.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]); - if (anAgainst.equals(src)) { - continue; - } - if (MovementHelper.canPlaceAgainst(ctx, anAgainst)) { - if (!MovementHelper.throwaway(ctx, true)) {//get ready to place a throwaway block - return state.setStatus(MovementStatus.UNREACHABLE); - } - double faceX = (dest.getX() + anAgainst.getX() + 1.0D) * 0.5D; - double faceY = (dest.getY() + anAgainst.getY()) * 0.5D; - double faceZ = (dest.getZ() + anAgainst.getZ() + 1.0D) * 0.5D; - state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations()), true)); - EnumFacing side = ctx.objectMouseOver().sideHit; - - ctx.getSelectedBlock().ifPresent(selectedBlock -> { - if (Objects.equals(selectedBlock, anAgainst) && selectedBlock.offset(side).equals(positionToPlace)) { - ticksWithoutPlacement++; - state.setInput(Input.SNEAK, true); - if (ctx.player().isSneaking()) { - state.setInput(Input.CLICK_RIGHT, true); - } - if (ticksWithoutPlacement > 10) { - // After 10 ticks without placement, we might be standing in the way, move back - state.setInput(Input.MOVE_BACK, true); - } - } else { - state.setInput(Input.CLICK_LEFT, true); // break whatever replaceable block is in the way - } - //System.out.println("Trying to look at " + anAgainst + ", actually looking at" + selectedBlock); - }); - return state; + ticksWithoutPlacement++; + if (MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), false) == PlaceResult.READY_TO_PLACE) { + state.setInput(Input.SNEAK, true); + if (ctx.player().isSneaking()) { + state.setInput(Input.CLICK_RIGHT, true); } } - return state.setStatus(MovementStatus.UNREACHABLE); + if (ticksWithoutPlacement > 10) { + // After 10 ticks without placement, we might be standing in the way, move back + state.setInput(Input.MOVE_BACK, true); + } + + return state; } MovementHelper.moveTowards(ctx, state, dest); if (MovementHelper.isBottomSlab(jumpingOnto) && !MovementHelper.isBottomSlab(BlockStateInterface.get(ctx, src.down()))) { return state; // don't jump while walking from a non double slab into a bottom slab } - if (Baritone.settings().assumeStep.get()) { + if (Baritone.settings().assumeStep.get() || ctx.playerFeet().equals(src.up())) { + // no need to hit space if we're already jumping return state; } - if (ctx.playerFeet().equals(src.up())) { - return state; // no need to hit space if we're already jumping - } - if (headBonkClear()) { return state.setInput(Input.JUMP, true); } diff --git a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java index d54ffc51e..aeb4e138f 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementDescend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementDescend.java @@ -137,7 +137,7 @@ public class MovementDescend extends Movement { IBlockState ontoBlock = context.get(destX, newY, destZ); 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) { + if ((ontoBlock.getBlock() == Blocks.WATER || ontoBlock.getBlock() == Blocks.FLOWING_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) { @@ -157,9 +157,6 @@ public class MovementDescend extends Movement { res.cost = tentativeCost;// TODO incorporate water swim up cost? return false; } - if (ontoBlock.getBlock() == Blocks.FLOWING_WATER) { - 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 diff --git a/src/main/java/baritone/pathing/movement/movements/MovementFall.java b/src/main/java/baritone/pathing/movement/movements/MovementFall.java index a82ad110a..729a2f1de 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementFall.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementFall.java @@ -81,7 +81,8 @@ public class MovementFall extends Movement { Rotation toDest = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest)); Rotation targetRotation = null; Block destBlock = ctx.world().getBlockState(dest).getBlock(); - if (destBlock != Blocks.WATER && destBlock != Blocks.FLOWING_WATER && willPlaceBucket() && !playerFeet.equals(dest)) { + boolean isWater = destBlock == Blocks.WATER || destBlock == Blocks.FLOWING_WATER; + if (!isWater && willPlaceBucket() && !playerFeet.equals(dest)) { if (!InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_WATER)) || ctx.world().provider.isNether()) { return state.setStatus(MovementStatus.UNREACHABLE); } @@ -102,8 +103,8 @@ public class MovementFall extends Movement { } else { state.setTarget(new MovementTarget(toDest, false)); } - if (playerFeet.equals(dest) && (ctx.player().posY - playerFeet.getY() < 0.094 || destBlock == Blocks.WATER)) { // 0.094 because lilypads - if (destBlock == Blocks.WATER) { // only match water, not flowing water (which we cannot pick up with a bucket) + if (playerFeet.equals(dest) && (ctx.player().posY - playerFeet.getY() < 0.094 || isWater)) { // 0.094 because lilypads + if (isWater) { // only match water, not flowing water (which we cannot pick up with a bucket) if (InventoryPlayer.isHotbar(ctx.player().inventory.getSlotFor(STACK_BUCKET_EMPTY))) { ctx.player().inventory.currentItem = ctx.player().inventory.getSlotFor(STACK_BUCKET_EMPTY); if (ctx.player().motionY >= 0) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java index ab98d3d08..38fd510ac 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java @@ -20,9 +20,6 @@ package baritone.pathing.movement.movements; import baritone.api.IBaritone; import baritone.api.pathing.movement.MovementStatus; import baritone.api.utils.BetterBlockPos; -import baritone.api.utils.RayTraceUtils; -import baritone.api.utils.Rotation; -import baritone.api.utils.RotationUtils; import baritone.api.utils.input.Input; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; @@ -35,9 +32,6 @@ import net.minecraft.block.BlockStairs; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; public class MovementParkour extends Movement { @@ -209,35 +203,9 @@ public class MovementParkour extends Movement { } } else if (!ctx.playerFeet().equals(src)) { if (ctx.playerFeet().equals(src.offset(direction)) || ctx.player().posY - ctx.playerFeet().getY() > 0.0001) { - - if (!MovementHelper.canWalkOn(ctx, dest.down()) && !ctx.player().onGround) { - BlockPos positionToPlace = dest.down(); - for (int i = 4; i >= 0; i--) { // go in the opposite order to check DOWN before all horizontals -- down is preferable because you don't have to look to the side while in midair, which could mess up the trajectory - 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(ctx, against1)) { - if (!MovementHelper.throwaway(ctx, true)) {//get ready to place a throwaway block - return state.setStatus(MovementStatus.UNREACHABLE); - } - double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D; - double faceY = (dest.getY() + against1.getY()) * 0.5D; - double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D; - Rotation place = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations()); - RayTraceResult res = RayTraceUtils.rayTraceTowards(ctx.player(), place, ctx.playerController().getBlockReachDistance()); - if (res != null && res.typeOfHit == RayTraceResult.Type.BLOCK && res.getBlockPos().equals(against1) && res.getBlockPos().offset(res.sideHit).equals(dest.down())) { - state.setTarget(new MovementState.MovementTarget(place, true)); - break; - } - } - } - ctx.getSelectedBlock().ifPresent(selectedBlock -> { - EnumFacing side = ctx.objectMouseOver().sideHit; - if (MovementHelper.canPlaceAgainst(ctx, selectedBlock) && selectedBlock.offset(side).equals(dest.down())) { - state.setInput(Input.CLICK_RIGHT, true); - } - }); + if (!MovementHelper.canWalkOn(ctx, dest.down()) && !ctx.player().onGround && MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), true) == PlaceResult.READY_TO_PLACE) { + // go in the opposite order to check DOWN before all horizontals -- down is preferable because you don't have to look to the side while in midair, which could mess up the trajectory + state.setInput(Input.CLICK_RIGHT, true); } if (dist == 3) { // this is a 2 block gap, dest = src + direction * 3 double xDiff = (src.x + 0.5) - ctx.player().posX; diff --git a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java index b236f7e2b..03bdb6f71 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java @@ -35,6 +35,8 @@ import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import java.util.Objects; + public class MovementPillar extends Movement { public MovementPillar(IBaritone baritone, BetterBlockPos start, BetterBlockPos end) { @@ -224,7 +226,7 @@ public class MovementPillar extends Movement { if (!(fr instanceof BlockAir || fr.isReplaceable(ctx.world(), src))) { state.setInput(Input.CLICK_LEFT, true); blockIsThere = false; - } else if (ctx.player().isSneaking()) { // 1 tick after we're able to place + } else if (ctx.player().isSneaking() && (Objects.equals(src.down(), ctx.objectMouseOver().getBlockPos()) || Objects.equals(src, ctx.objectMouseOver().getBlockPos()))) { state.setInput(Input.CLICK_RIGHT, true); } } diff --git a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java index 4a87a8a64..4f9b6b518 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java @@ -36,7 +36,6 @@ import net.minecraft.block.BlockFenceGate; import net.minecraft.block.BlockSlab; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; -import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -136,7 +135,7 @@ public class MovementTraverse extends Movement { } // now that we've checked all possible directions to side place, we actually need to backplace if (srcDown == Blocks.SOUL_SAND || (srcDown instanceof BlockSlab && !((BlockSlab) srcDown).isDouble())) { - return COST_INF; // can't sneak and backplace against soul sand or half slabs =/ + return COST_INF; // can't sneak and backplace against soul sand or half slabs (regardless of whether it's top half or bottom half) =/ } if (srcDown == Blocks.FLOWING_WATER || srcDown == Blocks.WATER) { return COST_INF; // this is obviously impossible @@ -247,53 +246,45 @@ public class MovementTraverse extends Movement { return state; } else { wasTheBridgeBlockAlwaysThere = false; - for (int i = 0; i < 5; i++) { - BlockPos against1 = dest.offset(HORIZONTALS_BUT_ALSO_DOWN____SO_EVERY_DIRECTION_EXCEPT_UP[i]); - if (against1.equals(src)) { - continue; - } - against1 = against1.down(); - if (MovementHelper.canPlaceAgainst(ctx, against1)) { - if (!MovementHelper.throwaway(ctx, true)) { // get ready to place a throwaway block - logDebug("bb pls get me some blocks. dirt or cobble"); - return state.setStatus(MovementStatus.UNREACHABLE); - } - if (!Baritone.settings().assumeSafeWalk.get()) { - state.setInput(Input.SNEAK, true); - } - Block standingOn = BlockStateInterface.get(ctx, ctx.playerFeet().down()).getBlock(); - if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof BlockSlab) { // see issue #118 - double dist = Math.max(Math.abs(dest.getX() + 0.5 - ctx.player().posX), Math.abs(dest.getZ() + 0.5 - ctx.player().posZ)); - if (dist < 0.85) { // 0.5 + 0.3 + epsilon - MovementHelper.moveTowards(ctx, state, dest); - return state.setInput(Input.MOVE_FORWARD, false) - .setInput(Input.MOVE_BACK, true); - } - } - state.setInput(Input.MOVE_BACK, false); - double faceX = (dest.getX() + against1.getX() + 1.0D) * 0.5D; - double faceY = (dest.getY() + against1.getY()) * 0.5D; - double faceZ = (dest.getZ() + against1.getZ() + 1.0D) * 0.5D; - state.setTarget(new MovementState.MovementTarget(RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations()), true)); - - EnumFacing side = ctx.objectMouseOver().sideHit; - if (Objects.equals(ctx.getSelectedBlock().orElse(null), against1) && (ctx.player().isSneaking() || Baritone.settings().assumeSafeWalk.get()) && ctx.getSelectedBlock().get().offset(side).equals(positionToPlace)) { - return state.setInput(Input.CLICK_RIGHT, true); - } - //System.out.println("Trying to look at " + against1 + ", actually looking at" + RayTraceUtils.getSelectedBlock()); - return state.setInput(Input.CLICK_LEFT, true); + Block standingOn = BlockStateInterface.get(ctx, ctx.playerFeet().down()).getBlock(); + if (standingOn.equals(Blocks.SOUL_SAND) || standingOn instanceof BlockSlab) { // see issue #118 + double dist = Math.max(Math.abs(dest.getX() + 0.5 - ctx.player().posX), Math.abs(dest.getZ() + 0.5 - ctx.player().posZ)); + if (dist < 0.85) { // 0.5 + 0.3 + epsilon + MovementHelper.moveTowards(ctx, state, dest); + return state.setInput(Input.MOVE_FORWARD, false) + .setInput(Input.MOVE_BACK, true); } } - if (!Baritone.settings().assumeSafeWalk.get()) { + double dist1 = Math.max(Math.abs(ctx.player().posX - (dest.getX() + 0.5D)), Math.abs(ctx.player().posZ - (dest.getZ() + 0.5D))); + PlaceResult p = MovementHelper.attemptToPlaceABlock(state, baritone, dest.down(), false); + if ((p == PlaceResult.READY_TO_PLACE || dist1 < 0.6) && !Baritone.settings().assumeSafeWalk.get()) { state.setInput(Input.SNEAK, true); } + switch (p) { + case READY_TO_PLACE: { + if (ctx.player().isSneaking() || Baritone.settings().assumeSafeWalk.get()) { + state.setInput(Input.CLICK_RIGHT, true); + } + return state; + } + case ATTEMPTING: { + if (dist1 > 0.83) { + // might need to go forward a bit + float yaw = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), VecUtils.getBlockPosCenter(dest), ctx.playerRotations()).getYaw(); + if (Math.abs(state.getTarget().rotation.getYaw() - yaw) < 0.1) { + // but only if our attempted place is straight ahead + return state.setInput(Input.MOVE_FORWARD, true); + } + } else if (ctx.playerRotations().isReallyCloseTo(state.getTarget().rotation)) { + // well i guess theres something in the way + return state.setInput(Input.CLICK_LEFT, true); + } + return state; + } + } if (whereAmI.equals(dest)) { // If we are in the block that we are trying to get to, we are sneaking over air and we need to place a block beneath us against the one we just walked off of // Out.log(from + " " + to + " " + faceX + "," + faceY + "," + faceZ + " " + whereAmI); - if (!MovementHelper.throwaway(ctx, true)) {// get ready to place a throwaway block - logDebug("bb pls get me some blocks. dirt or cobble"); - return state.setStatus(MovementStatus.UNREACHABLE); - } double faceX = (dest.getX() + src.getX() + 1.0D) * 0.5D; double faceY = (dest.getY() + src.getY() - 1.0D) * 0.5D; double faceZ = (dest.getZ() + src.getZ() + 1.0D) * 0.5D; @@ -302,25 +293,26 @@ public class MovementTraverse extends Movement { Rotation backToFace = RotationUtils.calcRotationFromVec3d(ctx.playerHead(), new Vec3d(faceX, faceY, faceZ), ctx.playerRotations()); float pitch = backToFace.getPitch(); - double dist = Math.max(Math.abs(ctx.player().posX - faceX), Math.abs(ctx.player().posZ - faceZ)); - if (dist < 0.29) { + double dist2 = Math.max(Math.abs(ctx.player().posX - faceX), Math.abs(ctx.player().posZ - faceZ)); + if (dist2 < 0.29) { // see issue #208 float yaw = RotationUtils.calcRotationFromVec3d(VecUtils.getBlockPosCenter(dest), ctx.playerHead(), ctx.playerRotations()).getYaw(); state.setTarget(new MovementState.MovementTarget(new Rotation(yaw, pitch), true)); state.setInput(Input.MOVE_BACK, true); } else { state.setTarget(new MovementState.MovementTarget(backToFace, true)); } - state.setInput(Input.SNEAK, true); if (Objects.equals(ctx.getSelectedBlock().orElse(null), goalLook)) { return state.setInput(Input.CLICK_RIGHT, true); // wait to right click until we are able to place } // Out.log("Trying to look at " + goalLook + ", actually looking at" + Baritone.whatAreYouLookingAt()); - return state.setInput(Input.CLICK_LEFT, true); - } else { - MovementHelper.moveTowards(ctx, state, positionsToBreak[0]); + if (ctx.playerRotations().isReallyCloseTo(state.getTarget().rotation)) { + state.setInput(Input.CLICK_LEFT, true); + } return state; - // TODO MovementManager.moveTowardsBlock(to); // move towards not look at because if we are bridging for a couple blocks in a row, it is faster if we dont spin around and walk forwards then spin around and place backwards for every block } + MovementHelper.moveTowards(ctx, state, positionsToBreak[0]); + return state; + // TODO MovementManager.moveTowardsBlock(to); // move towards not look at because if we are bridging for a couple blocks in a row, it is faster if we dont spin around and walk forwards then spin around and place backwards for every block } } @@ -342,4 +334,4 @@ public class MovementTraverse extends Movement { } return super.prepared(state); } -} +} \ No newline at end of file diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java index 6f161cc0b..a2c0e2ff2 100644 --- a/src/main/java/baritone/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/pathing/path/PathExecutor.java @@ -461,6 +461,7 @@ public class PathExecutor implements IPathExecutor, Helper { failed = true; } + @Override public int getPosition() { return pathPosition; } diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index d3883bbbe..806774561 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -94,14 +94,14 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro if (Baritone.settings().legitMine.get()) { addNearby(); } - Goal goal = updateGoal(); - if (goal == null) { + PathingCommand command = updateGoal(); + if (command == null) { // none in range // maybe say something in chat? (ahem impact) cancel(); return null; } - return new PathingCommand(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH); + return command; } @Override @@ -114,17 +114,18 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro return "Mine " + mining; } - private Goal updateGoal() { + private PathingCommand updateGoal() { + boolean legit = Baritone.settings().legitMine.get(); List locs = knownOreLocations; if (!locs.isEmpty()) { List locs2 = prune(new CalculationContext(baritone), new ArrayList<>(locs), mining, ORE_LOCATIONS_COUNT); // can't reassign locs, gotta make a new var locs2, because we use it in a lambda right here, and variables you use in a lambda must be effectively final Goal goal = new GoalComposite(locs2.stream().map(loc -> coalesce(ctx, loc, locs2)).toArray(Goal[]::new)); knownOreLocations = locs2; - return goal; + return new PathingCommand(goal, legit ? PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH : PathingCommandType.REVALIDATE_GOAL_AND_PATH); } // we don't know any ore locations at the moment - if (!Baritone.settings().legitMine.get()) { + if (!legit) { return null; } // only in non-Xray mode (aka legit mode) do we do this @@ -149,7 +150,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro } }; } - return branchPointRunaway; + return new PathingCommand(branchPointRunaway, PathingCommandType.REVALIDATE_GOAL_AND_PATH); } private void rescan(List already, CalculationContext context) { diff --git a/src/main/java/baritone/utils/pathing/PathBase.java b/src/main/java/baritone/utils/pathing/PathBase.java index 04fe9872c..3acf80b4e 100644 --- a/src/main/java/baritone/utils/pathing/PathBase.java +++ b/src/main/java/baritone/utils/pathing/PathBase.java @@ -17,6 +17,7 @@ package baritone.utils.pathing; +import baritone.Baritone; import baritone.api.BaritoneAPI; import baritone.api.pathing.calc.IPath; import baritone.api.pathing.goals.Goal; @@ -27,6 +28,9 @@ import net.minecraft.util.math.BlockPos; public abstract class PathBase implements IPath { @Override public PathBase cutoffAtLoadedChunks(Object bsi0) { // <-- cursed cursed cursed + if (!Baritone.settings().cutoffAtLoadBoundary.get()) { + return this; + } BlockStateInterface bsi = (BlockStateInterface) bsi0; for (int i = 0; i < positions().size(); i++) { BlockPos pos = positions().get(i);