Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/api/java/baritone/api/Settings.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -1489,7 +1488,7 @@ public final class Settings {
public final Setting<Boolean> 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<Boolean> elytraAutoJump = new Setting<>(false);

Expand Down
116 changes: 27 additions & 89 deletions src/main/java/baritone/process/ElytraProcess.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -53,29 +46,26 @@
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() {
this.state = State.START_FLYING; // TODO: null state?
this.goingToLandingSpot = false;
this.landingSpot = null;
this.reachedGoal = false;
this.goal = null;
startedJumpStateTime = 0L;
destroyBehaviorAsync();
}

Expand Down Expand Up @@ -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;
Expand All @@ -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);
}

Expand Down Expand Up @@ -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);
Expand All @@ -205,74 +191,55 @@ 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
if (this.state == State.PAUSE) {
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);
}
}
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
}
Expand Down
8 changes: 3 additions & 5 deletions src/main/java/baritone/process/elytra/ElytraBehavior.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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"));
}
}
Expand Down Expand Up @@ -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() {
Expand Down