diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index dc7669e75..799e4dd63 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -31,7 +31,6 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Mirror; import net.minecraft.world.level.block.Rotation; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,8 +42,8 @@ import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.List; import java.util.*; +import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -1489,7 +1488,7 @@ public final class Settings { public final Setting elytraRenderSimulation = new Setting<>(true); /** - * Automatically path to and jump off of ledges to initiate elytra flight when grounded. + * Automatically jump to initiate elytra flight when grounded. */ public final Setting elytraAutoJump = new Setting<>(false); diff --git a/src/main/java/baritone/process/ElytraProcess.java b/src/main/java/baritone/process/ElytraProcess.java index 276ab431b..09a0b10fd 100644 --- a/src/main/java/baritone/process/ElytraProcess.java +++ b/src/main/java/baritone/process/ElytraProcess.java @@ -18,16 +18,12 @@ package baritone.process; import baritone.Baritone; -import baritone.api.IBaritone; import baritone.api.event.events.*; import baritone.api.event.events.type.EventState; import baritone.api.event.listener.AbstractGameEventListener; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalBlock; import baritone.api.pathing.goals.GoalXZ; -import baritone.api.pathing.goals.GoalYLevel; -import baritone.api.pathing.movement.IMovement; -import baritone.api.pathing.path.IPathExecutor; import baritone.api.process.IBaritoneProcess; import baritone.api.process.IElytraProcess; import baritone.api.process.PathingCommand; @@ -36,13 +32,10 @@ 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.movements.MovementFall; import baritone.process.elytra.ElytraBehavior; import baritone.process.elytra.NetherPathfinderContext; import baritone.process.elytra.NullElytraProcess; import baritone.utils.BaritoneProcessHelper; -import baritone.utils.PathingCommandContext; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import net.minecraft.core.BlockPos; import net.minecraft.core.NonNullList; @@ -53,21 +46,18 @@ import net.minecraft.world.level.block.AirBlock; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; import java.util.*; -import static baritone.api.pathing.movement.ActionCosts.COST_INF; - public class ElytraProcess extends BaritoneProcessHelper implements IBaritoneProcess, IElytraProcess, AbstractGameEventListener { public State state; private boolean goingToLandingSpot; private BetterBlockPos landingSpot; private boolean reachedGoal; // this basically just prevents potential notification spam - private Goal goal; private ElytraBehavior behavior; private boolean predictingTerrain; + private long startedJumpStateTime = 0L; @Override public void onLostControl() { @@ -75,7 +65,7 @@ public void onLostControl() { this.goingToLandingSpot = false; this.landingSpot = null; this.reachedGoal = false; - this.goal = null; + startedJumpStateTime = 0L; destroyBehaviorAsync(); } @@ -105,8 +95,6 @@ public void resetState() { } } - private static final String AUTO_JUMP_FAILURE_MSG = "Failed to compute a walking path to a spot to jump off from. Consider starting from a higher location, near an overhang. Or, you can disable elytraAutoJump and just manually begin gliding."; - @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { final long seedSetting = Baritone.settings().elytraNetherSeed.value; @@ -124,7 +112,6 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (calcFailed) { onLostControl(); - logDirect(AUTO_JUMP_FAILURE_MSG); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } @@ -187,7 +174,6 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (ctx.player().isFallFlying()) { behavior.landingMode = this.state == State.LANDING; - this.goal = null; baritone.getInputOverrideHandler().clearAllKeys(); behavior.tick(); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); @@ -205,46 +191,41 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { if (this.state == State.FLYING || this.state == State.START_FLYING) { this.state = ctx.player().isOnGround() && Baritone.settings().elytraAutoJump.value - ? State.LOCATE_JUMP + ? State.JUMP : State.START_FLYING; } - if (this.state == State.LOCATE_JUMP) { + if (this.state == State.JUMP) { + if (startedJumpStateTime == 0L) { + startedJumpStateTime = System.currentTimeMillis(); + } if (shouldLandForSafety()) { logDirect("Not taking off, because elytra durability or fireworks are so low that I would immediately emergency land anyway."); onLostControl(); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } - if (this.goal == null) { - this.goal = new GoalYLevel(31); + final boolean isJumpBlocked = !ctx.world().getBlockCollisions(ctx.player(), ctx.player().getBoundingBox().move(0, 0.5, 0)).iterator().hasNext(); + if (ctx.player().isOnGround() && isJumpBlocked) { + ctx.player().jumpFromGround(); + return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } - final IPathExecutor executor = baritone.getPathingBehavior().getCurrent(); - if (executor != null && executor.getPath().getGoal() == this.goal) { - final IMovement fall = executor.getPath().movements().stream() - .filter(movement -> movement instanceof MovementFall) - .findFirst().orElse(null); - - if (fall != null) { - final BetterBlockPos from = new BetterBlockPos( - (fall.getSrc().x + fall.getDest().x) / 2, - (fall.getSrc().y + fall.getDest().y) / 2, - (fall.getSrc().z + fall.getDest().z) / 2 + final boolean canStartFlying = !ctx.player().isOnGround() && !ctx.player().isFallFlying(); + + if (canStartFlying) { + this.state = State.START_FLYING; + } else { + // todo: would be better if we searched for a safe pos to takeoff from, and then pathed directly there + if (System.currentTimeMillis() - startedJumpStateTime > 2500) { + logDirect("Unable to perform autoJump takeoff, pathing forward"); + final GoalXZ goal = GoalXZ.fromDirection( + ctx.playerFeetAsVec(), + ctx.player().getYHeadRot(), + 5 ); - behavior.pathManager.pathToDestination(from).whenComplete((result, ex) -> { - if (ex == null) { - this.state = State.GET_TO_JUMP; - return; - } - onLostControl(); - }); - this.state = State.PAUSE; - } else { - onLostControl(); - logDirect(AUTO_JUMP_FAILURE_MSG); - return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); + return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH); } + return new PathingCommand(null, PathingCommandType.SET_GOAL_AND_PATH); } - return new PathingCommandContext(this.goal, PathingCommandType.SET_GOAL_AND_PAUSE, new WalkOffCalculationContext(baritone)); } // yucky @@ -252,27 +233,13 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } - if (this.state == State.GET_TO_JUMP) { - final IPathExecutor executor = baritone.getPathingBehavior().getCurrent(); - final boolean canStartFlying = ctx.player().fallDistance > 1.0f - && !isSafeToCancel - && executor != null - && executor.getPath().movements().get(executor.getPosition()) instanceof MovementFall; - - if (canStartFlying) { - this.state = State.START_FLYING; - } else { - return new PathingCommand(null, PathingCommandType.SET_GOAL_AND_PATH); - } - } - if (this.state == State.START_FLYING) { if (!isSafeToCancel) { // owned baritone.getPathingBehavior().secretInternalSegmentCancel(); } baritone.getInputOverrideHandler().clearAllKeys(); - if (ctx.player().fallDistance > 1.0f) { + if (!ctx.player().isOnGround() && !ctx.player().input.jumping) { baritone.getInputOverrideHandler().setInputForceState(Input.JUMP, true); } } @@ -394,9 +361,8 @@ public boolean isSafeToCancel() { } public enum State { - LOCATE_JUMP("Finding spot to jump off"), + JUMP("Takeoff"), PAUSE("Waiting for elytra path"), - GET_TO_JUMP("Walking to takeoff"), START_FLYING("Begin flying"), FLYING("Flying"), LANDING("Landing"); @@ -442,34 +408,6 @@ public void onPostTick(TickEvent event) { if (this.behavior != null && procThisTick == this) this.behavior.onPostTick(event); } - /** - * Custom calculation context which makes the player fall into lava - */ - public static final class WalkOffCalculationContext extends CalculationContext { - - public WalkOffCalculationContext(IBaritone baritone) { - super(baritone, true); - this.allowFallIntoLava = true; - this.minFallHeight = 8; - this.maxFallHeightNoWater = 10000; - } - - @Override - public double costOfPlacingAt(int x, int y, int z, BlockState current) { - return COST_INF; - } - - @Override - public double breakCostMultiplierAt(int x, int y, int z, BlockState current) { - return COST_INF; - } - - @Override - public double placeBucketCost() { - return COST_INF; - } - } - private static boolean isInBounds(BlockPos pos) { return pos.getY() >= 0 && pos.getY() < 128; } diff --git a/src/main/java/baritone/process/elytra/ElytraBehavior.java b/src/main/java/baritone/process/elytra/ElytraBehavior.java index d4913f466..7a382d08a 100644 --- a/src/main/java/baritone/process/elytra/ElytraBehavior.java +++ b/src/main/java/baritone/process/elytra/ElytraBehavior.java @@ -53,9 +53,9 @@ import net.minecraft.world.phys.Vec3; import java.awt.*; +import java.util.*; import java.util.List; import java.util.Queue; -import java.util.*; import java.util.concurrent.*; import java.util.function.UnaryOperator; @@ -359,7 +359,7 @@ private void pathfindAroundObstacles() { return; } } - if (!canSeeAny && rangeStartIncl < rangeEndExcl - 2 && process.state != ElytraProcess.State.GET_TO_JUMP) { + if (!canSeeAny && rangeStartIncl < rangeEndExcl - 2) { this.pathRecalcSegment(OptionalInt.of(rangeEndExcl - 1)).thenRun(() -> logVerbose("Recalculated segment since no path points were visible")); } } @@ -465,9 +465,7 @@ public void onReceivePacket(PacketEvent event) { } public void pathTo() { - if (!Baritone.settings().elytraAutoJump.value || ctx.player().isFallFlying()) { - this.pathManager.pathToDestination(); - } + this.pathManager.pathToDestination(); } public void destroy() {