1
0
mirror of https://github.com/cabaletta/baritone synced 2025-02-19 13:37:03 +00:00

initial safe landing impl

This commit is contained in:
Babbaj 2023-07-22 19:12:53 -04:00
parent 097e30850f
commit 7f9e50bbe2
No known key found for this signature in database
GPG Key ID: F044309848A07CAC
2 changed files with 61 additions and 6 deletions

View File

@ -23,11 +23,8 @@ import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.exception.CommandException;
import baritone.api.command.exception.CommandInvalidStateException;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.process.IElytraProcess;
import net.minecraft.util.math.BlockPos;
import java.util.Arrays;
import java.util.List;

View File

@ -42,14 +42,21 @@ import baritone.process.elytra.NullElytraProcess;
import baritone.utils.BaritoneProcessHelper;
import baritone.utils.PathingCommandContext;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Set;
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 Goal goal;
private LegacyElytraBehavior behavior;
@ -93,8 +100,8 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
if (ctx.player().isElytraFlying()) {
final BetterBlockPos last = behavior.pathManager.path.getLast();
if (ctx.player().isElytraFlying() && this.state != State.LANDING) {
final BetterBlockPos last = this.behavior.pathManager.path.getLast();
if (last != null && ctx.player().getDistanceSqToCenter(last) < (5 * 5)) {
if (Baritone.settings().notificationOnPathComplete.value) {
logNotification("Pathing complete", false);
@ -105,6 +112,14 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro
ctx.world().sendQuittingDisconnectingPacket();
return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL);
}
if (!goingToLandingSpot) {
BlockPos landingSpot = findSafeLandingSpot();
if (landingSpot != null) {
this.pathTo(landingSpot);
this.goingToLandingSpot = true;
return this.onTick(calcFailed, isSafeToCancel);
}
}
this.state = State.LANDING;
}
}
@ -208,6 +223,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro
@Override
public void onLostControl() {
this.goal = null;
this.goingToLandingSpot = false;
this.state = State.START_FLYING; // TODO: null state?
if (this.behavior != null) {
this.behavior.destroy();
@ -234,6 +250,7 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro
@Override
public void pathTo(BlockPos destination) {
this.onLostControl();
this.behavior = new LegacyElytraBehavior(this.baritone, this, destination);
if (ctx.world() != null) {
this.behavior.repackChunks();
@ -253,7 +270,6 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro
public enum State {
LOCATE_JUMP("Finding spot to jump off"),
VALIDATE_PATH("Validating path"),
PAUSE("Waiting for elytra path"),
GET_TO_JUMP("Walking to takeoff"),
START_FLYING("Begin flying"),
@ -329,4 +345,46 @@ public class ElytraProcess extends BaritoneProcessHelper implements IBaritonePro
return COST_INF;
}
}
private static boolean isInBounds(BlockPos pos) {
return pos.getY() >= 0 && pos.getY() < 128;
}
private boolean isSafeLandingSpot(BlockPos pos) {
BlockPos.MutableBlockPos mut = new BlockPos.MutableBlockPos(pos);
while (mut.getY() >= 0) {
IBlockState state = ctx.world().getBlockState(mut);
if (state.getMaterial().isLiquid()) { // lava
return false;
}
if (state.getMaterial().blocksMovement() && state.getBlock() != Blocks.MAGMA) {
return true;
}
mut.setPos(mut.getX(), mut.getY() - 1, mut.getZ());
}
return false; // void
}
private BlockPos findSafeLandingSpot() {
final BlockPos start = new BlockPos(ctx.playerFeet());
Queue<BlockPos> queue = new LinkedList<>();
Set<BlockPos> visited = new HashSet<>();
queue.add(start);
while (!queue.isEmpty()) {
BlockPos pos = queue.poll();
if (ctx.world().isBlockLoaded(pos) && isInBounds(pos) && ctx.world().getBlockState(pos).getBlock() == Blocks.AIR) {
if (isSafeLandingSpot(pos)) {
return pos;
}
if (visited.add(pos.north())) queue.add(pos.north());
if (visited.add(pos.east())) queue.add(pos.east());
if (visited.add(pos.south())) queue.add(pos.south());
if (visited.add(pos.west())) queue.add(pos.west());
if (visited.add(pos.up())) queue.add(pos.up());
if (visited.add(pos.down())) queue.add(pos.down());
}
}
return null;
}
}