Add commands for pathfinder reset and chunk repack

This commit is contained in:
Brady 2023-07-07 19:44:59 -07:00
parent 487b3a759a
commit c0cdfb7781
No known key found for this signature in database
GPG Key ID: 73A788379A197567
3 changed files with 80 additions and 29 deletions

View File

@ -19,8 +19,20 @@ package baritone.api.behavior;
import net.minecraft.util.math.BlockPos;
import java.util.concurrent.CompletableFuture;
public interface IElytraBehavior extends IBehavior {
/**
* Marks the nether pathfinder context to be reset when it is safe to do so. Because this operation is not
* immediate, a {@link CompletableFuture} is returned that will complete after the context has been reset.
*
* @return A {@link CompletableFuture} that is completed when the context is reset
*/
CompletableFuture<Void> resetContext();
void repackChunks();
void pathTo(BlockPos destination);
void cancel();

View File

@ -41,6 +41,7 @@ import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.movements.MovementFall;
import baritone.utils.BlockStateInterface;
import baritone.utils.PathingCommandContext;
import baritone.utils.accessor.IChunkProviderClient;
import baritone.utils.accessor.IEntityFireworkRocket;
import it.unimi.dsi.fastutil.floats.FloatArrayList;
import it.unimi.dsi.fastutil.floats.FloatIterator;
@ -76,7 +77,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
// :sunglasses:
private NetherPathfinderContext context;
private boolean forceResetContext;
private CompletableFuture<Void> forceResetContext;
private final PathManager pathManager;
private final ElytraProcess process;
@ -370,7 +371,7 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
if (event.getWorld() != null) {
if (event.getState() == EventState.PRE) {
// Reset the context when it's safe to do so on the next game tick
this.forceResetContext = true;
this.resetContext();
}
} else {
if (event.getState() == EventState.POST) {
@ -429,6 +430,20 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
Arrays.fill(this.nextTickBoostCounter, 0);
}
@Override
public CompletableFuture<Void> resetContext() {
if (this.forceResetContext == null) {
this.forceResetContext = new CompletableFuture<>();
}
return this.forceResetContext;
}
@Override
public void repackChunks() {
((IChunkProviderClient) ctx.world().getChunkProvider()).loadedChunks().values()
.forEach(this.context::queueForPacking);
}
@Override
public boolean isActive() {
return baritone.getPathingControlManager().mostRecentInControl()
@ -455,15 +470,16 @@ public final class ElytraBehavior extends Behavior implements IElytraBehavior, H
// Setup/reset context
final long netherSeed = Baritone.settings().elytraNetherSeed.value;
if (this.context == null || this.context.getSeed() != netherSeed || this.forceResetContext) {
if (this.context == null || this.context.getSeed() != netherSeed || this.forceResetContext != null) {
if (this.context != null) {
this.context.destroy();
}
this.context = new NetherPathfinderContext(netherSeed);
this.forceResetContext = false;
if (this.isActive()) {
// TODO: Re-pack chunks?
if (this.forceResetContext != null) {
this.forceResetContext.complete(null);
this.forceResetContext = null;
}
if (this.context.getSeed() != netherSeed && this.isActive()) {
logDirect("Nether seed changed, recalculating path");
this.pathManager.pathToDestination();
}

View File

@ -18,6 +18,7 @@
package baritone.command.defaults;
import baritone.api.IBaritone;
import baritone.api.behavior.IElytraBehavior;
import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.exception.CommandException;
@ -40,30 +41,52 @@ public class ElytraCommand extends Command {
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
args.requireMax(0);
Goal iGoal = customGoalProcess.mostRecentGoal();
if (iGoal == null) {
throw new CommandInvalidStateException("No goal has been set");
final ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
final IElytraBehavior elytra = baritone.getElytraBehavior();
if (!args.hasAny()) {
Goal iGoal = customGoalProcess.mostRecentGoal();
if (iGoal == null) {
throw new CommandInvalidStateException("No goal has been set");
}
final int x, y, z;
if (iGoal instanceof GoalXZ) {
GoalXZ goal = (GoalXZ) iGoal;
x = goal.getX();
y = 64;
z = goal.getZ();
} else if (iGoal instanceof GoalBlock) {
GoalBlock goal = (GoalBlock) iGoal;
x = goal.x;
y = goal.y;
z = goal.z;
} else {
throw new CommandInvalidStateException("The goal must be a GoalXZ or GoalBlock");
}
if (y <= 0 || y >= 128) {
throw new CommandInvalidStateException("The y of the goal is not between 0 and 128");
}
elytra.pathTo(new BlockPos(x, y, z));
return;
}
final int x, y, z;
if (iGoal instanceof GoalXZ) {
GoalXZ goal = (GoalXZ) iGoal;
x = goal.getX();
y = 64;
z = goal.getZ();
} else if (iGoal instanceof GoalBlock) {
GoalBlock goal = (GoalBlock) iGoal;
x = goal.x;
y = goal.y;
z = goal.z;
} else {
throw new CommandInvalidStateException("The goal must be a GoalXZ or GoalBlock");
final String action = args.getString();
switch (action) {
case "reset": {
elytra.resetContext().whenComplete((result, ex) -> {
logDirect("Context reset, repacking chunks");
elytra.repackChunks();
});
break;
}
case "repack": {
elytra.repackChunks();
logDirect("Queued all loaded chunks for repacking");
break;
}
default: {
throw new CommandInvalidStateException("Invalid action");
}
}
if (y <= 0 || y >= 128) {
throw new CommandInvalidStateException("The y of the goal is not between 0 and 128");
}
baritone.getElytraBehavior().pathTo(new BlockPos(x, y, z));
}
@Override