From f6527340a8eb9aa421c9fec848dd9a06deb3cea8 Mon Sep 17 00:00:00 2001 From: Meloweh Date: Thu, 2 Dec 2021 21:56:32 +0100 Subject: [PATCH] - added player trail check --- .../java/baritone/process/BuilderProcess.java | 40 +++-- .../baritone/process/CustomGoalProcess.java | 10 ++ .../java/baritone/process/ExploreProcess.java | 13 +- .../java/baritone/process/FarmProcess.java | 1 + .../java/baritone/process/FollowProcess.java | 10 ++ .../baritone/process/GetToBlockProcess.java | 10 ++ .../java/baritone/process/MineProcess.java | 12 +- .../java/baritone/utils/RandomSpotNearby.java | 42 +++++ src/main/java/baritone/utils/Snake.java | 160 ++++++++++++++++++ 9 files changed, 277 insertions(+), 21 deletions(-) create mode 100644 src/main/java/baritone/utils/RandomSpotNearby.java create mode 100644 src/main/java/baritone/utils/Snake.java diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index c89ba9b00..804253c6b 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -20,10 +20,13 @@ import baritone.Baritone; import baritone.altoclef.AltoClefSettings; import baritone.api.BaritoneAPI; +import baritone.api.behavior.IPathingBehavior; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalBlock; import baritone.api.pathing.goals.GoalComposite; import baritone.api.pathing.goals.GoalGetToBlock; +import baritone.api.pathing.movement.IMovement; +import baritone.api.pathing.path.IPathExecutor; import baritone.api.process.IBuilderProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; @@ -36,13 +39,12 @@ import baritone.api.utils.Rotation; import baritone.api.utils.RotationUtils; import baritone.api.utils.input.Input; +import baritone.behavior.PathingBehavior; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; import baritone.pathing.movement.MovementHelper; -import baritone.utils.BaritoneProcessHelper; -import baritone.utils.BlockStateInterface; -import baritone.utils.NotificationHelper; -import baritone.utils.PathingCommandContext; +import baritone.pathing.path.PathExecutor; +import baritone.utils.*; import baritone.utils.schematic.MapArtSchematic; import baritone.utils.schematic.SchematicSystem; import baritone.utils.schematic.schematica.SchematicaHelper; @@ -96,6 +98,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil private long recalcCounter = 0; private boolean pausedBecauseOfMissingMaterials = false; private final Map protectedItems = new HashMap<>(); + private Snake snake; public BuilderProcess(Baritone baritone) { super(baritone); @@ -150,10 +153,10 @@ private void protectItemOfMissing() { protectedItems.putAll(missing); protectedItems.keySet().forEach(e -> { if (!Baritone.getAltoClefSettings().isItemProtected(e.getBlock().asItem())) { - System.out.println(Baritone.getAltoClefSettings().getProtectedItems().size()); - System.out.println("SET PROTECTION "); + //System.out.println(Baritone.getAltoClefSettings().getProtectedItems().size()); + //System.out.println("SET PROTECTION "); Baritone.getAltoClefSettings().protectItem(e.getBlock().asItem()); - System.out.println(Baritone.getAltoClefSettings().getProtectedItems().size()); + //System.out.println(Baritone.getAltoClefSettings().getProtectedItems().size()); } }); @@ -658,7 +661,7 @@ public void noteInsert(final BlockPos pos) { info.counter++; info.brokenPreviously = false; } - System.out.println("insert " + pos.getX() + " " + pos.getY() + " " + pos.getZ() + " c: " + getHistoryCount(pos)); + //System.out.println("insert " + pos.getX() + " " + pos.getY() + " " + pos.getZ() + " c: " + getHistoryCount(pos)); } else { blockBreakHistory.put(pos, new HistoryInfo()); } @@ -676,6 +679,13 @@ private long getHistoryCount(final BlockPos pos) { @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + if (snake == null) snake = new Snake(); + snake.tick(); + if (snake.passedLimits() && snake.getRunAwayCommand() != null) { + return snake.getRunAwayCommand(); + } + snake.printCurrent(); + protectItemOfMissing(); //if (!Baritone.getAltoClefSettings().isItemProtected(Items.DIRT)) //Baritone.getAltoClefSettings().protectItem(Items.DIRT); @@ -688,7 +698,7 @@ public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { } baritone.getInputOverrideHandler().clearAllKeys(); if (paused) { - System.out.println("a0"); + //System.out.println("a0"); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } if (Baritone.settings().buildInLayers.value) { @@ -770,7 +780,7 @@ public int lengthZ() { layer = 0; origin = new BlockPos(origin).offset(repeat); logDirect("Repeating build in vector " + repeat + ", new origin is " + origin); - System.out.println("a3"); + //System.out.println("a3"); return onTick(calcFailed, isSafeToCancel); } @@ -821,7 +831,7 @@ public int lengthZ() { noteRemoval(pos); baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_LEFT, true); } - System.out.println("a"); + //System.out.println("a"); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } List desirableOnHotbar = new ArrayList<>(); @@ -836,7 +846,7 @@ public int lengthZ() { baritone.getInputOverrideHandler().setInputForceState(Input.CLICK_RIGHT, true); } //System.out.println("goal"); - System.out.println("b"); + //System.out.println("b"); stopProtectItemOfMissing(); return new PathingCommand(null, PathingCommandType.CANCEL_AND_SET_GOAL); } @@ -860,7 +870,7 @@ public int lengthZ() { for (BlockState desired : noValidHotbarOption) { if (valid(approxPlaceable.get(i), desired, true)) { baritone.getInventoryBehavior().attemptToPutOnHotbar(i, usefulSlots::contains); - System.out.println("c"); + //System.out.println("c"); break outer; } } @@ -881,7 +891,7 @@ public int lengthZ() { return new PathingCommand(null, PathingCommandType.REQUEST_PAUSE); } } - System.out.println("big goal"); + //System.out.println("big goal"); return new PathingCommandContext(goal, PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH, bcc); } @@ -1035,7 +1045,7 @@ private Goal assemble(BuilderCalculationContext bcc, List approxPlac if (toBreak.isEmpty()) { if (!missing.isEmpty()) { this.pausedBecauseOfMissingMaterials = true; - System.out.println("prot called"); + //System.out.println("prot called"); protectItemOfMissing(); } diff --git a/src/main/java/baritone/process/CustomGoalProcess.java b/src/main/java/baritone/process/CustomGoalProcess.java index 86099860b..5cc8f6c97 100644 --- a/src/main/java/baritone/process/CustomGoalProcess.java +++ b/src/main/java/baritone/process/CustomGoalProcess.java @@ -24,6 +24,7 @@ import baritone.api.process.PathingCommandType; import baritone.utils.BaritoneProcessHelper; import baritone.utils.NotificationHelper; +import baritone.utils.Snake; /** * As set by ExampleBaritoneControl or something idk @@ -44,6 +45,8 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC */ private State state; + private Snake snake; + public CustomGoalProcess(Baritone baritone) { super(baritone); } @@ -76,6 +79,13 @@ public boolean isActive() { @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + if (snake == null) snake = new Snake(); + snake.tick(); + if (snake.passedLimits() && snake.getRunAwayCommand() != null) { + return snake.getRunAwayCommand(); + } + snake.printCurrent(); + switch (this.state) { case GOAL_SET: return new PathingCommand(this.goal, PathingCommandType.CANCEL_AND_SET_GOAL); diff --git a/src/main/java/baritone/process/ExploreProcess.java b/src/main/java/baritone/process/ExploreProcess.java index f86f5ed48..20cd4b6be 100644 --- a/src/main/java/baritone/process/ExploreProcess.java +++ b/src/main/java/baritone/process/ExploreProcess.java @@ -18,6 +18,7 @@ package baritone.process; import baritone.Baritone; +import baritone.api.BaritoneAPI; import baritone.api.cache.ICachedWorld; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.goals.GoalComposite; @@ -30,6 +31,7 @@ import baritone.cache.CachedWorld; import baritone.utils.BaritoneProcessHelper; import baritone.utils.NotificationHelper; +import baritone.utils.Snake; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @@ -42,12 +44,10 @@ import net.minecraft.world.level.ChunkPos; public final class ExploreProcess extends BaritoneProcessHelper implements IExploreProcess { - private BlockPos explorationOrigin; - private IChunkFilter filter; - private int distanceCompleted; + private Snake snake; public ExploreProcess(Baritone baritone) { super(baritone); @@ -81,6 +81,13 @@ public IChunkFilter calcFilter() { @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + if (snake == null) snake = new Snake(); + snake.tick(); + if (snake.passedLimits() && snake.getRunAwayCommand() != null) { + return snake.getRunAwayCommand(); + } + snake.printCurrent(); + if (calcFailed) { logDirect("Failed"); if (Baritone.settings().desktopNotifications.value && Baritone.settings().notificationOnExploreFinished.value) { diff --git a/src/main/java/baritone/process/FarmProcess.java b/src/main/java/baritone/process/FarmProcess.java index db312884b..0f07183e5 100644 --- a/src/main/java/baritone/process/FarmProcess.java +++ b/src/main/java/baritone/process/FarmProcess.java @@ -182,6 +182,7 @@ private boolean isNetherWart(ItemStack stack) { @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + //VectorPrinter.print(this.getClass().descriptorString()); ArrayList scan = new ArrayList<>(); for (Harvest harvest : Harvest.values()) { scan.add(harvest.block); diff --git a/src/main/java/baritone/process/FollowProcess.java b/src/main/java/baritone/process/FollowProcess.java index 085b17ae5..81e0e924d 100644 --- a/src/main/java/baritone/process/FollowProcess.java +++ b/src/main/java/baritone/process/FollowProcess.java @@ -29,6 +29,8 @@ import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; + +import baritone.utils.Snake; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; @@ -41,6 +43,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo private Predicate filter; private List cache; + private Snake snake; public FollowProcess(Baritone baritone) { super(baritone); @@ -48,6 +51,13 @@ public FollowProcess(Baritone baritone) { @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + if (snake == null) snake = new Snake(); + snake.tick(); + if (snake.passedLimits() && snake.getRunAwayCommand() != null) { + return snake.getRunAwayCommand(); + } + snake.printCurrent(); + scanWorld(); Goal goal = new GoalComposite(cache.stream().map(this::towards).toArray(Goal[]::new)); return new PathingCommand(goal, PathingCommandType.REVALIDATE_GOAL_AND_PATH); diff --git a/src/main/java/baritone/process/GetToBlockProcess.java b/src/main/java/baritone/process/GetToBlockProcess.java index 28037dca0..ef499c980 100644 --- a/src/main/java/baritone/process/GetToBlockProcess.java +++ b/src/main/java/baritone/process/GetToBlockProcess.java @@ -31,6 +31,8 @@ import baritone.pathing.movement.MovementHelper; import baritone.utils.BaritoneProcessHelper; import java.util.*; + +import baritone.utils.Snake; import net.minecraft.core.BlockPos; import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.level.block.Block; @@ -45,6 +47,7 @@ public final class GetToBlockProcess extends BaritoneProcessHelper implements IG private int tickCount = 0; private int arrivalTickCount = 0; + private Snake snake; public GetToBlockProcess(Baritone baritone) { super(baritone); @@ -67,6 +70,13 @@ public boolean isActive() { @Override public synchronized PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + if (snake == null) snake = new Snake(); + snake.tick(); + if (snake.passedLimits() && snake.getRunAwayCommand() != null) { + return snake.getRunAwayCommand(); + } + snake.printCurrent(); + if (knownLocations == null) { rescan(new ArrayList<>(), new CalculationContext(baritone)); } diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index bc93b62e0..b285f1448 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -28,9 +28,7 @@ import baritone.cache.WorldScanner; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.MovementHelper; -import baritone.utils.BaritoneProcessHelper; -import baritone.utils.BlockStateInterface; -import baritone.utils.NotificationHelper; +import baritone.utils.*; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; @@ -63,6 +61,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro private GoalRunAway branchPointRunaway; private int desiredQuantity; private int tickCount; + private Snake snake; public MineProcess(Baritone baritone) { super(baritone); @@ -75,6 +74,13 @@ public boolean isActive() { @Override public PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel) { + if (snake == null) snake = new Snake(); + snake.tick(); + if (snake.passedLimits() && snake.getRunAwayCommand() != null) { + return snake.getRunAwayCommand(); + } + snake.printCurrent(); + if (desiredQuantity > 0) { int curr = ctx.player().getInventory().items.stream() .filter(stack -> filter.has(stack)) diff --git a/src/main/java/baritone/utils/RandomSpotNearby.java b/src/main/java/baritone/utils/RandomSpotNearby.java new file mode 100644 index 000000000..e2119c7f9 --- /dev/null +++ b/src/main/java/baritone/utils/RandomSpotNearby.java @@ -0,0 +1,42 @@ +package baritone.utils; + +import baritone.api.utils.BetterBlockPos; + +import java.util.Random; + +public class RandomSpotNearby { + private BetterBlockPos end; + private final Random rand; + private double r; + private double old_r; + + public RandomSpotNearby(final double r) { + this.rand = new Random(); + this.r = r; + this.old_r = r; + } + + private final double MAX_DIST_INCREASE() { + return old_r * 2; + } + + private BetterBlockPos calc(final BetterBlockPos start) { + final double phi = rand.nextInt(360) + rand.nextDouble(); + final double radius = rand.nextInt((int) Math.round(r)) + rand.nextDouble(); //rand.nextDouble(r) + rand.nextDouble(); + final int x = (int) Math.round(radius * Math.sin(phi)); + final int z = (int) Math.round(radius * Math.cos(phi)); + + this.end = new BetterBlockPos(start.getX() + x, start.getY(), start.getZ() + z); + return this.end; + } + + public BetterBlockPos next(final BetterBlockPos start) { + this.r = (this.r - this.old_r > MAX_DIST_INCREASE()) ? this.old_r : this.r; + return next(start, 0.3d); + } + + public BetterBlockPos next(final BetterBlockPos start, final double increaseRadius) { + this.r += increaseRadius; + return calc(start); + } +} diff --git a/src/main/java/baritone/utils/Snake.java b/src/main/java/baritone/utils/Snake.java new file mode 100644 index 000000000..dfbc40088 --- /dev/null +++ b/src/main/java/baritone/utils/Snake.java @@ -0,0 +1,160 @@ +package baritone.utils; + +import baritone.api.BaritoneAPI; +import baritone.api.behavior.IPathingBehavior; +import baritone.api.pathing.goals.Goal; +import baritone.api.pathing.goals.GoalRunAway; +import baritone.api.pathing.goals.GoalXZ; +import baritone.api.pathing.path.IPathExecutor; +import baritone.api.process.PathingCommand; +import baritone.api.process.PathingCommandType; +import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.IPlayerContext; +import net.minecraft.world.level.ChunkPos; + +import java.util.*; + +public final class Snake { + private final Map vectors; + private final Queue traversedChunks; + private BetterBlockPos prev; + private final BlockStateInterface bsi; + private final IPlayerContext player; + private final static int VECTOR_LIMIT = 1024; + private final static int CROSS_LIMIT = 20; + private final static int CHUNK_TAIL_MAX = 4*4; + + public Snake() { + this.vectors = new HashMap<>(); + this.player = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext(); + this.bsi = new BlockStateInterface(this.player); + this.traversedChunks = new ArrayDeque<>(); + } + + private boolean equalPos(final BetterBlockPos pos1, final BetterBlockPos pos2) { + if (isNull(pos1) || isNull(pos2)) return false; + return pos1.getX() == pos2.getX() && pos1.getY() == pos2.getY() && pos1.getZ() == pos2.getZ(); + } + + + private boolean contains(final BetterBlockPos pos) { + return this.vectors.keySet().stream().anyMatch(e -> equalPos(e, pos)); + } + + public boolean passedLimits() { + return this.vectors.size() > VECTOR_LIMIT || vectors.entrySet().stream().anyMatch(e -> e.getValue().crossings > CROSS_LIMIT); + } + + private BetterBlockPos getOrigRef(final BetterBlockPos pos) { + final Optional opt = vectors.keySet().stream().filter(e -> equalPos(e, pos)).findFirst(); + if (opt.isPresent()) { + return opt.get(); + } + return null; + } + + private boolean isSameChunk(final ChunkPos c1, final ChunkPos c2) { + return c1.x == c2.x && c1.z == c2.z; + } + + public void reset() { + traversedChunks.clear(); + vectors.clear(); + prev = null; + pathing = false; + stuckPos = null; + targetPos = null; + } + + private boolean removeOutsiders() { + return this.vectors.entrySet().removeIf(e -> !traversedChunks.stream().anyMatch(c -> isSameChunk(e.getValue().chunkPos, c.chunkPos))); + } + + boolean pathing = false; + BetterBlockPos stuckPos; + RandomSpotNearby randSpot = new RandomSpotNearby(16d); + BetterBlockPos targetPos; + + public PathingCommand getRunAwayCommand() { + final BetterBlockPos curr = getCurrent(); + if (isNull(curr)) return null; + + if (!pathing) { + stuckPos = getCurrent(); + targetPos = randSpot.next(stuckPos); + pathing = true; + } + + if (curr.closerThan(targetPos, 3d)) { + reset(); + return null; //new PathingCommand(null, PathingCommandType.DEFER); + } + return new PathingCommand(new GoalXZ(targetPos), PathingCommandType.FORCE_REVALIDATE_GOAL_AND_PATH); + } + + public void tick() { + final BetterBlockPos curr = getCurrent(); + if (isNull(curr) || equalPos(prev, curr)) return; + prev = curr; + + final ChunkPos chunkPos = this.player.world().getChunk(curr).getPos(); + if (!traversedChunks.stream().anyMatch(e -> isSameChunk(e.chunkPos, chunkPos))) { + traversedChunks.add(new Pack(chunkPos)); + //TODO: save block pos index list in their chunk. if the chunk gets removed + // just iterate over it and remove that element in vectors over that index. + // Iteration steps can be cut down to vectors.size()/CHUNK_TAIL_MAX + CHUNK_TAIL_MAX + while (traversedChunks.size() > CHUNK_TAIL_MAX) traversedChunks.poll(); + } + + if (contains(curr)) { + final BetterBlockPos orig = getOrigRef(curr); + final Pack pack = this.vectors.get(orig); + pack.crossings++; + this.vectors.put(orig, pack); + } else { + final Pack pack = new Pack(chunkPos); + vectors.put(curr, pack); + } + + removeOutsiders(); + } + + /** + * Call only after tick. + */ + public void printCurrent() { + BetterBlockPos playerPos = getCurrent(); + if (isSet(playerPos) && this.vectors.size() > 0) { + System.out.println(playerPos.getX() + ":" + playerPos.getY() + ":" + playerPos.getZ() + " Counts: " + + this.vectors.get(getOrigRef(playerPos)).crossings + " Size: " + this.vectors.size()); + } + } + + private static boolean isSet(final Object o) { + return o != null; + } + + private static boolean isNull(final Object o) { return !isSet(o);} + + private static BetterBlockPos getCurrent() { + final IPathingBehavior p = BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior(); + if (isNull(p)) return null; + final IPathExecutor c = p.getCurrent(); + if (isNull(c)) return null; + final List bbp = c.getPath().positions(); + if (isNull(bbp)) return null; + final int posIndex = c.getPosition(); + final BetterBlockPos pos = c.getPath().positions().get(posIndex); + return pos; + } + + private class Pack { + public Pack(final ChunkPos chunkPos) { + this.crossings = 1; + this.chunkPos = chunkPos; + } + + public ChunkPos chunkPos; + public int crossings; + } +}